区块链核心技术演进之路 – 共识机制演进·壹

原文地址:https://www.jinse.com/news/blockchain/24216.html

     一般而言,在介绍区块链时经常会提到两个例子:一是由古老的记账模式延伸到分布式账本,二是拜占庭将军问题(Byzantine Generals Problem)。使用分布式账本目的是让每个节点都能够验证交易,而拜占庭将军问题与账本的一致性有关,即本文要讨论的共识机制(Consensus)。

     区块链上的共识机制主要解决由谁来构造区块,以及如何维护区块链统一的问题,该问题的理论基础是拜占庭容错(Byzantine Fault-Tolerant,BFT)。BFT从上世纪80年代开始被研究,目前已经是一个被研究得比较透彻的理论,存在解的前提条件及具体实现都已有现成算法。不过本文不打算从BFT说起,因为要分析的是区块链共识机制的演进过程,而中本聪并没有采用BFT。其实在我研究比特币伊始,即便在理解了POW机制之后的很长一段时间内,并不了解拜占庭将军问题。后文分析 HyperLedger Fabric的PBFT以及小蚁项目的DBFT时再全面阐述拜占庭将军问题及传统分布式一致性算法(PAXOS、RAFT)。

     共识机制的核心是区块的构建和检验,POW系统构建区块的过程一般称为“挖矿”(mine),POS 系统PPC的区块构建方式一般称为“铸造”(mint),而NXT的区块构建方式一般称为“锻造”(forge)。

POW

      共识机制在以前一般被称为证明方式(Proof),因为比特币采用工作量证明(即Proof-Of-Work,简写为POW)。随着大家对分布式账本一致性问题的不断探索,很多方法被提出来,尤其近期有很多区块链项目回归了对传统BFT算法的改进,在思路上已经跳出了“证明”的语义,因此进一步高度概括为共识机制。我记得第一次碰到工作量证明这一概念时感到很费解,对这种表述方式很头疼,掌握了POW机理后才真正明白,通俗讲就是“通过工作以获得指定成果,用成果来证明曾经付出的努力”。其实我们日常工作生活中经常使用工作量证明,比如学生考试成绩,毕业证以及驾照等,这种证明方式的一个显著特征是往往需要很大的工作量才能拿到指定成果,但这个成果很容易验证。因为我们一般很难去实时监督一个人是否真的付出了这些工作量,所以只能使用工作量的结果来证明。

       再回到比特币的设计思路,中本聪已经使用非对称密码解决了电子货币的所有权问题,用区块时间戳解决了交易的存在性问题,用分布式账本解决了剔除第三方结构后交易的验证问题,剩下需要解决的问题是双重支付,这要求所有节点账本统一,而真正的平等又必须赋予人人都有记账的权利,记账是一件简单的事情,每个人都可以做,显然最终会存在众多大同小异的账本,但我们只需要其中的一个账本就够了。

      中本聪想到给记账加入成本,总账本由各个分页按照时间先后排序,给每个账本分页设立一个评判标准,以区分账本分页是否合格,这给记账增加了难度,同时给每个账本分页加入一个随机元素,用以调节记账难度以保证一定时间段内只有一个人生成合格的账本分页。增加的成本就是工作量,合格的账本分页就是工作量证明。对于比特币而言,所谓的账本分页就是一个区块,区块通过巧妙设计形成区块链,合格的区块可以表述为:

F(Nonce) < Target

      其中Nonce是随机元素,Target是合格区块的量化,每个记账节点的Target一致。此外POW的成功运行还需要配合如下两条约定,Best chain原则:将最长的链条视为正确的链条。

       激励原则:找到合格的区块有奖励收益。

1条约定为硬性规则,无条件遵守,大家要么不玩,要玩就遵守这条原则,毕竟共同的目标是找到一致性账本,而最长的链条代表最大的工作量,如果没有这条约定,每个人都只会构造自己的区块链,无法统一。第2条为工作量激励,既然记账有成本,那唯有收益才能驱动大家都去记账,参与记账构造区块变成投资行为,其成本和收益风险在第1条约束下形成博弈,驱动所有节点按约定规则老老实实够造区块,最终达到纳什均衡。

具体实现方式,比特币采用哈希(Hash)算法,关于哈希算法的原理和特点在前一篇文章(挖矿演进)已经详细讨论。逻辑上比特币是对整个区块进行哈希运算,但真正实现并非将整个区块数据作为哈希函数的参数,区块大体可分为区块链头和交易列表两部分,交易列表通过构造成Merkle树最终浓缩成Merkleroot内置于区块头,区块头只有6个字段,共80字节,如此设计首先带来的好处是方便哈希运算,每次运算只需要80字节的参数输入,而不是整个区块的数据,但交易列表的任何变化又能体现在哈希运行结果上。


比特币采用SHA256哈希运算,且每次都是连续进行两次SHA256运算才能作为最终结果,前一次运算的结果作为后一次运算的输入,即Double SHA256,一般简称SHA256D,扩展上面的公式,比特币合格区块判断依据如下:

SHA256D(nVersion,hashPreBlock,hashMerkleRoot,nTimes,nBits,Nonce)<MAXTARGET/Diff

其中式子左边的6个参数(区块头)在前一篇文章已经解释,MAXTARGET为最大目标值,常量;Diff代表难度,全网难度一致。MAXTARGET/Diff即通常所说的当前目标值。

很显然,POW的核心要义为:算力越大,挖到块的概率越大,维护区块链安全的权重越大。相对其他共识机制而言,POW逻辑简单,容易实现,容错达50%,其安全有严格的数学论证。

 POS

 POW并非完美,其中被指责最多的主要有两点,一是浪费能源,二是风险和收益博弈必然导致联合挖矿,而大算力矿池可能会对系统的去中心化构成威胁。

于是在2011年,一个名为Quantum Mechanic的数字货币爱好者在Bitcointalk论坛提出Proof-of-Stake(POS)证明机制,该机制被充分讨论之后证明具有可行性。如果说POW主要比拼算力,算力越大,挖到一个块的概率越大,POS则是比拼余额,通俗说就是自己的手里的币越多,挖到一个块的概率越大。POS合格区块可以表述为:

F(Timestamp) < Target * Balance

POW相比,式子左边的搜索空间由Nonce变为Timestamp,Nonce值域是无限的,而Timestamp极其有限,一个合格区块的区块时间必须在前一个区块时间的规定范围之内,时间太早或者太超前的区块都不会被其他节点接纳。式子右边的目标值引入一个乘积因子余额,可见余额越大,整体目标值(Target * Balance)越大,越容易找到一个区块。因为Timestamp有限,POS铸造区块成功率主要与Balance有关。

POS只是代表一种共识机制理念,具体有多种实现方式,下面重点解析两种比较经典的实现思路。

 Peercoin

 Peercoin(点点币,PPC)于2012年8月发布,最大创新是其采矿方式混合了POW工作量证明及POS权益证明方式,其中POW主要用于发行货币,未来预计随着挖矿难度上升,产量降低,系统安全主要由POS维护。目前区块链中存在两种类型的区块,POW区块和POS区块。PPC的作者为同样不愿意公开身份的密码货币极客Sunny King,同时也是Primecoin的发明者。

要掌握Peercoin的POS机制,需要重点理解Sunny King专门为PPC设计的几个核心概念:Coinstake,Kernel,Stake Modifier,Modifier Interval,Stake Reward,Coinage等。

Coinstake

为了实现POS,Sunny King专门设计了一种特殊的交易,叫Coinstake,Coinstake的设计借鉴于中本聪的Coinbase设计。本质上Coinbase和Coinsake都是一笔交易,只是对他们的输入输出做了一些硬性限制。

Coinstake的设计又需要有别于Coinbase,这样才不会扰乱系统原有的POW机制,简单对比一下两者结构上的不同,

Coinbase结构要求:

输入数量必须等于1,且输入的prevout字段(指定前一笔交易的输出)必须置空值。输出数量必须大于等于1。


Coinstake结构要求:

输入数量大于等于1,且第一个输入的prevout字段不能为空,即要求Kernel必须存在。输出数量大于等于2,且第一个输出必须置空值。

这两种特殊交易在区块链中存放的位置也有特殊要求,中本聪规定每个区块的第一笔交易必须放置Coinbase,反之,Coinbase不能出现在区块的其他位置。Sunny King显然不想破坏这个规则,他增加了一条规则,对于POS区块,第二笔交易必须放置Coinstake,反之,Coinstake不能出现在其他地方。换言之,只要第二笔交易是Coinstake,那么这个区块就当POS区块来处理。

Coinbase和Coinstake都不会被单独广播,而只存在于区块中,因此客户端节点一般都不允许进入内存池,当花费这两种交易时,都需要检测是否已经成熟。

Kernel Protocal

Coinstake的第一个输入(Input 0)叫Kernel,Kernel在POS机制里确实起到核心作用,合格区块的判定与之息息相关。PPC合格区块判断条件为:

SHA256D(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime)< bnTarget * nCoinDayWeight

式子左边的每一个参数都有明确的设计目的,其中,

nStakeModifier:专门为POS设计的调节器,按照以上公式,如果没有参数nStakeModifier,当一个人收到一笔币得到网络确认之后,他立即就能提前计算得知自己在未来何时可以锻造区块,这显然不符合设计目标,Sunny King希望POS矿工和POW矿工一样做盲目探索,以实时在线维护区块链,nStakeModifier的设计就是为了防止POS矿工提前计算。nStakeModifier可以理解为POS区块的一个属性,每一个区块对应一个nStakeModifier值,但nStakeModifier并不是每个区块都变动,不过协议规定每隔一定时间(Modifier Interval)必须重新计算一次,取值与前一个nStakeModifier以及最新区块哈希值有关,因此POS矿工无法提前计算,因为他不知道未来的区块哈希值。

也就是说,在PPC系统中,除了存在区块链,币链(币的交易签名历史),还隐藏着一个很少被提及的链条——权益调节器链条。

值得一提的是,Sunny King是在PPC后来的版本才加入这个调节器的,一开始他使用nBits。

txPrevKernel对应的前一笔交易。

txPrev.block.nTimetxPrev所在区块的时间戳,一笔交易被纳入区块的时间是交易发起者不能确定的,节点有可能通过提前计算预估到未来对自己有利的时间戳,这个参数就是为了防止节点利用这种预估优势提前生成大批交易。

txPrev.offsettxPrev在区块中的偏移量,用以降低网路节点同时生成coinstake的概率。

txPrev.nTimetxPrev构造时间,设计目标如txPrev.offset。

txPrev.vout.nKernel在txPrev中的输出下标,设计目标如txPrev.offset。

再看等式右边,bnTarget:全网当前目标难度基准值,类似POW中的当前难度值,由nbits记录。nCoinDayWeightKernel的币龄。

由以上式子可知,Sunny King一方面希望能给POS矿工提供充足的随机性,另一方面搜索空间严格局限于Coinstake的时间戳字段,以保证影响找到合格区块链的最大因素是Kernel的币龄。

节点在锻造区块时,首先从自己所有的UTXO中选定一个作为Kernel,构造coinstake,计算hash,如果不合格,重新构造coinstake,重构时时间戳Time会改变,也可以改变Kernel,以得到不同的Coinstake,如此往复,直到找到合格区块。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值