节点数据一致性
区块链网络上的交易从连接的链上节点开始逐步向外扩散,最终会有一个时刻,所有的节点都可以收到该交易。这也就意味着去中心化网络中,想要实时保证每个节点数据状态一致比较困难,网络越分散,数据扩散的时间也越久,一致性也越难以达成。
在交易扩散过程中,还可能存在专门搞破坏的作恶者,故意阻碍所有节点数据最终一致性的达成。
因此,就需要专门有一种机制去协调,使其在一定程度上约束节点的行为,来保证整个区块链网络保持状态的一致性,也就是共识算法。
共识算法
共识算法可以说是区块链技术的核心思想,是区块链运行的行为准则。
区块链的共识算法是一种在分布式网络中实现节点间一致性的机制,它确保所有参与节点对区块链的状态达成一致意见。共识算法对于区块链系统来说至关重要,因为它不仅保证了数据的一致性和安全性,还支持去中心化和抗审查的特性。
针对的是核心三大部分:交易,区块,状态项中的“状态”在所有参与交易节点上的一致性。
引子:分布式对等网络通信容错问题- 拜占庭将军问题
在分布式计算中,不同的计算机通过通讯交换信息达成共识而按照同一套协作策略行动。但有时候,系统中的成员计算机可能出错而发送错误的信息,用于传递信息的通讯网络也可能导致信息损坏,使得网络中不同的成员关于全体协作的策略得出不同结论,从而破坏系统一致性。拜占庭将军问题被认为是容错性问题中最难的问题类型之一。
简述: 一组拜占庭将军分别各率领一支军队共同围困一座城市。为了简化问题,将各支军队的行动策略限定为进攻或撤离两种。因为部分军队进攻部分军队撤离可能会造成灾难性后果,因此各位将军必须通过投票来达成一致策略,即所有军队一起进攻或所有军队一起撤离。因为各位将军分处城市不同方向,他们只能通过信使互相联系。在投票过程中每位将军都将自己投票给进攻还是撤退的信息通过信使分别通知其他所有将军,这样一来每位将军根据自己的投票和其他所有将军送来的信息就可以知道共同的投票结果而决定行动策略。
上述的故事映射到计算机系统里,将军便成了计算机,而信差就是通信系统。
最小化模型推论
假设最小化模型中只有将军A,将军B,将军C。
A 将军分别向 B、C 将军发出“进攻”的命令,B、C 将军分别会收到 A 将军的“进攻”命令。
此时如果 B 将军是叛徒,他可能会告诉 C 将军,他从 A 将军那里收到的是“撤退”命令。那么 C 将军就会发现他收到了自己从 A 将军那里直接得到的“进攻”命令,以及从B 将军那里间接得到的 A 将军的“撤退”命令,因此 C 将军无法判断 A 将军到底是想要“进攻”还是“撤退”。这种情况是无解的。另外一种情况,假设 A 将军是叛徒,他告诉 B 将军我要“进攻”,同时呢,又告诉 C 将军他要“撤退”。
而当 B、C 将军交换自己从 A 将军那里得到的命令时,彼此都发现从 A 将军那里得到的是一个“进攻”,一个“撤退”。局面陷入僵局,他们无法就 A 将军的命令达成一致。
通过最小化模型N=3分析,得出这个问题要有解,叛徒的数量不能大于等于所有将军数的1/3。
Q: 为何如此纠结的要在多个节点之间交换信息?
A:
日常工作生活中,对问题的表决往往是实时的,要么面对面,要么通过即时通讯软件。实时可以杜绝两面派的可能性,也就是没有叛徒,而且也没有必要互相询问自己收到的是什么命令,因为命令是实时广播,大家接收到的是相同信息,达成共识只需要一次决议就够了。而在这个故事中,将军们之间无法面对面交流,信使传递消息也只能两两将军间定向传播。
并没有真正理解只有一位将军发起投票的意思,此处想要表达的是,这一次的共识针对的只是 A 将军发出的命令,而不是在这一次投票以后就决定整体是“进攻”还是“撤退”。
多个将军需要对什么信息进行协商保证“一致性”? 此处的例子N=3情况下,就是将军B,将军C需要对A将军这一次发出的命令进行协商确认,最终使得将军A,将军B,将军C对其中任意一个将军发送的命令,都得到一致的“结论”。
映射到区块链上的节点交易(假设链网上一共有N个参与交易节点),排除发生交易节点发生交易X,在关联节点中进行交易扩散的时候,要在N-1个节点之间,协商确认,针对此次X的交易,是否是有效的(共识确认交易)。
共识的必要性
可以把将军看作是区块链节点,信使是网络。信使被截杀代表着节点间网络的不可达,而将军的叛变代表着节点想作恶。
为什么一定要保持所有节点的状态一致?
针对单个节点来说,状态是节点接收到交易后执行结果的累积。如果每个节点接收到的交易是不一致的,那么即便现在不同节点处理同一笔交易,其前置状态也会有所不同,从而在此基础上累积成不同的状态结果。随着更多的交易被提交到区块链网络,这种状态的不一致会进一步加深。
如是面向链网上的全节点的整个网络,如果一个区块链节点出现问题,我们可以随时切换到任意其他节点继续工作,但如果此时两个节点的状态有差别,无疑会产生不一样的结果。
这影响了区块链去中心化的特性,是不可接受的。因此,我们非常有必要引入共识算法来保证节点间状态的一致!
Q: 为什么区块链中要引入区块的概念呢,直接交易不是更好吗,反正状态是交易执行结果的累积?
A:
- 交易的扩散是有时间消耗的,最终有个时刻所有的节点都会收到该交易,但会是哪一个时刻呢?在去中心化架构中我们无从知道。
- 交易的扩散也会受制于网络环境的影响,完全可能出现后发出的交易被某个节点先收到,先发出的交易后被收到,那这样累积的状态也是可能不一致的。(交易在多个不同节点上的乱序)
为了避免这些问题的出现,区块链是这样规定的:
- 节点会把一段时间内接收到的所有交易打个包组装成区块。
- 区块的构建是有确切时间点的,这样就可以保证在这个时间点前的交易有序排列,而且区块是有编号的,即便因网络问题区块并未按照编号顺序进行扩散,其接收节点也可以等待前置区块接收到以后,再累积状态。
状态的一致性保证的基础是: 区块+多个交易+时间的签名。
区块链中对状态的共识实质就是对区块的共识,只要区块一致状态就一定一致。当然,区块的产生是随机性的,任意节点都可以产生区块,那以谁产生的为准呢?而这也就是共识算法需要解决的问题了。
区块链中的共识算法
常见的共识算法:
工作量证明(Proof of Work,PoW)
原理:节点(矿工)必须解决一个复杂的数学难题,才能创建新的区块并将其添加到区块链中。
优点:安全性高,攻击者需要大量的计算资源才能篡改区块链。
缺点:能耗高,因为需要大量的计算资源;可能导致中心化,因为矿工会趋向于拥有更多的计算资源。权益证明(Proof of Stake,PoS)
原理:根据用户持有的货币数量和持有时间来选择创建新区块的节点。
优点:能耗低,不需要大量的计算资源;更倾向于长期持有者参与网络维护。
缺点:可能导致“富者更富”的问题,因为持有更多货币的用户更容易获得奖励。委托权益证明(Delegated Proof of Stake,DPoS)
原理:持币者投票选出代表节点(见证人或超级节点),由这些节点负责验证交易和创建新区块。
优点:交易速度快,因为只有少数节点参与共识过程;能耗低。
缺点:可能导致权力集中,因为少数代表节点控制了网络的决策。拜占庭容错(Byzantine Fault Tolerance,BFT)
原理:即使在一些节点(拜占庭节点)作恶或出错的情况下,系统仍能保证正常运行。
优点:容错性强,可以在不可靠的环境下运行。
缺点:可能需要复杂的算法和协议来实现。权威证明(Proof of Authority,PoA)
原理:由可信的节点(通常是预先选定的)负责验证交易和创建新区块。
优点:交易速度快,因为验证过程不需要复杂的计算;能耗低。
缺点:去中心化程度较低,因为网络依赖于预选的权威节点。有用性证明(Proof of Useful Work,PoUW)
原理:根据节点对网络或社区做出的有用工作来分配奖励。
优点:鼓励节点为网络提供实际价值;可以结合其他共识机制使用。
缺点:定义和衡量“有用工作”可能具有主观性。
总的来说可以分为两类,一类是联盟链中用到的拜占庭容错算法,而另一类就是公链中用到的类似于 PoW、PoS 之类的算法,某种程度上可以统称为激励共识算法。
针对链上的共识,可以具体成以下几个问题:(状态的共识就是对区块交易的共识)
由谁来生产区块?因为区块链是去中心化网络,节点间权利与义务是对等的,因此在任意一个时刻,任何节点都可以生产区块。但是以谁的为准呢?这是在理解区块链共识时需要首先搞清楚的问题。
什么时刻可以达成共识?分布式共识其实也蕴含一个前提,那就是需要在有限的时间内达成各节点间区块一致。如果共识过程无限期,那么共识本身就不成立了。
有多少节点参与了共识? 通过对拜占庭将军问题的解析,我们知道共识的达成跟叛徒的数量息息相关,不同的共识对于叛徒的容忍程度是不一样的,我们常听到的少数服从多数,51% 攻击等等说的就是这一点。
拜占庭容错共识
《实用拜占庭容错》算法,简称 PBFT。
在 PBFT 中,节点被赋予主节点与从节点这两个角色,request 都从主节点发起,一次共识有且只有一个 request 存在。图中的 0 就是 request的发起者,所以 0 是主节点。
主节点选举:为了防止主节点作恶,节点角色是可以动态进行切换的,其他节点通过共识的结果可以推断出主节点是否是诚实节点,一旦主节点不是,则可以发起投票剥夺主节点的权利,这样就保证了系统的正常运行。
从图中我们可以看到一个 request 被提交到 0 节点,再通过 0 节点发送给其他参与方节点,随之展开共识后续的流程。
如果从区块链角度来看,0 就是区块的生产者,且针对当前区块的共识并不存在潜在的竞争区块,也就是说在拜占庭容错共识中,主节点具有绝对的话语权。从图中可以发现,PBFT 将共识信息的流转划分成 3 步,每一步都包含着多次的信息广播通信。通信虽然需要时间,但是只要能走完整个流程,就代表着共识可以达成,而且一旦达成就不再改变,可以说拜占庭容错共识是强一致共识协议。
比如图中的节点 3,可以看作是因为网络问题,它并未响应任何其他节点的请求,但因为其他节点都是诚实节点,少数服从多数,这次的共识依旧成立。
我们已经知道一次共识的达成,PBFT 需要进行多次的网络通信,而图中还仅表示的是只有 4 个节点的情形,如果将节点数进一步扩展,通信的要求就会指数级增加,因此它并不适用于有大量节点参与的场景。
所以,BFT 类的共识算法主要是链圈在推动,大多是用在联盟链中,因为联盟链主要参与对象是企业,有准入机制的存在,一条链的参与方不会很多也很少存在动态增删节点的情形,可以说联盟链与拜占庭容错共识是天生一对。
激励共识
所谓公链,就代表着这是一个公开的、任何人、任何机构都可以随时随地参与的区块链网络。随时意味着网络中的节点可以任意的上线或者下线,不受任何约束。
Q: 那在这样苛刻的分布式系统中,该如何保持节点间数据的一致呢?
A: 共识算法的选择取决于区块链项目的目标和需求。例如,比特币和以太坊目前主要使用PoW,而许多其他加密货币和区块链平台则采用PoS或其他算法。随着区块链技术的发展,新的共识算法不断被提出和实施,以解决现有算法的局限性并满足不同应用场景的需求。
因为公链网络是公开的,没有任何人可以干涉别的节点,所以任意一个节点的动作都可以看作是网络的缩影,那任意一个节点可以生产区块也就意味着网络中所有节点都可以。那同一时刻肯定存在多个候选区块,这给共识的达成造成了不小的困难。
比特币上的共识(POW)
整体上来看是利用区块有效性确认条件+如果选择满足条件链两个点来进行限制。
交易有效性条件的确认:
虽然每个节点都可以独立的将自己一段时间内搜集到的交易打包成区块,但是你创建的区块必须满足一定的条件,否则就算区块被全网广播了,也是一个错误的区块,其他节点会拒绝接受,也就是说无法达成共识。
而这个条件就是利用哈希算法计算区块哈希,使得区块哈希以 N 个 0 开头,N 的多少取决于当前网络区块增长的速度,是一个动态调整的值。这样一来,PoW 就限制了一段时间内网络中区块提案的个数。多个同时满足区块的选择:(最长链原则)
区块创建的时间有先后顺序的差别,但网络扩散是无序随机广播的,谁也保证不了谁会被先收到,极有可能一些节点收到了满足条件的区块 A,而另一些节点收到满足条件的区块 B,那到底以谁的为准呢?
比特币网络允许有多条区块链存在,但只认同节点能接收到的最长的那条区块链是全网络共识的链,其余短的区块链都是无效链。
节点当前所累积的最长链可能并不是最终的结果,在某个时刻它可能收到比节点本地存储更长的链,此时节点就应该切换区块链,否则有很大概率它所维系的区块链并不是全网络共识的结果。
通过这两条规定,比特币巧妙解决了如何在分布式系统中达成共识的问题。与拜占庭容错共识相比,在无节点角色区分的情况下降低了区块提案的个数,同时将一致性从强一致性放宽到最终一致性,虽然效率有所下降,但却达到了相同的效果。
对比特币网络的篡改,实质是对计算资源(算力)的争夺(POW),谁拥有更多的计算资源,谁的话语权就大,这也就是我们通常听到的 51% 攻击。
其他激励共识算法也遵循相同的道理,比如 PoS,权益证明算法,谁拥有更多的权益,就更有机会去争夺下一个区块的提案权。再比如 DPoS,委托权益证明算法,个人的力量是有限的,但是如果把很多人手中的权益集中起来,就可以以一种联合代表的形式参与到对区块的共识当中。与 PoW 相比,无非是减少了对计算资源的浪费,但本质并无差别。