Nervos的分层思想
Nervos将公链分成了两个层,Layer 1是共识层和存储,Layer 2则是区块的生成。Nervos的CKB(Common Knowledge Base)实现了共识和存储的Layer 1。链下的Layer 2生成了新的状态/交易后,提交给CKB,然后在链上达成共识并进行存储。由于清晰的区分了Layer 1 和Layer 2, 每一层都有更大的灵活性和可扩展性。比如,Layer 2上可以采用其他的使用不同共识机制的区块链(或者应用)进行状态/交易的产生。Layer 2可以产生新的状态/交易的情形举例如下:
- 本地客户端的产生;
- 基于Web service的产生;
- 基于P2P的状态的产生;
- 其他区块链的产生。
CKB采用了PoW的共识方式,提供了一个基于RISC-V指令的图灵完备的虚拟机,并配上CKB特有的Cell模式,使得在CKB上产生状态或交易也是可行的。
CKB的整个模型包含了以下三部分:
- 状态生成(链下)
- 状态证明(CKB虚拟机)
- 状态存储(Cell模型)
虚拟机
我们看下比特网、以太网和CKB的虚拟机的区别:
Bitcoin | Ethereum | CKB | |
---|---|---|---|
指令集 | 脚本 | EVM | RISC-V |
指令运行方式 | Opcode | 预编译 | 汇编语言 |
状态 | 无 | 有 | 有 |
状态类型 | 账本 | 通用 | 通用 |
状态模型 | UTXO | 账户 | Cell |
状态证明 | 链上 | 链上 | 链上 |
状态生成 | 链下 | 链上 | 链下 |
Cell模型
Cell是CKB中存储状态的形式,是用户拥有的资产证明。在一个Cell中,还包含了用脚本语言描写的运用逻辑。CKB的虚拟机运行逻辑脚本,并验证输入Cell中的签名,以保证运行者有权利使用输入的Cell,验证交易在脚本指定的逻辑下是有效的。CKB的交易使用的是Cell模型,类似比特网的UTXO,交易的输入使用了以前交易的输出,并通过签名解锁输入的Cell。而交易的输出则是客户端产生的新状态,也被打包在Cell模型中。
在这个模型下,DApp的逻辑被分成了状态生成和状态证明两部分,分别运行在不同的地方。状态生成运行在链下的客户端,而生成的状态被打包在交易中向链上广播。
客户端生成状态以及在CKB上达到状态的验证,可以使用同一种算法。在这种方式下,隔离状态的生成和验证,有以下优点:
- 交易的可确定性。如果一个交易仅包含用户输入,而其状态要等待链上节点计算确认的话,交易的结果(由于链上计算的环境复杂程度)对于客户端是不可知的。在CKB里面,客户端直接生成交易结果,生成的交易结果是明确的,在提交到链上后,要么交易被接受,要么交易不被接受。
- 并行性。如果一个交易仅包含用户输入,而其状态要等待链上节点计算确认的话,由于节点并不知道共识流程会接受什么样的状态,因此也不能确定交易之间的依赖关系。而在CKB中,由于交易是明确包含了输入状态和输出状态的,节点可以在共识前就能知道交易之间的依赖关系,因此可以并行处理多个交易。
- 更高的资源利用率。由于整个应用逻辑被分在了不同的地方,因此整个网络可以更平均的将计算工作分在节点和客户端上,也能更好的使用计算资源。
- 更灵活的状态生成。在客户端可以使用更有效的编程语言进行状态的生成。
在某些情况下,状态的生成,与状态的检验使用的是不同的算法(但是是相关的)。比特币的交易就是一个明显的例子。比特币交易的生成使用的算法是找到正确的UTXO来使用,而交易的验证则是将输入的UTXO相加并和需要交易的数量进行比较。排序是另外一个例子,快速排序中,排序需要的复杂程度是O(N*log(N)),而验证搜索的结果只需要O(N)。业务规则越复杂,状态的生成和状态的检验就越可能使用不同的算法。
下图描绘了在链上生成和校验状态,与客户端生成状态链上校验的区别。
我们来看下一个cell里面有哪些数据:
-
capacity
- 表明一个cell的大小(所需要的字节数); -
data
- 状态数据; -
type
- 状态验证的代码。由CKB虚拟机在创建cell的时候运行,以确保cell的状态是正确的。 -
lock
- 用来表示拥有这个cell的代码。有CKB虚拟机在本cell被用作一个交易的输入的时候执行,以确保使用者拥有这个cell。如果lock的代码返回true
,用户可以将cell转移给其他用户,或者更新cell的数据(根据type的代码确定是否可以更新)。
cell有以下特征:
- 不可修改。一个cell被创建后不能被修改。一个对于cell的update动作其实是把原有的cell标记为作废,同时创建一个有同样capacity的新cell。
- 只能被使用一次。一个cell不能用做两个不同的交易的输入项。
- 一个cell可以转移它的capacity到其他cell,全部或者一部分。比如,一个capacity为10的cell可以变成两个capacity为5的cell。
type
和lock
的代码提供了一些业务需求的可行性,包括:
- 使用的密码学方式。在CKB的虚拟机里,并没有在代码里指定加密方案,用户可以自由选择在签名交易的时候使用任何签名技术。当然,CKB提供了缺省的hash函数以及公钥处理等功能。
- 多签。用户可以在
lock
字段使用多签的方式。 - 借贷。cell的拥有者可以将cell“借给”其他用户,并同时保留这个cell的所有权。
我们再来看下CKB里面的交易。
交易表示状态的转移,在CKB里面,表现在cell的转移,更新,或者两者皆有。一个交易包含以下数据:
-
deps
- 依赖的cell列表。提供只读的,为了校验交易的cell列表。 -
inputs
- 输入的cell。指向会被转移或者更新的cell。 -
outputs
- 输出的cell。
下图表示了deps
、inputs
和outputs
的关系:
CKB cell模型是有利于轻节点的。因为所有的状态都在区块中,区块的同步就相当于状态的东部。全节点之需要进行区块的同步,而不需要进行状态的同步或者状态转换的计算。同时,cell的模型和普通的区块同步还有所不同,因为在cell模型里,广播一个区块是会被通证激励的。
CKB里面有三类节点:
- 挖矿节点:参与CKB的共识。挖矿节点收集新的交易,在找到PoW后打包到区块中。
- 全节点:验证新区块和交易,转发区块和交易信息,并将区块加到链上。
- 轻节点:轻节点信任全节点,同步更新一小部分轻节点关注的cell。轻节点被设计成跑在移动设备上。