098df9d1d07eaea24e34084e67cdd746
016 | 漫谈区块链共识机制

共识机制是区块链的一个核心特征,是保证区块链系统在分布式架构下的一致性方案。目前主流的也有好多种共识算法:POW、POS、DPOS、RCP、PBFT、DBFT 等等。网上已经充斥了很多对这些共识算法的简单介绍,但基本流于表面而缺少深入的讲解,从而读者们也很难理解到这些共识机制背后的核心原理。而本文将以深入浅出的方式讲解区块链共识机制,但由于篇幅有限,因此,只会讲解最重要的两种区块链的共识机制,即比特币和以太坊的共识机制。

比特币共识机制

比特币是区块链的第一个应用,也是第一个实现了共识机制的,因此,要理解区块链共识机制,自然也要先从比特币共识机制开始。另外,虽然很多文章都提到比特币的共识机制为 POW(Proof of Work,工作量证明),但实际上,POW 只是整个比特币共识机制中的一部分,虽然是核心的那部分,但却不是全部。其实,比特币的分布式共识是由网络节点的 4 种独立过程相互作用而达成的:

  • 每个全节点基于一份长长的判断标准清单对每个交易进行独立验证
  • 每个挖矿节点独立将多个交易打包进新区块,通过完成 POW 算法的验算
  • 每个节点独立验证新区块并组装进区块链
  • 每个节点独立选择最长链,即在 POW 机制下累计工作量最多的那条链

先说第一种过程,对交易的独立验证。每个节点收到每一个交易之后,都会先根据一份很长的判断标准清单对该交易进行有效性校验,包括但不限于校验交易的语法和数据结构是否正确、输入和输出是否为空、输入总额是否小于输出总额、每一个输入所引用的输出是否已经被消费,等等。如果该交易通过所有验证,则可以说明该交易是有效的,那么,该节点就会将该交易放入本地的交易池(或称内存池),并将该交易广播给其他相临的节点。如果没通过验证,则会废弃该交易,也不会将其广播出去。其他节点接收到该交易后,也各自做同样的独立校验,校验为交易有效之后,同样也放入各节点自己的交易池,并继续广播给其他节点。所以,理论上来说,无效的交易一开始就会被废弃,而有效的交易最终会到达整个网络所有节点,并被每个全节点所保存,即全网达成了“该交易有效”的共识。

接着,再来聊聊第二种过程,了解有效的交易是如何被打包进区块的。经过一段时间后,一般是 10 分钟左右,每个节点的交易池里会收集到很多有效但还未确认的交易,这些交易会组装成一颗 Merkle Tree。关于 Merkle Tree 的结构,我们在之前的文章《014|从微观到宏观理解区块链》已经讲过,这里就不赘述了。不过,组装进 Merkle Tree 的第一笔交易是比较特殊的,这是一笔创币交易,也叫 Coinbase 交易,新的比特币就是从该笔交易产生的。这笔交易是由节点自己创建的,并将挖矿奖励支付到矿工自己的地址,挖矿奖励包括新创建的比特币和打包进该区块所有交易的手续费总额。组装好 Merkle Tree 之后,就得到 Merkle Root,再结合区块头的其他 5 个字段——Version、Pre Block、Times、Difficulty、Nonce,总共 6 个字段合在一起经过两次 SHA256 计算得到区块哈希值。一个有效的区块要求其哈希值必须小于 Difficulty 难度值,写作本文时的难度要求哈希值至少已经有 18 个 0 开头。挖矿其实就是通过修改参数的值而不断计算区块哈希值,直到计算出符合难度要求的哈希值。一般是通过修改 Nonce 值来计算区块哈希值,其他 5 个字段基本是不变的。而由于哈希函数的特性,难度值越大,理论上计算出符合要求的哈希值所需的计算量就越大。举个简单例子,比如你扔三个骰子,如果难度要求总和小于18,那是非常容易达到的,基本扔个一两次就能满足要求了;而如果加大难度,要求总和小于9,那从概率上来说相对就没那么容易了,可能要扔个十几次甚至几十次才能达到;而如果要求总和等于 3,那只能扔出三个 1 才行,这谁都知道要达到的概率是很低的,也许扔个一两百次才可能出现。因此,从统计学来说,一定的难度值可以推算出概率上对应所需的计算次数,也就是“工作量”,所以,只要你达到了难度要求,也就间接证明你付出了对应的工作量,这就是工作量证明

当某个节点计算出符合难度要求的区块哈希时,即说明该矿工挖矿成功了,该节点就会将此区块组装到本地的区块链,同时也将此区块广播给其他节点。然后,就进入第三种过程了。当其他节点收到此区块时,也会各自独立验证该区块是否有效。和独立验证交易一样,也存在一份验证标准清单,包括但不限于校验引用的上一个区块是否是否正确、难度值是否符合标准、区块哈希是否真的符合难度要求、Coinbase 交易中的挖矿奖励是否多于应得的、整个区块的每笔交易是否都是有效的,等等。其中,难度值是有标准的计算公式的,每个节点都会根据标准公式独立计算实际的难度值,所以,矿工如果不按照标准而自己设置一个较低的难度,在其他节点是无法通过的。同样,挖矿奖励也是有标准公式的,所以,如果矿工给自己奖励过多的比特币,在其他节点也是同样无法通过的。每个节点验证该区块为有效之后,也会各自将该区块组装进它们本地的区块链,并继续将该区块广播给其他节点。

由于所有节点同时在挖同一个区块,就有可能会出现多个节点同时挖出了同个区块,并都将各自挖到的区块广播到其他节点。假设有两个节点同时挖出了新区块,分别为区块 N1 和 N2,它们的上一个区块都是 P。有些节点会先收到 N1,它们会将 N1 先组装进它们本地的区块链,也称为主链。但之后不久,这些节点也会收到 N2,这时候,它们会将 N2 放入备选链。而其他节点则先收到 N2 再收到 N1,则 N2 在它们的主链上,而 N1 在它们的备选链上。这时候,整个区块链暂时就分成了两个分叉,而要打破这种局面,就要看下一个生成的区块是基于 N1 还是 N2 了。如果下一个区块是基于 N1,自然,N1 的这条链就变成了最长链,也是累计工作量最多的链。那么,那些将 N2 链设为主链的节点就会根据实际情况自己选择将 N1 链改为主链,而 N2 将成为孤块而被废弃。

以上就是比特币共识机制的核心内容了,说白了其实就是根据一些所有节点都认可的标准对每个交易和区块的创建和校验进行独立验证,当大多数节点都认可并写入自己的区块链的时候,就自动形成了分布式共识。所有区块链基本都是这个逻辑,不同区块链主要在于制定的标准不同,比特币主要就是基于 POW 机制,这种机制实现简单,但它会造成大量的能源浪费,由于所有节点同时竞争挖矿同一个区块,而基本只有一个节点能胜出,那其他未胜出的节点所消耗的算力能源就白费了。另外,每次交易确认(即出块时间)大概 10 分钟,一笔交易一般要有 6 次确认才算安全,那基本就要 1 个小时了,这共识达成的时间太长了。

以太坊共识机制

以太坊的共识机制也是基于 POW 的,但与比特币相比,主要有两点不同:一是挖矿时间控制在 10 ~ 19 秒之间,出块时间比比特币快了很多;二是对于孤块也有挖矿奖励。在比特币中,孤块(即上文的 N2 区块)是会被丢弃的,挖出了孤块的矿工是得不到任何奖励的。但在以太坊中,孤块是能被打包进区块里的,如果后续的区块将前面产生的孤块也打包进区块里,那这个孤块就变成了叔块,那么,挖到这个叔块的矿工就能得到奖励,而将叔块打包进区块的矿工也能得到额外的奖励,但每个区块最多只能包含两个叔块,而且也不能包含太久的孤块,最多只支持到 7 层的祖先孤块。由于以太坊的出块时间短很多,那自然更容易出现临时分叉而产生孤块,而且这么短的时间内,每个区块也很难能够在全网充分传播,那对于网速慢的矿工来说,就非常吃亏了。所以,为了平衡各方利益,以太坊才设计了叔块机制。写作本文时,叔块率在 16.9% 左右。

不过,以太坊正在计划从 POW 机制切换为 POS(Proof of Stack,权益证明)机制,其新的共识机制名为 Casper,其存在两个不同实现的版本,分别是:

  • Casper the Friendly Finality Gadget(FFG)
top Created with Sketch.