2018年的公链将会毫不意外的统一转向pos共识方向,pow将会被扫入历史中。
在我认为,pos代表的就是不再需要从现实中将价值输入至区块链体系(pow消耗现实中的算力达成区块链的价值体系),而是根据已有的“历史”来不断衍生出新的价值来维护区块链的价值体系。也就是说,所谓权益证明(pos)就是能根据历史所产生的“权益”,使用一套算法能利用好历史中的“权益”来达成共识从而不断衍生出的新的价值,使得区块链本身就能成为一个闭环(而不像pow一样从外界,也就是算力来输入),不断运行下去。
在 区块链算法原理之:Casper 和Tendermint共识算法的比较 这篇文章中提到:
有很多不同的方式来实现权益证明的算法,但是权益证明设计的两个主要原理是 基于链的PoS和 基于拜占庭容错(BFT)的PoS。
Ada的共识算法 Ouroboros(乌洛波洛斯,也就是衔尾蛇)由于其严谨的学术性和在顶级密码学刊物上发表的论文而闻名,并且是 “Ouroboros是第一个被工业界采用的学术界提出来的可证明是安全和健壮的POS算法。(引用自maxdeath菊苣的回答)” (虽然我不确定和dfinity的那边相比谁才是第一)
本文即将根据 Ouroboros 的论文 “Ouroboros: A Provably Secure Proof-of-Stake Blockchain Protocol”及IOHK在youtube上的视频解说:Bernardo David, IOHK Research, Proof-of-Stake Protocol 对Ouroboros的运作流程进行自己浅薄的解释。
若有错误,欢迎大家指出。
本文首发于我自己的知乎专栏 金狗喵喵喵的区块链研习
如需转载,需取得同意并标明出处!
毫无疑问,Ouroboros是 “基于链的PoS”。
首先先要声明:论文中的Ouroboros是一个理论,说的是按照什么样的一个流程可以设计出一个健壮的pos算法并给出充分的证明,而Cardano中的Ouroboros是对论文的实现,在实现上和论文中的描述有所不同。
我并没有看过 Cardano 的实现,所以主要是根据论文并结合Cardano来讲Ouroboros是怎么设计的
maxdeath菊苣在很多回答中都指出了:下文引用
本质上,POW和POS都是一种随机选择下一个区块上传者的方式。
所以Ouroboros的根本目的就是为了根据权益多少,随机的选出一个记账者,并且随机选择的这个过程是不可预知的。
开头先简单描述一下Ouroboros运行的流程:
首先是一些术语及作用的解释:
在已有这些基础术语及作用的基础上,现在来简单介绍一下的工作流程:
如图所示,执行流程如下:(注:我并不保证这个流程是完全符合Cardano源码的实现(毕竟我没看过),但是是符合论文的描述的)
以上就是 Ouroboros 大致执行的流程。
根据上一章所描述的Ouroboros的模型及结合目的“产生一个不可预测的随机数”,我们来探讨一下其中的关键问题:如何随机的选出记账者
我们可以发现,在Ouroboros中,由于epoch的模型,这个问题被拆分成两个部分:
以每一个epoch为分析单位,那么只要每一个epoch的执行流程是成立的,那么不断重复epoch生成的链就是成立的。(就像该算法的命名Ouroboros,衔尾蛇一样)
那么我们就来分别解释着两个问题
产生这个随机种子的方法在密码学中应该属于交互式协议
首先需要介绍一些东西:
coin tossing 是为了在多方通信中,通过伪随机数和互相交互,最终得到一个统一的,被所有人认可的真随机数的交互式协议。如下图的左边所示:
左图是一个2方进行coin tossing 的过程:
当把这个两方的coin tossing 扩展为多方的时候,就是一个多方coin tossing的交互式随机数生成协议了。
但是呢,我们可以看到,这种交互至少需要3步(左图描述的过程),我们可以发现,要达成这样的交互式协议是不能比3步更少的(可以更多,比如一般google到的coin tossing会是4步,例如B并没有直接给s',而是给了一个Com(s',n'),然后需要第4步B发送给A一个Open)。如果少于了3步,就会出现右图的情况,协议出现了Abort!
在右图的执行流程中:
虽然最终这样并不是作恶成为A可以控制最终字符串的产生,但是A这样的行为却可能导致最终的协议无法执行下去,进而被中断(Abort)。而且即便是多步也会有Abort的行为发生使得协议无法执行下去,而太多的通信则会造成整个网络的拥堵(特别是多方的情况下,有k次通信就是O(n^k)的通信复杂度)。
所以如果能在尽可能少的通信下(如三步)又希望保证整个协议不会因为Abort而无法运作下去,这样的目的就被称为guarantee output delivery(G.O.D)
那么为了保证G.O.D这个目标成立,就需要引入一些新的机制,如下文所述。
verifiable secret sharing (VSS) :可验证的密钥分享。在Cardano中使用的是PVSS,见链接 乌洛波罗斯协议论文与实现的区别。
这里先介绍VSS:
把一个秘密S 通过 share(s) 可以拆分成 m 份,分发给m个人,每个人拿到其中的一片并不知道整个S 是什么 因为我并不是学密码学的,所以就不班门弄斧了,下文只能简单介绍一下VSS能起到的作用。 在视频里面举的例子如下: 以上只是从原理上简单描述VSS能够做到的事情。我们可以发现,VSS的特点就在于,每个人拿到的那个秘密是不能可能知道原来的秘密是什么的,必须得到他人的“帮助”才能恢复出原来的秘密是什么。 而VSS得特点在于,每个人并不是要拿到所有的密码,而是拿到一定多的秘密(剩余的秘密可以为空,可以为假等等)就可以重新恢复出原来的那个秘密S。 这个特性可以达成一个功能:例如A向大家宣告我有一个东西,然后A就可以用VSS把这个东西分发给所有人,但是所有人又不知道这个东西是什么。此时,即使A挂了或者跑路了,大家也可以互相通信恢复出A一开始的东西。 那这个VSS有什么用途呢?先回到coin tossing 的最后一个问题,协议要是中断了怎么办? 显然,VSS就是用来解决coin tossing 协议中断执行的问题 coin tossing 的问题在于要是 A 没有发送open给B,那么协议就无法执行下去。那么联系起VSS的性质,我们就可以很自然的得出:要是open会因为意外原因导致协议中断,那么我们把open分发给所有人不久可以了么?因为即使A跑路了,大家也可以互相通信恢复出A一开始给出的承诺是什么东西,使得coin tossing的协议能够正常执行下去,得到大家都认可的真随机字串。 所以把 VSS 和 coin tossing 结合起来的时候,就可以达成 G.O.D 的目标,称为 “G.O.D coin tossing” 所以在论文中提出的方案如下: 如图所示: 注:这里的Deal()对应上一章节中的Share() 并对share的结果使用对应接受者的公钥进行加密 Ouroboros采用的方法如下: (注:我之前的文章有点错误,现在重新更正如下:) 那么G.O.D coin tossing 的执行流程如下: 首先先注意,在epoch genesis block生成的时候(也就是ρ产生的时候),实际上每一个slot的slotleader已经被选出来了(划重点),也就是说在epoch开始的时候就已经知道整个epoch中分别是谁出块了,只是选出的方式是按权益概率决定的(下一章节会详细解释)。另一方面genesisblock中包含的是S=>{(vk1,s1),(vk2,s2),...,(vkn,sn)}也就是不止权益,还有stakeholder候选人的公钥 至此,如何在一个epoch中生成一个不可控制的随机数ρ就解释完成了。我们可以看出通过G.O.D coin tossing 是可以做到一个不会被Abort的交互式随机数生成过程。 下面是论文原文中的算法,注意用红框框出来的地方: 请注意在前两个阶段指的是所有的 stakeholders(i∈{0...n}),是所有的stakeholder都参与,然后Recovery阶段只有被选中的stakeholders才参与。这块地方我之前的理解有误,认为是所有阶段都是只有被选中的stakeholders才参与(slotleaders)。这里特地更正。 (但是还是有点奇怪,更细节的部分我之后会看了源码后再更正的。。。) 根据Cardano结算层的文档来看,在实现上是和论文有区别的。 具有权益的确是就是stakeholders,但是注意参与过程的人并不是所有的stakeholders,而是只有2%以上的人才能参与,而这些2%以上的人就叫做“electors”。 而后续的那些操作都是基于electors的。(并不是所有的stakeHolders了) 在论文中这部分没有详细描述,只是直接定义出了这样一个函数。那么在Cardano中的实现使用的是“follow-the-satoshi”算法,见链接:术语表 follow-the-satoshi算法最原始是来自于论文:Proof of Activity: Extending Bitcoin’s Proof of Work via Proof of Stake 论文大致是说,使用pow产生一堆stakeholders,然后在这堆stakeholders中使用follow-the-satoshi找出出块者,当然Ouroboros对其的改进就是把pow做成了G.O.D coin tossing follow-the-satoshi的算法其实很简单,在github上有人对其作了一个模拟实现:Realiserad/fts-tree 这里引用README.md中的话: 并且引用之中的图做个简单的解释: 大意就是说,把所有的stakeholder组成一个merkletree的形式,然后根据一个随机种子开始,通过伪随机数做出选择,最终会按照大家权益的比例选出对应的stakeholder。 注意这里强调的是伪随机数,是为了当有一个相同的种子后,每个不同的个体分别执行这个伪随机后都能得到相同的序列。 比如图中的例子,假设我已使用一个种子,每次执行伪随机后可以获得序列{65, 20,15} 这颗树的组成是把stakeholders排列好,按merkletree组织好,附加上每一条边代表两个叶子权益之和。那么我们根据序列从树根开始查找开始: 因为比如参与的所有的stakeholder是 A0,A1,...,An,分别对应的权益是s1,s2,...,sn,那么其中Ai, i∈{0,n}的权益比例为: 又因为是使用一个真随机数作为种子,执行伪随机进行漫步,那么只要所有人拿到的真随机数的种子是一致的时候,那么所有人得到的随机出的stakeholder的结果就是一致的 所以就是可以解释G.O.D coin tossing 中的问题,只要但genesis block 能够生成后得到ρ和权益集合S,那么就相当于直接可以计算出当前这个epoch中所有的slotleaders们都是谁了。 本文根据论文和视频描述了Ouroboros整体的执行流程和中间的一些细节。首先先对想出这种思路并给出证明的科学家们致意崇高的敬意,Ouroboros将会开启pos的新篇章。Ouroboros论文最重要的不只是给出这样一种pos的思路,更多的是提出对这个思路的一个论证证明的方式。这种论证的方式可以延续到其他共识算法的证明中。 事实上诚实的说,我并不保证我完全看懂了论文,因为论文中写的实际上很复杂···另一方面,本文也没有解释论文中后半段关于“权益委托”的方式,之后有空慢慢补。 下一篇和pos相关的文章将会描述Dfinity的实现,Dfinity是“基于拜占庭容错(BFT)的PoS”,并在更后面的文章中对这两者做比较。 之后我也会尝试使用c++去针对我司区块链系统实现Ouroboros的共识算法。 本文首发于我自己的知乎专栏 金狗喵喵喵的区块链研习
但是只要收集到另外t(tS share(S) -> S1, S2, ... // 比如我原本有一个秘密S,通过 share(S) 把密码拆成了4份
share(S) = Sa, Sb, Sc, Sd
Sa Sb Sc Sd // 把这4份秘密分别给4个人
A B C D
// 比如按照如下的方式赋值分解出的各个秘密,xor是异或,
// 可以看出A,B,C,D分别拿到的秘密 Sa, Sb, Sc, Sd 都是不可能知道原来的S是什么的
Sa = S xor Ra R is random str
Sb = S xor Rb
Sc = S xor Rc
Sd = Ra xor Rb xor Rc
// 但是只要其中有人能收集到别人的秘密,比如A自己向B,C,D收集到了另外3个秘密
// 那么 A 就可以把这些秘密全部执行 xor, 由于xor 的性质,就能恢复出原本的 S
reconstract(Sa, Sb, Sc, Sd) = Sa xor Sb xor Sc xor Sd=S
G.O.D coin tossing
Slot leaders are elected from the group of all stakeholders. Please note that not all stakeholders participate in this election, but only ones who have enough stake (for example, 2% of the total stake). This group of stakeholders are known as “electors”.
2. 根据随机种子ρ在当前epoch中以权益的比例为概率,随机选出slotleader
The idea is simple: The edges the Merkle tree are labelled with the amount of coins in the left and right subtree respectively. Given a psuedo-random number generator, one can randomly select a stakeholder from the tree, weighted by the amount of coins they own, by traversing the tree down to a leaf node, containing one of the stakeholders. Each stakeholder controls a number of coins and a private key used to sign blocks.
那么我是根据随机数进行随机漫步,那么显然最后选中某个stakeholder的概率就是其权益占总体的比例。四、总结