区块链共识算法讲解及发展

本文将介绍

① 主流共识算法,简述算法分类,适用范围,应用场景等
② PoW(Proof of Work) 工作量证明
③ PoS(Proof of Stake) 权益证明
④ DPoS(Delegated Proof of Stake) 委任权益证明
⑤ PBFT(Practical Byzantine Fault Tolerance) 实用拜占庭容错算法
⑥ PAXOS 算法
RAFT算法

前导. 主流共识算法简述

共识机制是特殊节点的投票,在很短的时间内完成对交易的验证和确认;对一笔交易,如果利益不相干的若干个节点能够达成共识,我们就可以认为全网对此也能够达成共识。再通俗一点来讲,如果中国一名微博大V、美国一名虚拟币玩家、一名非洲留学生和一名欧洲旅行者互不相识,但他们都一致认为你是个好人,那么基本上就可以断定你这人还不坏。(摘自百度百科)

共识算法是实现共识机制的方法,目前常见的有PoW,PoS,DPoS,PBFT,PAXOS, RAFT等,主流共识算法可大致分为三类
1)挑战证明(Proof of Challenge)
2)权益证明(Proof of Stake)
3)协商证明(Proof of Negotiation)

挑战证明(Proof of Challenge)

简单地说,就是给所有参与者一个有挑战性的问题,谁能在最短的时间内找到答案,那么他就是这轮公认的决策者。PoW是一个典型的例子,每个参与者都必须计算一个块的哈希值,这个哈希值需要由N个前导0组成,谁找到了这个哈希值,那新的区块就属于谁。

权益证明(Proof of Stake)

简单地说,就是根据参与者所拥有的某种资产或授予的权利,标志在转盘上,然后开始转转盘,转到这对应位置的那个参与者,就是该轮公认的决策者。现在的系统,有的根据拥有币的数量,有的根据贡献的储存空间,有的根据积分奖赏的额度等等,千奇百怪。虽然披着不同的羊皮,但他们都是狼,本质都是权益证明。现实生活中,民主选举投票领导人就是这种逻辑,但权益证明有一定随机性。

协商证明(Proof of Negotiation)

简单地说,就是所有参与者坐在一起,通过多轮对话,协商一个新的决策者。例如PBFT,PAXOS都是属于这种类型,需要多轮交互协议,需要形式化证明协议的可靠性安全性。但交互的次数太多引入了复杂性,给网络宽带资源带来了很大负担,这个一个缺点。现实生活中的民主协商制就是这种逻辑。

为了上述各种类型效率,聪明的人类引入了代表机制(Delegated),不需要所有的参与者都参与最后的决策,而是先选出一些代表,每个代表代理一部分参与者的行使权力,例如DPoS。现实生活中,广大人民群众选出人民代表,召开人民代表大会就是这种逻辑。

共识算法的应用场景

脱离应用场景谈算法是没意义的,每一种算法都有各自适用的场景,到底选择哪个取决于实际环境的网络和数据。通常PoW和PoS是公有链常用的共识算法,而PBFT和RAFT是联盟链和私有链中常用的共识算法,在可信环境使用PAXOS或RAFT。

PoW算法代表:比特币 & 莱特币 & 以太坊
PoS算法代表:Peercion(点点币) & Nxt(未来币)
DPoS算法代表:Bitshare & EOS
PBFT算法代表:HyperLedger fabric0.6

下文按算法出现的时间和流行热度详细讲解

1. PoW(Proof of Work) 工作量证明

这是一种通过工作量抢夺决策权的方案。谈PoW不得不提比特币,比特币带火了区块链,同时将共识算法推向人们的视野中。此处以比特币的运作原理讲解PoW。

比特币提出一个方程式,用前一个区块的哈希值和一个随机数nonce计算一个新的哈希值,新的哈希值必须满足N个前导0的要求。谁能最先找到这个nonce,谁有拥有下一个区块。新的区块赋予这个新的哈希值,再以此推算下一个满足条件的new nonce,如此循环,我们称为挖矿。

区块链共识算法讲解及发展_第1张图片

要找到适合的nonce必须经过大量哈希碰撞运算,没有捷径解法,能找到适合的nonce即证明了你已做过大量运算,这就是工作量证明的由来。

PoW一直以来遭人诟病的是耗费算力,所有的节点都来求解,最终只有一个节点解出来,其他节点都白忙活了,浪费大量电力计算资源。

2. PoS(Proof of Stake) 权益证明

在PoW流行的时候,从CPU挖矿到ASIC挖矿,各种专业矿机形成强大算力,理论上有超过51%的算力攻击最长链,那么区块链就会受到威胁,是一个隐患。有趣的是,据说80%的算力集中在中国。众币玩家试图改善算法缓解算力中心化的现象,但徒劳无功。在2011年Bitcointalk论坛上,Quantum Mechainc提出了Proof of Stake机制,这个机制通过验证证明了可行性,于是换一种思路,考虑新的共识机制。

PoS机制简单理解为,网络节点中打开自己的钱包,登录上线增加权重参与挖矿。PoW是依靠计算算力决定区块的产生,而PoS中是通过虚拟币的数量作为抵押,从而有一定几率产生区块,就像在银行中存钱获得利息一样概念。

PoS运行机制:网络的节点把自身的虚拟货币投入PoS机制中,身份变为验证者,PoS机制在这种验证者中随机选择一个作为区块的产生者。投入的货币越多被选中的概率越大,如果在一定时间内这个被选中者没有产生区块,那么再次选择下一个验证者。没有挖矿过程,(点点币)在创世区块内写明了股权分配的比例,之后通过转让交易等方式(通常是IPO)分散到用户手中,然后通过“利息”的方式新增货币。

纯PoS机制的加密货币,只能通过IPO方式发行,这导致了少数人获得大量成本极低的加密货币,如果大量抛售会导致雪崩效应。PoS机制最开始应用在点点币上,Sunny King 提出一种混合挖矿方案PoW&PoS,PoW用于挖矿而PoS用于维护系统。PoS机制也存在51%的攻击隐患,但对比PoW,掌握51%的币量比掌握51%的算力要难得多,随着币种的发行时间越久,被攻击的可能性越低。

3. DPoS(Delegated Proof of Stake) 委任权益证明

随着币圈的发展,比特币提出的“去中心化”变成了一个乌托邦式的笑话,ASIC等矿机的发明使得矿霸和普通用户在算力上的差距相差十万八千里,PoW这种最为“去中心化”的设计反而在现实里慢慢变得最为中心化。

而PoS因为IPO发行和利滚利等原因,使得一些早先拥有代币的持币者,在币的数量和币龄上让后来者有着几乎无法超越的可能,同比特币一样,点点币和未来币等PoS币种也在走向中心化。

趋向中心化,简单地说就是记账权被支配在少数人手里。

这时,DPoS横空出世!代表是EOS币,特点是出块时间短,效率很高,几乎不会分叉。想了解更多关于DPoS技术细节的朋友,请自行谷歌 “DPOS共识算法 - 缺失的白皮书”,里面详细论证了DPoS是如何实现共识算法的健壮性、安全性和有效性。

在介绍DPoS之前,必须谈一谈“去中心化”这个思想。去中心化这个字眼让人联想到民主、平等,而中心化会让人联想到独裁、专制。但是人类真的能脱离中心吗?如果你读过《人类简史》,你应该会知道让现代人逐渐融合的有三股最大的力量 - 经济上的货币秩序、政治上的帝国秩序和宗教上的全球性信仰。世界上所有的国家权力都集中在首都,地区权力集中在省会;每个公司必须有一个董事会,部门需要有一位总经理;生活中的一切都表明了人类活动是需要有中心的(注意,不是中心化)。PoS正是基于这种思想,选出若干代表,每个代表代表了一部分持币者,代表们交流决策新的区块产生,并不需要所有的玩家参与。

DPoS运行机制

区块链项目发起方组织若干个见证人,一般是101个。任何用户都可以参与竞选见证人,然后用户用自己的持币量投票,持币量多的投票权重大。每一轮选举结束后,得票率最高的101个用户将成为项目的见证人,负责打包区块、维持系统的运作并获得相应的奖励。

这些见证人是完全等价的,他们的职责是:

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

DPoS的实质也是PoS,但相比PoS不会因为一个人的持币量过大而出现支配记账权。101个见证人会被随机排列,每个见证人有2秒的权限时间生产区块,如果见证人算力不足或计算机宕机,用户可以随时投票更换见证人。所以DPoS也是区中心化的。

4.PBFT(Practical Byzantine Fault Tolerance) 实用拜占庭容错算法

2015年,比特币已经流行了好几年时间,以太坊也逐渐壮大,区块链开始进入广大人民视野中。聪明的人类已经发现,区块链的应用远不止发行虚拟币玩玩那么简单,它还可以用作记录重要的内容,而这个内容是不可篡改的,而且因为去中心化的思想,还能大大降低了运营成本。厉害了!如果把身份证、学历文凭、发票证明等都以区块链的形式记录下来,那就无人能作假了。于是,区块链迅速向这方面发展。

那么问题来了,以往的区块链项目都以虚拟币为内核,而记录数据的应用并不需要币机制模型。这个时候,HyperLedger(超级账本)应景而生,它是由Linux基金会组织牵头的项目,是一个旨在推动区块链数字技术和交易验证的开源项目。这个分布式账本技术是完全共享、透明和去中心化的,非常适合于金融行业的应用,以及其他的例如制造、银行、保险、物联网等无数个其他行业。

PBFT(Practical Byzantine Fault Tolerance)正是HyperLedger中使用的共识算法。

关于HyperLedger的更多技术介绍,将在后面逐一讲解。

拜占庭将军问题

实用拜占庭容错算法来源于拜占庭将军问题,是Leslie Lamport在1982年用来解析一致性问题的一个虚构模型。拜占庭是古代东罗马帝国的首都,由于地域宽广,守卫边境的多个将军(系统中的多个节点)需要通过信使来传递消息,达成某些一致的决定。但由于将军中可能存在叛徒(系统中节点出错),这些叛徒将努力向不同的将军发送不同的消息,试图会干扰一致性的达成。拜占庭问题即为在此情况下,如何让忠诚的将军们能达成行动的一致。

假如有七位将军,他们想进军敌城。于是A将军发起明天八点出战提议,其他将军也同时发出不同法人进攻提议,将军之间两两相互通知。由于各有想法,不同的将军提议可能是不同的。结果导致一种情况,A将军有4个支持者,B将军有3个支持者,C将军有5个支持者。

又假如七位将军中有一位叛变了(错误节点),这位叛徒向不同的将军提出不同的进攻时间,那每个将军(正常节点)收到的进攻时间都不一样,出现问题;这位叛徒也可能答应每个将军的提议,使得其他将军以为自己的提议已经被对方认同,最终出战时间也不一致。

PBFT运行机制

拜占庭容错算法是解决方案。PBFT系统通常假设故障点数为f个,而整个服务节点点数为3f+1个,数学家已证明一个结论:若系统中有超过f个故障节点,系统将不能正常运行。下图是一个简化的PBFT通讯模式:

区块链共识算法讲解及发展_第2张图片

其中C是客户端,N0~N3代表服务节点,N0是主节点,N3是故障节点,整个协议的运行过程:
1)客户端发送请求,激活主节点N0的服务操作; 
2)主节点收到请求后,启动三阶段的协议向各从节点广播请求;
    1.序号分配阶段,主节点给请求赋值一个序号n,广播序号分配消息和客户端的请求消息m,并将构造pre-prepare消息给各从节点;
    2. 交互阶段,从节点接受pre-prepare消息,每个节点向其他服务节点广播prepare消息;
    3.序号确认阶段,各节点对视图内的请求和次序进行验证后,广播commit消息,执行客户端发来的请求并给客户端响应。
3)客户端等待来自不同的节点的响应,若有2f+1个响应相同,则该响应即为请求的结果。

PBFT算法的三个核心阶段是pre-prepare(预准备阶段),prepare(准备阶段),commit(提交阶段)。
pre-prepare阶段:节点收到pre-prepare消息后,会选择接受或不接受。一个典型情况是消息里的视图编号和请求编号在之前收到的消息里曾经出现过,但是消息的内容却和之前的消息不一样,这时就会拒绝请求。拒绝的原因是主节点不会发送两条有相同编号却有不同内容的消息。
prepare阶段:节点向其他节点发送prepare消息。如果节点收到了2f个不同节点的消息,代表该节点的prepare阶段已经完成。
commit阶段:节点向其他节点广播commit消息。如果节点收到了2f+1个commit消息(包括自己),代表大多数节点已经进入commit阶段,这一阶段已达成共识。于是节点会执行请求,运行结果。

从上述流程可看到,PBFT的通讯量复杂度是o(N^2),所以很难适应全球性的业务流程,适用场景是少量节点的政府和大型企业。目前PBFT的中文文献还不多,算法实现比理论更难,想深入了解就钻研HyperLedger0.6吧。

最后,附上BFT的论文 https://www.microsoft.com/en-us/research/publication/byzantine-generals-problem

5.PAXOS共识算法

Paxos算法也是Leslie Lamport提出的,最初是为了解决ECHO的容错文件系统问题,是一个在分布式系统上应用广泛的算法。区块链作为分布式系统的典型代表,自然少不了用Paxos作共识算法。该算法出现在拜占庭算法后面,拜占庭算法适合在联盟链中使用,而Paxos算法适合在私有链中。因为都是Lamport提出的,所以PBFT和Paxos会有一些相似之处。

在Paxos算法中,有4种角色:
Proposer:提议者    
Acceptor:决策者
Client:产生议题者
Leaner:最终学习决策者

大致运行流程是:Client产生一个议题,Proposer会拿着议题去向Acceptor提问,让多个Acceptor决策,Leaner总结Acceptor决策结果。Leaner最终学习的目标是Acceptor们最终接受了什么议题,而非Client们产生的议题。如果有多数派个Acceptor最后决策了同意的提议,那Leaner就会总结占比大的结果,达到一致性的目的。以一幅图来介绍更加直观:

区块链共识算法讲解及发展_第3张图片

Client和Proposer可以有一个或多个,但Acceptor必须有3个以上的奇数,因为要形成多数派,偶数会打平。如果只有一个Proposer,那所以Acceptor都会顺利通过同样的议题,没有竞争力,如果有多个Proposer就会复杂。下面通过一个简短的故事解析Paxos运行机制。

( FROM: http://www.cnblogs.com/endsock/p/3480093.html#3991965)

假设有2个Client老板(Client1,Client2之间是竞争关系),老板有各自的Proposer秘书,和3个Acccptor(政府官员)

1)现在Client1老板和Client2老板需要对一项议题来进行Paxos过程,议题是 “项目要中标!”,两位老板开始竞争。

2)Proposer当然听Client老板的话了,于是带着议题和现金去找Acceptor政府官员。
注:需要经过两个阶段才能定下议题,第一阶段形成初步支持,第二阶段强化初步支持达到一致性.

3)Proposer小姐带着现金同时知道了Accepor1~Acceptor3官员,1与2官员分别收取了10比特币,找到第3号官员时,没想到遭到了3号官员的鄙视,3号官员告诉她,Proposer-2给了11比特币。不够没关系,Proposer-1已经得到了1,2两个官员的认可,形成了多数派(如果没有形成多数派,Proposer-1回去银行提款再来找官员们给没人20比特币,这个过程一直重复每次+10比特币,知道形成多数派),满意的找老板复命去了。但是此时Proposer-2先生找到了1,2号官员,分别给了他们11比特币。1,2号官员的态度立刻转变,都说Proposer-2的老板懂事,这下Proposer-放心了,搞定了3个官员,找老板复命去了。这个过程是第一阶段提交,只是官员们初步接受贿赂而已。故事中的比特币比喻编号,议题比喻value.
注:这个过程保证了在某一时刻,某一个Proposer的议题会形成多数派进行初步支持

4) 现在进入第二阶段提交,现在proposer-1小姐使用分身术(多线程并发)分了3个自己分别去找3位官员,最先找到了1号官员签合同,1号官员没接受,1号官员告诉他proposer-2先生给了他11比特币。proposer-1小姐知道了在第一阶段中,在她之后又重新形成了多数派(至少有2位官员倒向proposer-2);此时她赶紧去提款准备重新贿赂这3个官员(重新进入第一阶段),每人20比特币。1号官员很高兴拿了20比特币并重新接受了议题,但还没来得及见到2,3号官员,这时proposer-2先生也在行动。

    proposer-2先生也使用分身术分别找3位官员(这里是proposer-2的第二阶段),第2,3号官员顺利签了合同,这时2,3号官员记录client-2老板用了11比特币中标。而1号官员拒绝了,因为1号收到了20比特币并同意proposer-1小姐。没关系,因为已经形成了多数派,所以最终接受了Client2老板中标这个议题,proposer-2先生已经出色的完成了工作。

    这时proposer-1小姐找到了2号官员,官员告诉她合同已经签了,将合同给她看,proposer-1小姐是一个没有什么职业操守的聪明人,觉得跟Client1老板混没什么前途,所以将自己的议题修改为“Client2老板中标”,并且给了2号官员20比特币,这样形成了一个多数派。顺利的再次进入第二阶段。由于此时没有人竞争了,顺利的找3位官员签合同,3位官员看到议题与上次一次的合同是一致的,所以最终接受了,形成了多数派,proposer-1小姐跳槽到Client2老板的公司去了。

Paxos过程结束了,这样,一致性得到了保证,算法运行到最后所有的proposer都投“client2中标”所有的acceptor都接受这个议题,也就是说在最初的第二阶段,议题是先入为主的,谁先占了先机,后面的proposer在第一阶段就会学习到这个议题而修改自己本身的议题,因为这样没职业操守,才能让一致性得到保证,这就paxos算法的一个过程。

Paxos算法实际上是比较复杂的,上述故事只简单说明操作流程,很多细节(编号、议题等)没细说。
Paxos算法公认有两大缺点:①难以理解;②工程实现更难。但Paxos在分布式领域有着很重要地位,希望大家多了解。

附上Paxos原版论文 https://www.microsoft.com/en-us/research/publication/part-time-parliament
更易理解的版本《Paxos Made Simple》 https://www.microsoft.com/en-us/research/publication/paxos-made-simple

6.RAFT共识算法

在说RAFT前,讲一个小故事,Leslie Lamport本人1998年在ACM上正式发表PAXOS,然而由于算法难以理解而没得到重视,之后作者用更容易接受的方法重新发表了一篇论文《Paxos Mde Simple》,意为Paxos的简化版本。但论文发表了多年后的今天,依然难以寻找实现了它的实现开源库。反观RAFT,它设计之初就以更易理解为目标,这是2013年发表的算法,但网上已能找到十数个不同语言版本的开源库了。

先放一段RAFT动画演示视频:http://thesecretlivesofdata.com/raft/
视频详细讲解了算法共识过程,看完都能掌握算法基本思路,下面补充一些文字讲解。

在一个由Raft协议组织的群集中,每个节点有三种状态:
1. Leader(领袖)
2. Follower(群众)
3. Candidate(候选人)

系统初期,所有节点都是群众(Follower),节点通过领袖选举策略会自荐成候选人(Candidate),成功被选举的是领袖(Leader),而其余节点会变回群众。每个共识过程中,只能有一位领袖。

领袖选举策略Leader Election

领袖选举有两个阶段,第一阶段选举一位领袖,第二阶段该领袖维系自己的统治。若领袖挂了(宕机)则返回第一阶段重新开始。

第一阶段选领袖:刚开始无领袖(Leader)时,节点需要选举领袖。规则就是,每个节点会随机等待150ms - 300ms的选举超时(Election Timeout),先完成等候的节点会争取做领袖。正因为节点的选举超时各不相同,最先完成的节点会马上向其他节点自荐当领袖(Candidate)。而其他节点收到信息会回复同意,若能获得大多数的节点同意,领袖就选举完成了。若碰巧有多个节点有相同的超时,并都得到了相同数量的节点支持,那所有节点会重置超时时间,直到唯一的领袖产生。
在这个过程中,每个节点都有机会做候选人(Candidate)。

第二阶段领袖维系:选举完毕后,领袖需要定时发送心跳包给各其余节点,而其余节点会进入心跳包超时(Heartbeat Timeout)模式。此处,每个节点的心跳包超时也不相同,若节点在心跳包超时内没能收到领袖的心跳包,那它会认为领袖已经挂了并马上进入领袖自荐模式(即第一阶段)。被多数节点认同的会成为领袖,挂掉的领袖恢复后会变回群众。

两个阶段中,均有一个随机Timeout协助过程进行下去。这两个Timeout非常重要,因为节点的超时各不一样,最先完成超时等待的节点有成为领袖的机会,也是Raft算法的核心。

领袖节点(Leader)的作用

Leader节点负责收集来自Client(客户端)的数据并转交给其余Follower节点。当C向Leader节点提交数据后,Leader节点接收到的数据处于未提交状态(Uncommitted),接着Leader节点会并发向所有Follower节点分发复制数据并等待接受响应,直到群集中有超过半数节点表示已收到数据后,再向Client确认数据已接收(ACK),此时数据进入已提交状态(Commit),Leader节点再通知所有Follower节点数据状态已提交。这个过程叫做日志复制(Log Replication)

Raft协议保障数据一致性的方法

1. 数据到达Leader节点前。
Leader挂掉了。Leader会被重选,不影响过程。

2. 数据到达L节点,但未复制到F节点。
Leader挂掉了。此时数据处于未提交状态,Client长时间没收到ACK反馈会重新提交数据。Follower长时间没收到L的心跳包,会通过领袖选举策略选新Leader,新Leader重新接收Client数据。旧Leader恢复后变回Follower,保持和新Leader数据一致。

3. 数据到达Leader节点,成功复制到Follower所有节点,但还没向Leader接受响应。
Leader挂掉了。虽然数据在Follower节点处于为提交状态(Uncommitted)但保持一致,重新选出Leader后可完成数据提交,此时Client由于不知到底提交成功没有,可重试提交。针对这种情况Raft要求PRC请求实现幂等性,也就是要实现内部去重机制。

4. 数据到达Leader节点,成功复制到Follower部分节点,但还未向Leader响应接受。
Leader挂掉了。数据在Follower节点处于未提交状态(Uncommitted)且不一致,Raft协议要求投票只能投给最新数据的节点。所以拥有最新数据的节点会被选为Leader,再强制同步数据到Follower,数据不会丢失并最终一致。

5. 数据到达Leader节点,成功复制到Follower所有或多数节点,数据在Leader处于已提交状态,但在Follower处于未提交状态。
Leader节点。重新选出新Leader后的处理流程和阶段3一样。

6. 数据到达Leader节点,成功复制到Follower所有或多数节点,数据在所有节点都处于已提交状态,但还未响应Client。
Leader节点挂掉了。系统内部数据已经是一致的Client重复尝试基于幂等策略对一致性无影响。

7. 网络是分区导致的节点分区情况,出现双Leader。
在视频最后有演示节点分区情况。网络分区将原先的 Leader 节点和 Follower 节点分隔开,Follower 收不到 Leader 的心跳将发起选举产生新的 Leader。这时就产生了双 Leader,原先的 Leader 独自在一个区,向它提交数据不可能复制到多数节点所以永远提交不成功。向新的 Leader 提交数据可以提交成功,网络恢复后旧的 Leader 发现集群中有更新任期(Term)的新 Leader 则自动降级为 Follower 并从新 Leader 处同步数据达成集群数据一致。
Raft算法简洁高效,最重要的是便于工程实现。由此可知一个算法的可理解性有多重要。

最后附上资料:
Raft开源库链接:
https://raft.github.io/#implementations
Raft论文下载:
https://ramcloud.stanford.edu/raft.pdf

总结

至此,几种常见的共识算法介绍完毕。PoW,PoS,DPoS适合公有链,它们适合全球性的大量节点运作(挖矿);PBFT适合政府企业等联盟链,是系统只有少量节点系统并不需要具备币机制时理想选择;Paxos和Raft适合企业内部的私有链,在分布式系统中Paxos地位很重要,但Raft更适合工程实现表现也不俗。
没有那种算法是最好的,它们都有各自适用背景,各有优缺点。我们需要更好地认识各算法原理,不同场合选用不同算法。


你可能感兴趣的:(区块链共识算法讲解及发展)