如何解决比特币和以太坊编程模型中存在的问题
“通过分层架构,可以创建一个经济实惠且通用的基础架构,在我看来,这是区块链驱动世界唯一可行的未来。”
三大编程模型
——UTXO模型
首先,从比特币开始,比特币又被称为点对点电子支付系统,其使用名为UTXO(关联比特币地址的比特币金额的集合,是一个包含数据和可执行代码的数据结构火币网 交易软件)的编程模型。
最简单的方法是将UTXO看作一个盒子。该盒子包含一个表示货币价值的数字和一个锁。只有拿着相应钥匙的人才能打开盒子。当进行转账时,持有钥匙的所有者或个人使用钥匙解锁,找到另一个空盒子,将新面值放入新盒子中,并附加一个新所有者的锁。
整个交易可以概括为打开盒子,拿出里面的钱,摧毁原来的盒子,然后把它放在另一个盒子里
总而言之,盒子表示存储数据的UTXO模型,锁表示所有权。
——Account模型
除了UTXO模型,还有Account模型。这个模型最著名的例子是以太坊。
除了数据,以太坊Account模型中还有计算逻辑。你可以将ERC20合约想象成一个盒子,盒子里没有钱而是一组复杂的逻辑和数字。
与UTXO不同,Account模型的盒子始终可以重复使用,并且在其生命周期内无法打开。
当Account模型的盒子被制作出来时,一套规则会被写进盒子里,而一些按钮也会被放置在盒子中,这样人们就可以和盒子互动了。例如,规则可能这样表示:如果一方想转账,那么她或他或它需要出示身份证明的一种形式,并输入密码。一旦完成前面的步骤,就需要以下信息:转账金额、收件人和其他信息。一旦进入,她或他或者它需要按下转移按钮才能完成转移。在收到信息后,它会从您的金额中扣除并更改到另一方的帐户,然后更新所有内部数据。
熟悉编程的人会很快发现Account模型类似于现实世界中的OOP(面向对象编程,一种计算机编程架构),按钮的概念类似于API(应用程序编程接口)。
如果我们扩展盒子隐喻,以太坊的功能更像ATM机。
在Account模型中,该盒子保存逻辑和数据。在将逻辑写入工厂设置的盒子后,永远不能更改它。您只能在需要修改数据时使用外部按钮。每个人的钱都记录在盒子里。要进行事务是,只需要输入事务信息,该盒子便会根据规则处理的请求进行数据更新。
——Cell模型
在Cell模型中,我们也可以将Cell看作一个盒子,因为它与UTXO模型非常相似,可以包含任意锁定的任意对象。
你可以对该框执行并编写一组规则来指定该盒子可以存储什么。通过这种方式,单元内的数据可以表示货或加密猫之类的资产。此外,UTXO中的锁也是相同的。但是在单元格模型中,用户可以自由地更改和使用定制的锁。(你可以将普通挂锁与指纹锁或数字锁做对比)
总的来说,Cell模型是一个广义的UTXO模型,具有以下两个意义:第一、锁是可定制的; 第二、盒子可以存储用户定义的数据。
Nervos(分层架构的分布式应用网络)的核心项目CKB 中,有一个编程模型便结合了比特币编程模型和以太坊编程模型的优点。
有些人可能会对Cell模型如何使用其编程模型感到好奇。
首先理解区块链系统的演变是很重要的。比特币是p2p(点对点)支付系统的衍生,后来又诞生了更广义的分散式应用平台——以太坊。区块链的进一步发展带来了各种各样的新项目,而且越来越多样化。
由于需要全网共识的交易和存储成本高昂,因此区块链不可避免地采用一种架构。该架构允许在一致同意的范围内实现灵活性,从而允许它们大规模地交付低成本交易。
两大主要障碍
——可扩展性问题
继续阻碍区块链发展的一个障碍是可扩展性问题。如果我们无法缓解这一问题,区块链能力将受到限制,我们将无法看到强大的高级应用程序的开发,继而释放分散经济的真正潜力将面临挑战。
可扩展性是“区块链三难”的一部分,其中还包括安全性和分散性。而一个区块链系统最多可以具有三难困境中的2个。
——交易成本问题
第二个障碍是交易成本问题。一个社会整体交易成本的降低是衡量一项技术在规模上可行性的最有力指标之一。由于需要全网共识的交易和存储成本高昂,因此区块链不可避免地采用一种架构。该架构允许在一致同意的范围内实现灵活性,从而允许它们大规模地交付低成本交易。
解决方案:分层架构
计算机爱好者知道他们的设备包含一个复杂的分层架构。该分层架构中包括内存、硬盘、多级缓存和各种寄存器。这种架构允许普通大众低成本使用,同时利用其可伸缩的能力以满足不断增长的计算挑战。
我们可以将相同的设计原则应用于区块链。通过分层的架构,可以创建经济实惠且通用基础设施。在我看来,这是区块链驱动的世界唯一可行的未来。随着Lightning、(闪电网络)、Plasma(以太坊扩容的四大方案之一)和支付通道的兴起,我们已经可以看到这种类型的架构正在兴起以及它所促进的用例。在接近这种分层的区块链架构时,重要的是要检查构成区块链系统的三种不同数据模型之间的关系:UTXO模型,Account模型和Cell模型。
——验证与计算模型
Cell模型源自UTXO模型,因此是验证模型。相反,Account模型是计算模型。
在资产从第2层返回到第1层时,第2层解决方案会利用证明提交和验证机制(如闪电网络)。而由于第1层扮演的是验证角色,而不是计算角色,因此我们可以看到UTXO或Cell模型是这种结构的合适方法。
——解决规模扩增性问题
目前,以太坊和“下一代”区块链面临着规模不断增长的严峻挑战。虽然大规模采用已实现突破,但全节点的数据存储成本日渐增高,包括各种僵尸帐户的扩增,也让情况变得更糟。
使用Account模型时,所有用户的资产都存储在一个合约中。如果没有直接的方法来为每个用户分割状态,则很难根据每个用户占用状态的容量和持续时间向他们收费。
同时,这对支付通道收费的实施也提出了挑战。目前在以太坊,交易费用是一次性支付,授予永久性存储。但鉴于区块链是公共基础设施,这种模式是不可持续的。我们可以看到,持续支付仓储空间租金是一种更加合理的方式。
在单元模型中,每个用户的数字资产分别存储在各自的单元中。如果用户不想继续持有资产,则可以释放单元中的数据,并且可以将存储容量出售或借给其他用户。这种设计确保了第1层不会无限期地存储废弃的资产,并为状态存储开辟了新的可能性。
结论
总的来说,当考虑存储和验证要求时,单元模型最适合分层区块链架构的需求。
附:UTXO与ACCOUNT优缺点对比
UTXO 模型
UTXO 模型中,交易只是代表了 UTXO 集合的变更。而账户和余额的概念是在 UTXO 集合上更高的抽象,账号和余额的概念只存在于钱包中。
优点:
计算是在链外的,交易本身既是结果也是证明。节点只做验证即可,不需要对交易进行额外的计算,也没有额外的状态存储。交易本身的输出 UTXO 的计算是在钱包完成的,这样交易的计算负担完全由钱包来承担,一定程度上减少了链的负担。
除 Coinbase 交易外,交易的 Input 始终是链接在某个 UTXO 后面。交易无法被重放,并且交易的先后顺序和依赖关系容易被验证,交易是否被消费也容易被举证。
UTXO 模型是无状态的,更容易并发处理。
对于 P2SH 类型的交易,具有更好的隐私性。交易中的 Input 是互不相关联的,可以使用 CoinJoin 这样的技术,来增加一定的隐私性。
缺点:
无法实现一些比较复杂的逻辑,可编程性差。对于复杂逻辑,或者需要状态保存的合约,实现难度大,且状态空间利用率比较低。
当 Input 较多时,见证脚本也会增多。而签名本身是比较消耗 CPU 和存储空间的。
ACCOUNT 模型
对于 Account 模型,Account 模型保存了世界状态,链的状态一般在区块中以 StateRoot 和 ReceiptRoot 等形式进行共识。交易只是事件本身,不包含结果,交易的共识和状态的共识本质上可以隔离的。
优点:
合约以代码形式保存在 Account 中,并且 Account 拥有自身状态。这种模型具有更好的可编程性,容易开发人员理解,场景更广泛。
批量交易的成本较低。设想矿池向矿工支付手续费,UTXO 中因为每个 Input 和 Out 都需要单独 Witness script 或者 Locking script,交易本身会非常大,签名验证和交易存储都需要消耗链上宝贵的资源。而 Account 模型可以通过合约的方式极大的降低成本。
缺点:
Account 模型交易之间没有依赖性,需要解决重放问题。
对于实现闪电网络/雷电网络,Plasma 等,用户举证需要更复杂的 Proof 证明机制,子链向主链进行状态迁移需要更复杂的协议。
UTXO VS ACCOUNT
对于以上几个优点和缺点,我们再做一些分析和对比。
第一,关于计算的问题。
UTXO 交易本身对于区块链并没有复杂的计算,这样简单的讲其实并不完全准确。主要原因是 Bitcoin 本身的交易多为 P2SH,且 Witness script 是非图灵完备的,不存在循环语句。而对于 Account 模型,例如 Ethereum,由于计算多在链上,且为图灵完备,一般计算较为复杂,同时合约安全性就容易成为一个比较大的问题。当然是否图灵完备对于是否是账户模型并没有直接关联。但是账户模型引入之后,合约可以作为一个不受任何人控制的独立实体存在,这一点意义重大。
第二,关于 UTXO 更易并发的问题。
在 UTXO 模型中,世界状态即为 UTXO 的集合,节点为了更快的验证交易,需要在内存中存储所有的 UTXO 的索引,因此 UTXO 是非常昂贵的。对于长期不消费的 UTXO,会一直占用节点的内存。所以对于此种模型,理论上应该鼓励用户减少生产 UTXO,多消耗 UTXO。但是如果要使用 UTXO 进行并行交易则需要更多的 UTXO 作为输入,同时要产生更多的 UTXO 来保证并发性,这本质上是对网络进行了粉尘攻击。并且由于交易是在钱包内构造,所以需要钱包更复杂的设计。反观 Account 模型,每个账户可以看成是单独的互不影响的状态机,账户之间通过消息进行通信。所以理论上用户发起多笔交易时,当这些交易之间不会互相调用同一 Account 时,交易是完全可以并发执行的。
第三,关于 Account 模型的交易重放问题。
Ethereum 使用了在 Account 中增加 nonce 的方式,每笔交易对应一个 nonce,nonce 每次递增。这种方式虽然意在解决重放的问题,但是同时引入了顺序性问题,同时使得交易无法并行。例如在 Ethereum中,用户发送多笔交易,如果第一笔交易打包失败,将引起后续多笔交易都打包不成功。在 CITA 中我们使用了随机 nonce 的方案,这样用户的交易之间没有顺序性依赖,不会引起串联性失败,同时使得交易有并行处理的可能。
第四,存储问题。
因为 UTXO 模型中,只能在交易中保存状态。而 Account 模型的状态是在节点保存,在 Ethereum 中使用MPT 的方式存储,Block 中只需要共识 StateRoot 等即可。这样对于链上数据,Account 模型实际更小,网络传输的量更小,同时状态在节点本地使用 MPT 方式保存,在空间使用上也更有效率。例如 A 向 B 转账,如果在 UTXO 中假设存在 2 个 Input 和2个 Output,则需要 2 个 Witness script 和 2 个Locking script;在 Account 模型中则只需要一个签名,交易内容只包含金额即可。在最新的隔离见证实现后,Bitcoin的交易数据量也大大减少,但是实际上对于验证节点和全节点仍然需要针对 Witness script 进行传输和验证。
第五,对于轻节点获取某一地址状态,UTXO 更复杂。
例如钱包中,需要向全节点请求所有关于某个地址的所有 UTXO,全节点可以发送部分 UTXO,钱包要验证该笔 UTXO 是否已经被消费,有一定的难度,而且钱包很难去证明 UTXO 是全集而不是部分集合。而对于 Account 模型则简单很多,根据地址找到 State 中对应状态,当前状态的 State Proof 则可以证明合约数据的真伪。当然对于 UTXO 也可以在每个区块中对 UTXO 的 root 进行验证,这一点与当前 Bitcoin 的实现有关,并非 UTXO 的特点。