两种模式的演化
道生一,一生二,二生三,三生万物。 --《道德经》
Account Model仍然以Ethereum为代表。进一步的演化过程中将世界状态分成两层。
一层是账户地址Address到Account结构的映射。然后Account结构内部除了余额又增加了code和storage。
storage是上一章提到的账本的泛化,不只是简单地包含账户和余额的表格,还可以是复杂的数据结构。
code是一个图灵完备的虚拟机的代码,可以实现上一章提到的转账计算,以及更广泛的任意的计算逻辑。代码经过虚拟机解释转变为对storage进行修改的操作。
账户地址Address层面并不区分外部账户(只有原生token和转帐功能)和合约账户(有code和storage)。两者的地址处于同一地址空间,表面看不出区别。
交易在原有基础上增加了data字段。外部账户之间转账的时候data会被忽略,调用合约账户的时候,data字段作为参数传给code。data字段可以包含复杂结构,使用rlp序列化。
对于用户来说,其演化非常的平滑,非常容易理解。如果只是转账的话,跟上一章描述的体验完全一致。额外增加的合约账户只要将其理解为一个机器人,其行为逻辑完全受内部的code控制即可。
Bitcoin其实也有一定的可编程性,即所谓的LockScript。因为其定位,可编程性都是围绕账户的。比如多签,收款账户是一个群体;P2SH,收款账户是一个脚本/合约等。
UTXO Model的演化是CKB提出的Cell Model。将余额一般化为data,保留LockScript的同时,增加TypeScript对Data数据进行解释和约束。
Account Model在增加了图灵完备的可编程能力之后,灵活性得到很大的提升。比如多签,就可以通过智能合约来模拟。类似Proxy设计模式,让一个合约代为收集多个签名。多签里的每个成员都将签名发送到这个合约,合约校验签名并计数,达到阈值之后就触发后续的操作。与比特币相比,缺点是中间状态也要上链,会占用一些状态空间。比特币的多签是链下收集签名,签名没收集齐之前根本上不了链,中间状态相当于在链外维护。
但是灵活性方面还是比不上UTXO/Cell Model。我们将前一章5人结算的例子进行一般化推广。可以看到两种模型的关键区别是,Account Model在执行一个交易的时候,需要详细指明如何从之前的状态变化到之后的状态;而UTXO/Cell Model只需要给出变化前后的状态即可,及其需要满足的约束即可,不关心两个状态之间具体的路径。
原因是Account Model的计算在链上,由验证节点执行,有点像云计算。如果不明确前后状态之间具体的变化路径,每个共识节点可能会选择不同的路径。不同的路径会产生不同的中间状态,这些中间状态会被计算到世界状态中,导致分叉。
这个灵活性导致Cell Modle的另外一个好处是其组合性比较好。Account Model下每种资产都按账户地址划分好,一个合约地址只针对一种资产类型进行操作。可以想象Ethereum上有多个代表不同资产类型的ERC20合约。如果用户想将任意一种资产转换为任意另一种资产,是无法直接完成转换的。可能需要先将数字资产转为原生Token,然后再去兑换另外一种数字资产。这个过程中需要用户多个步骤的操作,整个过程也不是原子性的,会有各种中间状态。
但是如上一章中的例子,一个UTXO类型的交易,其多个input可以来自不同的账户。类似的,在Cell Model中,一个交易的多个input也可以是多个不同的Type。只要满足一定的约束,可以直接完成多种数字资产对多种数字资产的交换,而且过程是原子性的,不会有中间状态。
当然Cell Model的用户友好性也同样的糟糕。Bitcoin只有一个UTXO Set,没有针对账户建立索引。用户转账前要自己挑选合适的UTXO作为交易的input,只能遍历UTXO,然后用自己的账户地址进行过滤。到了Cell Model,情况就更严重了。UTXO一般化为有各种不同Type的Cell。这样遍历的时候就有两个维度了,更复杂了。这方面其实可以借鉴Account Model,每个用户都使用HD钱包生成一些列地址。将不同类型的Cell放到不同的子地址中进行区分,这样可以加快搜索速度,增加一些用户友好性。