共计 3182 个字符,预计需要花费 8 分钟才能阅读完成。
在接下来的秘猿科技小课堂里,我们会从技术角度、经济模型设计角度、以及共识角度来拆解 Nervos 加密经济网络中,底层公链 CKB 的设计理念。而本文将会作为技术角度核心设计 Cell 模型的预备文章,通过本文,我们希望读者能够理解比特币以状态为中心设计的优势!从而,能够在接下来的几篇文章中,更加充分的理解 Cell 模型对于比特币 / 以太坊模型的传承与突破。(PS. 本文源于 2018 年初,秘猿科技在招商银行总行举办的一次金融区块链闭门会,公链 CKB 是对文中思想的具体实现。)
秘猿科技区块链小课堂第 16 期
如何对状态机建模
状态机是计算机的一个基本模型,它可以分成二个部分:状态和操作。状态是指计算机里的数据;操作是指对数据进行的操作。如果把状态机比喻成日常使用的数学计算器,计算器屏幕上显示的就是状态,按「按键」就是对计算器的操作。
状态机模型
区块链用许多的节点共同模拟了一台多复本的状态机。在许多区块链或者分布式系统中,用户发出的签名交易包含了对状态机的操作,节点执行共识协议对所有操作进行排序,然后按共识排好的顺序执行操作,计算出新的状态。
多复本状态机
举例:我们先保证所有节点初始状态一致,就是让每人手上的计算器开始状态为数字 0。然后我们把要执行的操作广播给每个操作员,这四个操作员算完后,这个计算器上的最终结果是一模一样的。为什么会有一样的结果?因为他们有一个相同的初始状态。接着,我们用共识算法保证了相同的操作顺序。所以最后一定有一个相同的最后状态。
状态机的概念在区块链里面非常重要,但我们往往忽视其中的基本细节。设计区块链最应该考虑的因素,是应该以状态为中心,还是以操作为中心进行设计?这二种不同的设计理念会对整体架构产生很大影响,这也是比特币和以太坊架构的一个根本区别:比特币是以状态为中心的设计,以太坊是以事件为中心的设计。
这两者有非常大的区别。如果以事件为中心,计算是在节点上发生;以状态为中心的话,计算是在客户端发生。计算转移到客户端,节点的计算就相应减少。交易包含最后的状态的话,节点可以很方便的判断交易的相互依赖关系。计算在节点上发生的话,客户端就可以很简单。所以我们需要根据目标来权衡这个事情。其实很难说谁更好,只是看我们目标是什么。
如何设计账本
区块链被称为分布式账本,记录着所有者和资产之间的关系。账本里有二个概念,一个是资产,一个是所有者。所以可以从二个方向去设计系统。
账本设计
账户模型以「人」为核心建模,先建立账户的概念,再记录他们的账户里有多少钱,以太坊、CITA、Ripple 都是这个模型;以「资产」为核心建模,最基础的概念是资产,比如 UTXO,在 UTXO 的基础上去记录所有权。以资产为核心建模,更适合并行处理,一个人所拥有的资产不再是一个字段,而是可能分成十份。我可以独立去操作这十份资产。
RSM 设计
以账户为核心的设计,交易并行处理更难,账户更改只能按照交易顺序一个一个来。但是,账户模型可以很方便的去记录账户相关的元数据,比如说这个账户有哪些权限。所以对于许可链来说,账户模型是非常适合的选择。
如何选择共识
在公有链上,比特币所开创的 Nakamoto 共识,在开放网络下,引入了经济激励,在开放网络下实现了对拜占庭错误的容忍,但也付出了性能上的代价。许可链中通常使用传统拜占庭共识的变种,充分利用了分布式系统领域过去几十年的研究成果。优点是延迟非常低、吞吐量很高。
在网络分裂时,许可链是选择网络停止服务,等待网络的恢复,来保证一致性;公有链则偏好可用性,在网络分裂时可以容忍账本分成二个版本,等网络恢复之后,选择其中一个版本作为正确的版本,废弃掉另外一个版本。公有链想要的是 24 小时不间断的服务;金融行业回滚的代价太大,想要的却是一致性。所以选择 C 还是选择 A,取决于你的需求是什么。
区块链共识的四个阶段
第一阶段是「加入共识」
加入共识阶段决定了什么样的节点可以参与共识协议。比如:在比特币中,一开始是任意节点都可以加入共识。现在则可以认为比特币的共识加入机制变成了买矿机,有矿机才能参与共识。在 PoS 里面,则是需要持有代币或者交保证金才能参与共识。在 DPoS 里面,代理人需要获得足够多的投票才能参与共识。学术界也有其他的研究,比如是加入共识也需要提供一个工作量证明。
通过加入共识阶段的设计,我们可以把参与共识的节点范围缩小。比如公有链上有一万个节点,但是我们只要设计一个加入共识的机制,就可以把共识范围缩小到 100 个节点,一旦我们可以缩小这个共识范围,后面就可以用任意的方法去实现共识。
第二阶段是「出块」
这个阶段需要选择一个节点来将交易打包,生成一个新的区块。通常有三种方式:
1. 共识节点按轮流顺序出块,比如 PoA。
2. 采用随机出块方式,从 共识节点里随机挑一个节点出块,比如 PoW, NXT-PoS,DPoS。
3. 在不出问题的情况下一直保持一个节点出块,目前只有许可链会用这种方式。
第三阶段是「进行验证和投票」
涉及到共识投票的过程,这里的设计就非常多。现在大家经常在讨论的一些新的共识方法,往往只是第二和第三阶段的方案。
投票主要有用区块投票和用消息投票两种方式。在 Nakamoto 共识中,新制造的区块是一张投票,下一个矿工挖出的块是对之前一系列区块的投票。每一个区块都是一张票(严格来说票有权重,例如工作量证明),最后那条高度最长,包含的区块(票数)最多,就是胜出的那条链。在许可链里面,常常通过节点之间交换投票消息来对新出的块进行投票,所以在下一个块没有出之前就可以对这一个块完成共识。
第四阶段是「退出共识」
这是常常被忽略的部分。在比特币系统中,退出共识很简单,停止挖矿就行了。在许可链中,我们本来是共识节点,现在不想做共识节点了,则需要有相应的设计,进行共识节点变更。
以上四个步骤是区块链共识的一个完整流程。传统 BFT 共识算法,发挥作用一般是在第三阶段,在网络异步的时候会涉及第二阶段,基本上不讨论其它两个阶段。所以我们如果要将传统的共识算法融入到区块链中,需要另外考虑的问题是非常多的。
未来我们能做什么
在设计 CITA 的时候,我们是为企业级的用户考虑的。他们拥有很好的计算资源,所以我们可以通过内部并行和分片的方式解决区块链面临的性能扩展的问题,把区块链里每一个节点的能力放大一百倍,那么整个网络的能力就会放大一百倍。这是我们 CITA 提出微服务的原由。我们把一个节点拆散,将节点内部变成一个集群是 CITA 能够提升吞吐量的根本原因。在 CITA 里面有很多的微服务,比如 auth 服务是交易验证的,是可以并行处理的。所以我们通过这个方式去解决性能瓶颈问题。
微服务
CITA 的设计目标是多中心的区块链网络。这样的网络不需要太多的节点,就可以创造很高的信任。这是我们自己在某云平台上做的一个实测。用了一个中型的云服务器,一般交易处理可以达到 15000 TPS,测试用例包括存证,合约创建和代币转移,都有比较好的性能。特别指出的,CITA 这种架构对云计算很友好。我们更加倾向从架构的角度、从软件的角度解决各种问题。尽量避免去依赖硬件。
性能对比
在我们工程设计和实现中我们会遇到很多选择,我们往往是选了一边。有没有可能兼得呢?我认为在一些地方是可以的。比如以太坊上的智能合约非常的轻量,通过 evm 合约构造分布式应用时,可以生成成千上万的合约共同来完成一个使命。Fabric 上的合约可以用任意原生语言实现,执行环境比较重。CITA 则同时支持二种方式,既可以跑 evm 合约,又可以跑原生合约。
未来,我们还可以做什么呢?比如现在的共识算法的选择倾向,已经很明显的显示出了混合共识的趋势。我们是不是也可以做到这一点?以状态为中心的设计还是以事件为中心的设计,是不是也能兼得?这正是我们最近在做的一些尝试。 如果能够同时拥有鱼和熊掌,我们可能能够找到一种更好的区块链,尤其是公有链架构 。