共识机制概述

本文最后更新于:2023年6月19日 晚上

熟悉一下共识机制

pow

工作量证明

DPOS

DPOS 又称 Delegated Proof of Stake,即委托股权证明,最为形象地解释为:

公司员工总数有 1000 人,每个人都持有数额不等的公司股份。每隔一段时间,员工可以把手里的票投向自己最认可的 10 个人来领导公司,其中每个员工的票权和他手里持有的股份数成正比。等所有人投完票以后,得票率最高的 10 个人成为公司的领导。如果有领导能力不胜任或做了不利于公司的事,那员工可以撤销对改领导的投票,让他的得票率无法进入前 10 名,从而退出管理层。

在 DPoS 共识算法中,区块链的正常运转依赖于受托人(Delegates),这些受托人是完全等价的。受托人的职责主要有:

  1. 提供一台服务器节点,保证节点的正常运行;
  2. 节点服务器收集网络里的交易;
  3. 节点验证交易,把交易打包到区块;
  4. 节点广播区块,其他节点验证后把区块添加到自己的数据库;
  5. 带领并促进区块链项目的发展;
    受托人的节点服务器相当于比特币网络里的矿机,在完成本职工作的同时可以领取区块奖励和交易的手续费。

拜占庭将军问题

拜占庭是东罗马帝国的首都,为了防御外敌入侵,周边驻扎了军队,而且每个军队都分隔很远,相互独立,将军与将军之间只能靠信差传递消息。在战争的时候,拜占庭军队内所有将军必需达成一致的共识(进攻或撤退),才有胜算把握。但是,在军队内部有可能存在叛徒,左右将军们的决定。这时候,在已知有成员叛变的情况下,其余忠诚的将军如何达成一致的协议,拜占庭问题就此形成。Lamport 证明了在理想状态下,背叛者为 m 或者更少时,将军总数只要大于 3m,忠诚的将军就可以达成一致。
从技术上理解,拜占庭将军问题是分布式系统容错性问题。加密货币建立在 P2P 网络之上,是典型的分布式系统,类比一下,将军就是 P2P 网络中的节点,信使就是节点之间的通信,进攻还是撤退的决定就是需要达成的共识。如果某台独立的节点计算机拓机、掉线或攻击网络搞破坏,整个系统就要停止运行,那这样的系统将非常脆弱,所以容许部分节点出错或搞破坏而不影响整个系统运行是必要的,这就需要算法理论上的支撑,保证分布式系统在一定量的错误节点存在的情况下,仍然保持一致性和可用性

比特币的解决方案-pow

首先,维持周期循环,保证节点步调一致。这个世界上,最容易达成的就是时间上的共识,至少“几点见面”、“什么时候谈判”这样的问题很好解决吧,不然其他的都不用谈了。比特币有一个算法难度,会根据全网算力自动调整,以保证网络一直需要花费 10 分钟来找到一个有效的哈希值,并产生一个新区块。在这 10 分钟以内,网络上的参与者发送交易信息并完成交易,最后才会广播区块信息。拜占庭将军问题复杂在将军步调不一致,比特币杜绝了节点(将军们)无限制、无规律的发送命令的状态。
其次,通过算力竞赛,确保网络单点广播。将军们如果有个“带头大哥”,事情就好办了。这里的“带头大哥”可以简单的竞争得来,举个极端的例子,说好的 8 点钟谈判,那么先到的就是“带头大哥”,可以拟定草稿,等其他人到了签字画押就行了。 “工作量证明”就是一种竞赛机制,算力好的节点,会最先完成一个新区块,在那一刻成为“带头大哥”。它把区块信息立即广播到网络,其他节点确认验证就是了。比特币通过时间戳和电子签名,实现了这样的功能,确保在某一个时间点只有一个(或几个,属于分叉行为)节点传输区块信息,改变了将军们互相传送的混乱。
最后,通过区块链,使用一个共同账本。对于单个区块,上述两条已经可以达成共识了。但现在的问题是,有一个叛徒(不诚实节点)修改了前面区块的信息,计划把钱全部划归自己所有,当它广播新区块的时候,其他节点如何通过验证?如果大家手里没有一份相同的账本,肯定无法验证,问题就会陷入僵局。基于 P2P 网络的 BT 技术是成熟的,同步一个总帐是很简单的事情。网络中的节点,在每个循环周期内都是同步的,这让每个节点(将军)做决策的时候就有了共同的基础。如果每个节点都独立维护自己的账本,问题的复杂性将无法想象,这是更广泛基础上的共识。

Fabric 的解决方案-DPOS

应用程序和 Peer 节点

当应用程序需要访问账本和链码的时候,他们总是需要连接到 Peer 节点。Hyperledger Fabric SDK 将这个操作变得非常简单,它的 API 使应用程序能够连接到 Peer 节点,调用链码生成交易,提交交易到网络,在网络中交易会被排序并且提交到分布式账本中,并且在这个流程结束的时候接收到事件。
image.png
完整流程
Peer 节点和排序节点,确保了账本在每个 Peer 节点上都具有最新的账本。在这个例子中,应用程序 A 连接到了 P1 并且调用了链码 S1 来查询或者更新账本 L1。P1 调用了链码 S1 来生成提案响应,这个响应包含了查询结果或者账本更新的提案。应用程序 A 接收到了提案的响应,对于查询来说,流程到这里就结束了。对于更新来说,应用程序 A 会从所有的响应中创建一笔交易,它会把这笔交易发送给排序节点 O1 进行排序。O1 会搜集网络中的交易并打包到区块中,然后将这些区块分发到所有 Peer 节点上,包括 P1。P1 在把交易提交到账本 L1 之前对交易进行验证。当 L1 被更新之后,P1 会生成一个事件,该事件会被 A 接收到,来标识这个过程结束了。

Peer 节点可以马上将查询的结果返回给应用程序,因为满足这个查询的所有信息都保存在 Peer 节点本地的账本副本中。Peer 节点从来不会为了应用程序的查询返回结果而去询问其他 Peer 节点的。但是应用程序还是能够连接到一个或者多个 Peer 节点来执行一个查询;比如,为了协调在多个 Peer 节点间的一个结果,或者当怀疑数据不是最新的时候,需要从不同的 Peer 节点获得更新的结果。在这个图标中,你能够看到账本查询是一个简单的三步流程。
更新交易和查询交易起点相同,但是有两个额外的步骤。尽管更新账本的应用程序也会连接到 Peer 节点来调用链码,但是不像查询账本的应用程序,一个独立的 Peer 节点目前是不能进行账本更新的,因为其他的 Peer 节点必须首先要同意这个变动(即达成共识)。因此,Peer 节点会返回给应用程序一个被提案过的更新,这个 Peer 节点会依据其他节点之前的协议来应用这个更新。第一个额外的步骤,也就是第四步,要求应用程序将响应的提案过的更新发送到网络中,网络中的 Peer 节点会将交易提交到它们相应的账本中。应用程序会收到排序节点打包了交易的区块,然后将他们分发到网络中所有的 Peer 节点,在区块被更新到每个 Peer 节点本地账本的副本中之前,这些区块都需要被验证。**排序流程需要一定时间来完成 (数秒钟)**,因此应用程序会被异步通知,像步骤五中展示的那样。

类图

数据库表


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!