最近阅读了Algorand的论文及一些相关资料,把自己对于Algorand一步步理解的思路记录下来,也希望可以帮到之后需要学习、使用Algorand到自己的链里的同学,如果对文章内容有任何不同见解的欢迎提出,一起讨论。
WHY - 为什么需要Algorand
-
PoW的不足
比特币所使用的共识算法PoW,为了解决分叉问题,需要一条链超过另一条链至少6个块时才能够达成共识,产生一个块大约需要十分钟,那么达成一笔交易需要等待大约一个小时,这个速度让人很难接受。
另一方面,PoW通过工作量进行验证,期间消耗大量的计算资源和电力,也是急需优化的点。
-
PBFT的不足
PBFT即实用性拜占庭容错算法,核心是通过
n>=3f+1这个公式容纳节点中可能出现的错误,那么为了完成所有节点间的互相通信,将涉及大量的节点间的网络传输,当全网节点数量较大时,大量的传输在网络内会出现阻塞,使PBFT的工作效率极差。因此PBFT基本无法适用于拥有大量节点的链。
SO - Algorand需要做到什么
-
PoW => PoS
PoW太慢,太浪费资源,于是Algorand就使用了PoS,根据节点所拥有的Token数给节点不同的优先级,这个优先级有什么用呢?之后会说到
-
PBFT => BA*
PBFT无法适用于含大量节点的链,那么就先从所有节点中选择少量节点,再在少量节点中使用类PBFT的共识算法来完成共识,其中涉及了一些具体环节的优化,新的共识算法在论文中称为BA*(超快速拜占庭协议)
即:大量节点 => 少量节点,少量节点使用PBFT(的小变形)做共识
HOW - Algorand如何做到这些的
大量节点 => 少量节点
从大量节点中选取少量节点的过程,在Algorand中称为“选举委员会”,仔细考虑,选举委员会的过程可能会面临以下风险:
敌人可能对(固定、公开的)委员会发起攻击
为了防止这类危险的发生,我们应该做到
- 随机抽取委员会
- 只有节点自己能够知道自己是不是委员会成员
- 委员会一旦做出区块提议等暴露身份的行为后立刻替换新的委员会成员
因此就引出了Algorand实现中非常重要的一部分加密抽签
加密抽签
加密抽签根据用户权重随机选择用户子集,用户通过私钥证明自己被抽中了。
主要涉及的技术是VRF(可验证随机函数)和PoS(用来对委员会中的节点进行优先级指定)。再详细一些说:
- 使用可验证随机函数(Verifiable Random Function,简称 VRF)实现随机数的产生
- Input: 种子(seed)
- Output: 一段随机哈希值(下一轮的种子输入)and π(π是此轮次内被抽签选中的用户证明)
- 第 r 轮的种子将会被 r-1 轮的 VRF 所决定,并且每一轮的种子以及π都会被记录到此轮次内的区块中
- 在进行加密抽签前,Algorand 将预先决定需要抽取的人数τ
少量节点使用PBFT做共识
这一部分的流程是
-
区块提议(一群由加密抽签出来的leaders来做)
-
BA*达成共识(另一群也由加密抽签出来的验证组来做)
注意这两个流程其实是由两群人完成的
区块提议
用户的账户余额将决定被选中的概率(拥有越多数量的 Token 将拥有更高的概率被选中),并且给予每一个被选中用户一个优先级别(priority)以及拥有此优先级的证明。
- 每个节点都通过以下 VRF 独立地验证自己是否是潜在的 leader
- leaders提议区块,并在全网内通过gossip协议传播
- 这些区块中最高优先级的区块将作为下一轮的待定区块等待验证组公证
小优化:减少不必要的块传输。由于推选出的委员会中的每个提议者都会通过gossip协议传输它们选举出来的块,导致产生大量的通信成本,所以会给每个用户指定一个优先级,当其他用户收到块时会丢弃非最高优先级用户发出的块。
达成共识
BA = GC + BBA**
-
GC - 分级共识协议
从多个可能的候选新区块中选择被大多数认可的一个作为最终候选的区块,再通过BBA*最终达成共识
- 第一步:所有验证节点将各自的区块哈希值发给其他所有验证节点
- 第二步:对于某个x值,当且仅当节点收到其他验证节点发来该 x 值的总次数(多次收到同一节点发送的x值,只算一次)超过总验证节点数的 ⅔ 时,这个节点会对其它节点发送值
-
BBA* - 改进的二元拜占庭协议
接受GC推选出的最终候选区块为新区块或以空白块为新区块。其具体过程是一个3步循环,循环中每一步都有⅓ 的概率达成共识