[翻译] Godwoken导论-Cell模型缺失的一角

原文链接:Introducing Godwoken - A missing piece of the cell model
作者: Profile - jjy - Nervos Talk

对于开发人员而言,Cell模型下的编程是CKB中最有意思的一点。
下面是对细胞模型的简短描述:

  • Cell 就是 广义UTXO模型中的Cell
  • 每个Cell包含一段数据或是自定义脚本
  • 当交易使用或创建Cell时,会执行Cell中的脚本。脚本如果执行失败,则交易执行失败

细胞模型与账户模型相比有很大的不同:

  • Cell模型中脚本仅仅是验证,而不是计算。( 可区别于ETH智能合约
  • 数据存储在独立的Cell中,而不是账户Tree中。( 可区别与ETH的世界状态树

如果你还想比较Cell模型和账户模型的其他不同,可以参考论坛里其他帖子

细胞模型缺失的一角

UTXO 模型是一个非常灵活的模型,Cell 模型直接从它继承而来,并且具有图灵完整编程能力。
我们可以发行 UDT 代币来存储链上资产、可以玩石头剪刀布、或与比特币进行跨链交易。细胞模型可以实现许多原本不可能的事情。
但遗憾的是,还有很多功能难以在Cell模型上实现,比如:

  • Voting 投票
  • Crowdfunding 众筹
  • Decentralized price oracle 去中心化价格预言机

这些复杂合约的共同点是,它们都需要一个共同状态。然而在CKB中,链的状态和用户状态是分离的。

译者注:CKB中没有世界状态这种说法,有的只是每个CKB用户自己手中的cell

在CKB中,如果我们想要实现一个投票系统。由于没有世界状态,我们只能在链上投票,链下计票。

译者注:计票就是由一个链下的节点,收集所有voting交易,将用户投票时生成的voting cell,汇总到一个vote_result_cell中。

这样一来,我们虽然可以通过链下监测的方法获取到投票结果,但是我们很难在链上验证这个结果。因为如果要验证每一个投票,就需要在链上保存对应的投票记录。而这个记录的开支是巨大的。

我们再来看另外一个场景,众筹。我们使用一个Cell(记作cell_t)来保存所有众筹Token。用户可以用CKB来买Token。
当用户试图购买令牌时,会消耗掉用户原有的cell_a 和 众筹项目的cell_t,并生成两个新的Cell: 存储给用户CKB找零的cell_b 和记录了剩余众筹Tokencell_t_new
如此一来,众筹交易需要的input cell就改变了。其他用户必须使用新的cell_t_new来进行众筹操作。换句话说,在每一个区块链高度中,只有一个用户可以参与众筹。这样实现的众筹操作效率太低了,无法接受。

和voting的解决方案一样,我们可以引入一个链下角色对链上的众筹操作进行监测。将监测到的cell_new汇总到一个包含全部众筹记录的cell_result中。可见,由于CKB没有世界状态,我们必须依靠一些链下角色来对监控状态变化。
这个解决方案虽然有效,但是仍然存在一些问题:

  • 如何有效证明聚合结果的完整性?
  • 既然引入了链下节点,我们该如何实现去中心化?
  • 用户如何与链下节点交互?
    当然了,我们可以通过一些奖罚机制来激励链下参与者,通过一些零知识证明来验证聚合结果,通过定义协议来约束用户交互接口。
    想解决这些问题,总是有办法的。
    但我只是想搞一个投票系统诶!要不要这么麻烦?

One contract to rule them all

就为了写一个投票合同搞这么多事,太累了。
为了避免每写一次投票系统就写这么多东西,我决定写一个轮子!

Godwoken是CKB上一个程序层的世界状态解决方案。
Godwoken由如下部分组成。

  • Main Contracts: 维护着所有账户信息,并运行着layer1.5挖矿。
  • Aggregator:链下进程,检测、收集所有layer1.5的事件。
  • Validator:链下进程,监控Main Contract状态。如果监测到一个异常的layer1.5的区块,则提出Challeng Requests。
  • Challenge Contract:处理所有Challenge Requests。

译者注:原文作者提到,关于Rollup方案,很多人称其为Layer2 或 Layer1.5。甚至有人称其为Layer1 (根据信任等级区分)。原作者在全文使用Layer1.5 来称呼这一层。由于译者常年使用Layer2关键词,如果下文出现手误请见谅。

Godwoken乍一看类似于以太坊的扩容方案。没错!就是他!这个方案和以太坊的Layer1.5方案们不一样的地方仅仅是,Godwoken旨在改变CKB的账本模型(从UTXO变为账户模型),而Rollup 等Layer1.5方案是为了通过扩容来提高以太坊的交易效率。

Godwoken和原生CKB脚本使用相同的技术栈。但不同的是,Godwoken提供了一套面向账户系统的API。Godwoken验证账户的状态而不是Cell的状态。账户状态和Cell状态之间的映射关系由Main Contract处理。
对于想要创建voting合约的开发人员而言,可以先调用脚本创建一个账户,然后验证输入的数据和账户状态。伪代码如下:

fn verify_voting(i, votes) -> bool {
    state[i] += votes;
    merkle_root(state) == next_account_root
}

Godwoken main contract 使用sparse merkle tree来存储账户状态数据。我们可以通过检查账户状态是否存在于smt中以进行验证。
如果开发者想从Layer1层脚本中读取Layer1.5的账户状态,需要在cell_deps中引用Godwoken账户状态树。从而对账户状态进行验证。

总结

通过把账户层从CKB中抽象出来,我们简化了创建有共享状态的合约的过程。

引用

Godwoken design document
Sparse merkle tree

5 Likes