Files
CategoryResourceRepost/极客时间专栏/左耳听风/区块链/66 | 区块链技术细节:去中心化的共识机制.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

244 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<audio id="audio" title="66 | 区块链技术细节:去中心化的共识机制" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/87/a2/870fce7a3f16358a8c31dcbb0eadb8a2.mp3"></audio>
其实,去中心化的共识机制也是要解决拜占庭将军问题([The Byzantine Generals Problem](https://web.archive.org/web/20170205142845/http://lamport.azurewebsites.net/pubs/byz.pdf)它是莱斯利·兰伯特Leslie Lamport于1982年提出来的用来解释一致性问题的一个虚构模型。同时它也是分布式领域中最复杂、最严格的容错模型。
# 分布式一致性算法
拜占庭的将军们没有一个中心化的领导机构,所以,如果他们需要攻击某个城市,所有将军需要对任何将军可能提出的攻击时间达成共识。也就是说,只有所有的将军都达成了共识,在同一个攻击时间攻击,就有非常大的胜率。但是,问题来了。这时,可能会有多个将军同时发出不同的攻击计划,而且这些将军中还有叛徒。那么,将军们怎样达成共识呢?
莱斯利·兰伯特证明,当叛变者不超过 1/3时存在有效的算法。不论叛变者如何折腾忠诚的将军们总能达成一致的结果。如果叛变者过多则无法保证一定能达到一致性。
拜占庭问题之所以难解,在于任何时候系统中都可能存在多个提案(因为提案成本很低),并且要完成最终的一致性确认过程十分困难,容易受干扰。但一旦确认,即为最终确认。
比特币的区块链网络在设计时使用的 PoWProof of Work 算法思路。一个是限制一段时间内整个网络中出现提案的个数(增加提案成本),另外一个是放宽对最终一致性确认的需求,约定好大家都确认并沿着已知最长的链进行拓宽。
也就是说,如果比特币系统在某一个时刻同时出现了两个都合法的区块,那么两个都承认。于是,区块链上会出现两个合法的分支(术语叫&quot;分叉&quot;)。此时矿工可以选择任何一个分支继续,在某个分支的长度超过了另一个分支时,短的那个分支马上作废。
如果你看过我之前写的《分布式系统架构的本质》系列文章那么一定知道Paxos协议这也是一种分布式一致性的共识算法。但为什么不用Paxos和Raft来做区块链的一致性算法的协议呢这两个算法对资源的消耗比PoW要小得多呢。
如果你熟悉这几个算法那么你就知道PoW和Paxos/Raft的算法在本质上有下面这些不同。
<li>
对于Paxos/Raft其需要Leader选举而对于比特币或者以太坊这样的无中心化的方式是没有leader的。
</li>
<li>
对于Paxos/Raft加入其网络集群的结点前提假设都是受信的。然而对于比特币/以太坊来说,其前提假设都是不受信的,它们只相信,超过一半的结点所同意的东西。
</li>
<li>
对于Paxos/Raft需要事先对整个集群中的结点数有定义而无中心化的比特币和以太坊中的结点是想来就来想走就走来去自由。如果Paxos/Raft在这样的环境下其会处于一个非常尴尬的境地——要能随时进行伸缩。而且Paxos/Raft并不适合在一个非常大的网络中玩比如上百万的结点
</li>
但是它们有一些是相同的。
<li>
它们都是一致性的算法。
</li>
<li>
对系统的修改总是需要一个人来干区块链用PoW消耗资源让提案变得困难Paxos/Raft用领导选举
</li>
<li>
系统中暂时的不一致是可以被修正的区块链会考虑最长链牺牲了强一致性保证了可用性Paxos/Raft如果没有超过半数的结点在线会停止工作牺牲了可用性保证了强一性
</li>
总之区块链所面对的无中心化的P2P网络要比Paxos/Raft所面对的相对中心式分布式网络要复杂多得多。所以不太可能使用Paxos/Raft协议来替代PoW协议。除非你想干一个相对中心化的区块链然而这就成了区块链的一个悖论了。
无论你是搞区块链还是搞分布式你都需要知道拜占庭容错系统研究中的三个重要理论CAP、FLP 和 DLS。
<li>
CAP理论 - “在网络发生阻断partition你只能选择数据的一致性consistency或可用性availability无法两者兼得”。论点比较直观如果网络因阻断而分隔为二在其中一边我送出一笔交易“将我的十元给A”在另一半我送出另一笔交易“将我的十元给B ”。此时系统要么是a无可用性即这两笔交易至少会有一笔交易不会被接受要么就是b无一致性一半看到的是A多了十元而另一半则看到B多了十元。要注意的是CAP理论和扩展性scalability是无关的在分片sharded或非分片的系统皆适用。
</li>
<li>
[FLP impossibility](http://the-paper-trail.org/blog/a-brief-tour-of-flp-impossibility/)-在异步环境中,如果节点间的网络延迟没有上限,只要有一个恶意节点存在,就没有算法能在有限的时间内达成共识。但值得注意的是, [“Las Vegas” algorithms](https://en.wikipedia.org/wiki/Las_Vegas_algorithm)这个算法又叫撞大运算法其保证结果正确只是在运算时所用资源上进行赌博。一个简单的例子是随机快速排序它的pivot是随机选的但排序结果永远一致在每一轮皆有一定机率达成共识随着时间增加机率会越趋近于1。而这也是许多成功的共识演算法会采用的解决办法。
</li>
<li>
容错的上限-由[DLS论文](http://groups.csail.mit.edu/tds/papers/Lynch/jacm88.pdf)我们可以得到以下结论。
</li>
<li>
在部分同步partially synchronous的网络环境中即网络延迟有一定的上限但我们无法事先知道上限是多少协议可以容忍最多1/3的拜占庭故障Byzantine fault
</li>
<li>
在异步asynchronous网络环境中具确定性质的协议无法容忍任何错误但这篇论文并没有提及 [randomized algorithms](http://link.springer.com/chapter/10.1007%2F978-3-540-77444-0_7) 在这种情况可以容忍最多1/3的拜占庭故障。
</li>
<li>
在同步synchronous网络环境中网络延迟有上限且上限是已知的协议可以容忍100%的拜占庭故障。但当超过1/2的节点为恶意节点时会有一些限制条件。要注意的是我们考虑的是“具认证特性的拜占庭模型authenticated Byzantine而不是“一般的拜占庭模型”。具认证特性指的是将如今已经过大量研究且成本低廉的公私钥加密机制应用在我们的算法中。
</li>
# 工作量证明
比特币的挖矿算法并不是比特币开创的,其原型叫 [Hashcash](https://en.wikipedia.org/wiki/Hashcash)。这个想法最初是由哈佛大学的女计算机科学家辛西娅·德沃克(Cynthia Dwork)、加州伯克立大学的Moni Naor和Eli Ponyatovski于1992年的&quot;[Pricing via Processing or Combatting Junk Mail](http://www.wisdom.weizmann.ac.il/~naor/PAPERS/pvp_abs.html)&quot;论文中提出来的。是的,一开始这个算法是用来限制垃圾邮件的。
简单说来Hashcash一开始要求邮件发送方对邮件头其中包括时间和收件人地址计算一个160bit的SHA-1哈希值。其前面需要有5个零也就是20bit的0。接收端会检查这个事。
为什么要设计成这个样子因为如果我们发垃圾邮件这点算力对于发送方来说没有什么。但对于需要大量发送垃圾邮件的人来说这就是一个很大的成本了。就算是那些控制着用户的僵尸网络的黑客来说发送垃圾邮件时导致CPU使用率过高会马上引起电脑所有者的警觉而且还很容易定位相应的恶意程序。
对于一些受信的邮件服务器我们可以把其放进白名单中这样就不需要它们接受Hashcash挑战它们也不用为之付出成本。
于是这种玩法叫做Proof-of-Work简称为PoW工作量证明。我们用这种消耗对手能源的手段来阻止一些恶意的攻击或是像垃圾邮件这样的对服务的滥用。
PoW有两种协议。
- 一种叫Challenge-Response协议用于Client-Server。如图所示如果Client需要使用服务那么需要被Challenge去花费一些资源。如果证明自己的资源已被花费了则通过认证授权使用。
<img src="https://static001.geekbang.org/resource/image/51/94/51b22e1076f3db3d4e8063f382f09894.png" alt="" /><br />
(图片来源:[Wikipedia](https://en.wikipedia.org/wiki/Proof-of-work_system)
- 另一种叫Solution-Verification协议用于验证使用。Hashcash就是这种协议。下图可以帮助你更形象地理解。
<img src="https://static001.geekbang.org/resource/image/32/e8/32dbf07ce5ef0333333a1cc563b2b2e8.png" alt="" /><br />
(图片来源:[Wikipedia](https://en.wikipedia.org/wiki/Proof-of-work_system)
通过前面的描述可以得知我们需要为用户记录的交易是不能被修改的所以使用hash方法为每个账本做了“签名”还把其不断地打包再hash形成merkle root然后再形成一个串链。于是修改一个地方就会导致所有地方的“签名hash值”都需要跟着一起修改于是形成了复杂度。
然而这样的复杂度对于计算机来说并不高找上一台或是几台主流点的电脑分分钟就破解掉了。因为hash运维这个事对于计算机来说是一件非常高效根本不费事的事。
于是乎我们通过挖矿——PoW这样的协议来大幅度地提高修改成本使得有恶意的人要改一个地方需要花很大很大的成本来修改。这几乎是一件不可能的事情。
因为比特币是去中心化的P2P系统任何人都可以方便地获得所有的数据所以为了防止有恶意的人修改数据使用PoW的&quot;挖矿&quot;机制,可以大幅度提高想要通过修改和攻击这个系统的人的成本。
当然PoW的初衷是通过消耗资源的方式来阻止一些恶意攻击。然而在区块链的去中心化的世界里PoW还有另一个功能那就是让这些不受控制的分布式P2P网络里的结点统一思想。也就是说我们常说的分布式一致性。这对分布式系统中的交易系统来说是一件非常重要的事。
总结一下,工作量证明就是为了下面几件事。
<li>
**提高对数据篡改的成本**。让你修改数据需要付出大量的算力,而区块链的数据相互依赖,导致&quot;一处改处处改&quot;,因此你要完全修改就需要付出大量的算力。
</li>
<li>
**提高网络中有不同声音的成本**。试想,如果一个网络有不同的人给出来了不同的账本,而且都合法,你会信谁的?所以,挖矿可以解决这个事。让你要做一个伪造账本的成本极其地大,而校验账本的成本很小。
</li>
<li>
**解决分歧**。当有不同声音的时候,即区块链出现分叉时,所有的矿工只能选择其中一个分支(因为没人有算力可以同时发出两个不同的声音)。于是,大多数人选择的那个分支就会成为事实,少数人选的那头就被遗忘了。**这让整个去中心化系统的一致性,不再以人数多认可的数据为准,而是以算力多的人认可的数据为准**。
</li>
只要网络越来越大,能掌握半数以上算力的人基本上是不可能的。是这样的吗?我表示怀疑。
PoW解决这种无中心化网络的作弊、分歧这样的问题是目前最有效的其他不用PoW这样的玩法的都存在很大的安全问题。但是现在的PoW也有几个非常严重的问题。
<li>
**越来越中心化地记账**。本来是要大众一起参与去中心化的事现在因为算力的问题因为GPU的出现导致一般人几乎无法参与其中了。
</li>
<li>
**越来越跑不动**。比特币今天的链越来越长,导致要验证数据是否正确的成本越来越高,一般人的电脑基本都快要跑不起来了。
</li>
所以,比特币社区也开始分裂成好几个衍生品,用不同的手段在解决这个问题。但是,目前为止,我没有看到什么比较好的方式。因为这世界上不存在完美的解决方案,你要一头,另一头就没了。
# 股权证明协议
PoW这个机制要找到符合条件的Hash值在目前来看其耗费的电力和时间成本是越来越大了。所以为了每个Block更快的生成出现了PoS Proof of Stake协议中文翻译为股权证明协议。
在PoS机制下矿工不再叫矿工而是叫Validator校验者。假设现在有一个区域需要被生成而现在有4个Validator每一个Validator需要以&quot;交押金&quot;的方式来取得记账权。假如A交的押金占了38%B占25%C点21%D占16%。那么他们按照股权的比权来获得记账权。比如A有38%的概率可以获得记账权不是由系统随机分配还是要算hash值只不过是财富越多的人挖矿的难度越小。而如果你发起恶意攻击的话你的钱就会被系统没收充公。而Validator记账后没有奖金只有手续费。
也就是说在PoS机制下记账权不再像PoW那样由谁的算力大谁就越有机会来记账而是由谁的财富多谁就越有可能来记账。于是记账权按大家财富的比例来分配。
**PoW好像是&quot;多劳多得&quot;的社会而PoS更像是&quot;资本主义&quot;社会,钱越多的人越有话语权。这其实也没有什么不对的。从博弈论的角度上来说,钱越多的人越有动力维护社会的稳定,因为如果社会不稳定了,他是损失最为惨重的人。**
**这里有一个逻辑问题:如果钱越多的人越有动力维护社会稳定,那么,是不是中心化的机构也越有动力维护整个系统的健康度?如果是这样的话,我们为什么要去中心化呢?**更多的逻辑问题会在本文最后提出。)
在以太坊下是根据拥有以太币的总量来决定成为Validator的机率。
PoS宣称至少有如下的几个好处。
<li>
第一个好处很明显。不需要那么费劲的挖矿了。那样浪费电力不环保地挖矿的确有点太糟糕了。PoS很明显地解决了这个问题。
</li>
<li>
在P2P这种无中心化的网络下如果你要控制整个网络就需要超过半数以上的能力。在PoW下你需要51%的算力。在今天这会是一个非常大的成本。但是我们看一下下面的全球比特币的算力图我们发现只要前四家公司联合起来作弊就可以完成对比特币的攻击据说中国有60%左右的算力看来只要中国政府愿意要拿下比特币也不是什么难事呵呵。而在PoS下你需要有51%的财富你才可以发起攻击这相对于算力而言需要更多的成本。设想一下你得拥有51%的比特币你才能黑了比特币然而如果你有51%的财富,你为什么要黑了这个系统,自己把自己干死呢?这就是博弈论。
</li>
<img src="https://static001.geekbang.org/resource/image/8a/c2/8afccadcf03aa96e2371726b4dc5f3c2.png" alt="" /><br />
(图片来自:[http://qukuai.com/pools](http://qukuai.com/pools)
# PoS机制潜在的问题
世界上没有免费的午餐也没有绝对完美的事所以PoS也有其潜在的问题。最明显的一个问题就是当不需要太多算力的时候如果账本出现分叉的情况也就是系统出现两个冲突且合法的区块的时候在比特币这种算力密集的PoW机制下所有的矿工必需赌其中一个分支往下走。
因为算力的问题所以基本上来说不太可能同时在两个分支上发展。而其中一个分支如果长于另一个分支较短的那个分支就会被孤立出去其上的账本就都不作数了而矿工的奖励也没有了。这是PoW机制的好处。
而在PoS这种不需要算力的机制下就可以让记账人们在两个分支上同时进行以争取实现利益的最大化无论哪个分支最终胜出我都可以有利。这样一来攻击者就可以利用这种情况来发起Nothin-At-Stake攻击。
也就是说如果绝大多数人都在发展两个分支假设有99%的人发展A分支99%的人也同时发展B分支而有1%股份的人在分支A中写一笔交易然后在B分支没有这笔交易当其在A分支上达成合约后比如收到商品加入B分支然后B分支胜出导致其没有交易。
另外两个分支发展还可以发起双重支付。就是说Bob把他的10元钱借给了Alice也给了Marry在不同的分支上。这就是所谓的&quot;双重支付&quot;问题Double Spend Problem
在CAP理论中如果出现网络分区的情况Partition你要么选择数据的一致性Consistency,那么你就得让整个系统不可用Availability要么选择系统的可用性Availability那么你就得牺牲数据的一致性Consistency。所以在无中心化下我们通过分叉来牺牲数据的一致性于是在一个分叉上Bob把10元给了Alice另一个分叉上Bob把10元给了Marry。
甚至可以发起&quot;贿赂攻击Bribe Attack&quot;,攻击者可以在一个分支上声称购买了某个商品。然后,收到货后,以提高手续费的方式只养另一个没有购买这个商品交易的分支,然后把没有这个交易的链养得足够长,长到系统最终选择了没有交易的这条链。
在PoW机制下这种&quot;分叉攻击&quot;的玩法基本上来说不可能但在PoS的玩法下这种攻击就很有可能。在以太坊下如果发现有人玩同时养分叉的玩法就会予以惩罚。然而如果这个攻击者有多个账户呢我用多个马甲来玩不同的分叉……
另外PoS这种通过财富的占比来决定记账概率的玩法可以让结点进行预计算也就是可以计算下一个的hash值这样一来相当于我可以偷偷养分叉。
看来PoS的问题也很多所以有人又提出来了一个进化版叫DPoSDelegated Proof of Stake委托股权证明。它是 PoS 的进化方案。
以太坊的官方Wiki上有一份[Proof-of-Stake的FAQ](https://github.com/ethereum/wiki/blob/master/%5B%E4%B8%AD%E6%96%87%5D-%E6%AC%8A%E7%9B%8A%E8%AD%89%E6%98%8E%E6%A9%9F%E5%88%B6FAQ.md) 你可以前往一读。
# DPoS机制
在常规PoW和PoS中一大影响效率之处在于任何一个新加入的区块都需要被整个网络所有节点做确认。DPoS优化方案在于通过不同的策略不定时地选中一小群节点这一小群节点做新区块的创建、验证、签名和相互监督。这样就大幅度减少了区块创建和确认所需要消耗的时间和算力成本。
这就像选举人团代议制度和美国选总统一样。DPoS下每个token都是选票大家票选20个选举人团+1个随机选举人=21个选举人代表网络。然后每隔一段时间在这21个人中挑选一个出来维护账本并获得收益。
近日推崇DPoS的EOS开始了其21个超级节点的选举。作为超级节点他们将获得 EOS 每年增发 5% 的收益中的大部分,大约每一个节点每年可以获得 238 万个 EOS的收益按照当前价格EOS/RMB ¥34一个节点每年可以分到 1 亿元人民币的奖励。
注明一下EOS是以准备颠覆以及坊以及整个区块链生态的姿态打着提高交易吞吐量到百万级TPS的技术口号的进入这个世界的本文成稿时EOS还没有正式发布相关细节你可以看看 [EOS白皮书的中文版翻译](https://www.jianshu.com/p/f65bf7691482) 。)
比较有趣的是在这次超级节点的竞选上主要竞选节点来自中国、美国和韩国。这三方的优势是韩国人拥有最大的EOS交易量而中国人拥有更多的EOS之外的资本而美国人则有规则制定权。看起来就是美国有政治权力韩国有经济权力中国这边有外围经济权。看上去是比较完美的制衡就像三国演义一样。
为了赢得选举中国竞选人开始进行了我们熟悉的套路——贿选。所谓贿选就是指将上文提到的当选超级节点后每年应分得的「巨额工资」返还给每一位投自己票的人。通过这样的贿选就可以破坏上述看起来比较制衡的政治局面。这样搞下去很有可能那21超级个节点就会成为一家公司所控制。
所以很快创始人BMDan Larimer就现身表示不支持节点对投票人实行分红的做法。然后Thomas Cox 也在社区内发帖《为什么付费投票是坏的》来谴责贿选,并在开始陆续发布 EOS.IO 的 0.1 版本「宪法」的第一条款《不说谎》…… (相关的报道可参看《[EOS超级节点投票「千亿」利润下的币圈国家战争](https://mp.weixin.qq.com/s/qtbyvpcEmN06V_p-QtCJ7A)》。)
顺便八卦一下EOS创建人BM在2014年的时候创建比特股时打出超级比特币的概念然后因为Bug大多体验非常地差后面他和公司不合离开了比特股。2016年他创建了社交平台Steemit想颠覆传统媒体结果也失败了并于2017年创建EOS瞄准以太坊想做区块链接基础设施包括并行运算、数据库、账户系统等等。老实说我觉得这个对他来说更难。
在我看来,有两点让这区块链这个技术开始有些变味了。
<li>
DPoS已经开始把区块链的去中心化的初衷开始向中心化的地方演进了。
</li>
<li>
政治在未来区块链的世界里是一个必不可少的技能这意味着不可控的复杂性。我感觉这些技术宅是一定Hold不住的。
</li>
# 小结
对我来说目前为止PoW还是一个比较稳健的共识方式PoS/DPoS还需要更多的实践和改进当然也许混合PoW和PoS/DPoS也不错呢。&quot;去中心化&quot;&quot;高吞吐&quot;这两个事,我觉得是很难协调的。
总结一下。
<li>
PoW就是蛮荒社会。谁的拳头大谁说话。是真正意义上的无政府的去中心化的社会。
</li>
<li>
PoS就是资本主义社会。谁的钱多谁说话还是无政府的社会但是资本家控制的。
</li>
<li>
DPoS就是政治主义社会。谁的选票多谁说话我也不知道怎么个选举竞选活动吗有电视辩论吗还是投票玩玩但是感觉又回到了中心化架构中的Leader选举。
</li>
无论怎么样,人类社会进化的影子在去中心化的社会中又开始出现了。那么,另一个逻辑问题来了,如果这种&quot;去中心化的社会&quot;本质上是在重复一遍&quot;中心化&quot;的演进过程,那么,还有什么意义?
上面的这个逻辑问题我们留到最后,这里还是看一下技术方面的事儿。
我们都知道分布式系统的CAP原则在一致性、可用性和分区容忍性上只能三选两。在区块链的P2P网络下也是很类似的在去中心化、安全和高性能中我们也只能选两个。
<img src="https://static001.geekbang.org/resource/image/62/58/62b1abfbc89d368f72a80d4eda935b58.png" alt="" />
<li>
如果我们想要一个既安全性能也很高的系统那么得放弃去中心化的架构如DPoS这样的中心化系统直接放弃区块链走传统的中心化架构。
</li>
<li>
如果我们想要一个去中心化和安全的系统,主要去挖矿,那么放弃高性能。这就是目前的比特币架构。
</li>
<li>
如果我们想要一个去中心化和高性能的系统,那么就得放弃安全。没有安全的系统,基本上来说是不会有人用的。
</li>
文末给出了《区块链技术》系列文章的目录,希望你能在这个列表里找到自己感兴趣的内容。
- [区块链的革命性及技术概要](https://time.geekbang.org/column/article/5197)
- [区块链技术细节:哈希算法](https://time.geekbang.org/column/article/5363)
- [区块链技术细节:加密和挖矿](https://time.geekbang.org/column/article/5438)
- [去中心化的共识机制](https://time.geekbang.org/column/article/5612)
- [智能合约](https://time.geekbang.org/column/article/5623)
- [传统金融和虚拟货币](https://time.geekbang.org/column/article/5636)