block chain/Ethereum/docs/pos.md
### 什么是Proof of Stake(权益证明机制)
权益证明机制是公有链共识演算法的一类,乙太坊接下来的Casper 演算法是其中之一。它和比特币、目前的以太坊及许多其他区块链背后的Proof of Work有着相似的作用,但在安全性及能源使用效率上有着显着的优点。
总的来说,权益证明机制演算法大致如下。区块链记录着一组**validator**(验证者),所有持有该区块链数位货币的使用者(即以太坊的以太币)都可藉由一个特殊交易将他们的数位货币锁进一个存库来成为验证者。创造一个新的区块的过程则藉由一个验证者参与的共识演算法来进行。
目前有许多种的共识演算法及许多种奖赏验证者的方式,因此有许多不同种类的权益证明机制。从一个演算法的角度,主要分为两种: 链型态的权益证明机制及Byzantine Fault Tolerance( BFT,拜占庭容错)相似的权益证明机制。
在链型态的权益证明机制中,演算法在每个时间区间(例如每十秒为一区间)里以伪随机的方式选择验证者,并赋予其创造一个区块的权利。而这个区块如同区块链,必须指向之前的区块(通常是指向最长链的最新区块),并随时间拉长,成为单一条持续增长的链。
在拜占庭容错相似的权益证明机制中,某个验证者被随机指派来_提议_(propose)新的区块,每一轮每个验证者将票(vote)投给特定的区块,经过多轮投票来决定区块是否有效。在过程结束之后,该区块是否合法会达成永久的共识,即不会再改变。
### 权益证明机制在和工作量证明机制相比下有哪些优点?
详细说明可见:[ A Proof of Stake Design Philosophy ](https://medium.com/@VitalikButerin/a-proof-of-stake-design-philosophy-506585978d51)里有更完整的论述。
简短来说:
* 不需要为了达成链的安全而**消耗大量电力**,(估计以太坊和比特币每天都会各消耗一百万美元在电力及硬体成本上)。
* 因为不需要消耗大量电力,所以**没有发行等量的货币的需要**来提供加入网路的动机。理论上什至可以有净量为负值的发行量--透过销毁一部分的交易手续费的方式来达成。
* 权益证明机制提供了更多赛局理论的发挥空间,来**降低中心化组织的形成**,以及在组织已形成的情况下,可能的方法来防止他们进一步伤害网路(例如工作量证明机制中的[ selfish mining ](https://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf))。
* **减少中心化造成的风险**。因为采用权益证明机制后,矿工(验证者)要扩展规模将不会是个问题。在工作量证明机制中,当你资本多到一定程度,你可以负担更好的规模生产设备,拉大和其他人的差距(投入一千万的成本所获得的收益不只是投入一百万的十倍)。而在权益证明机制中,相比于一百万货币,持有一千万的货币会保证让你获得十倍的报酬,而且是以公平的方式。
* 可以利用经济上的惩罚来**大大地提高不同51%攻击方式在权益证明机制中所需要的成本**,引用Vlad Zamfir所述--"想像一参与51%攻击你的ASIC工厂就会被烧毁"。
### 权益证明机制和传统的拜占庭容错研究怎么结合?
拜占庭容错研究中有一些重要的结论是适用到各种共识演算法中的,包含传统的演算法如PBFT,同时也可用在任何权益证明机制中。如果搭配恰当的数学模型,甚至可以用在工作量证明机制中。
这些重要的结论包含:
* [ **CAP理论** ](https://en.wikipedia.org/wiki/CAP_theorem) - "如果网路发生阻断(partition)时,你只能选择资料的一致性(consistency)或可用性(availability),无法两者兼得"。论点很直觉:如果网路因阻断而分隔为二,在其中一边我送出一笔交易:"将我的十元给A";在另一半我送出另一笔交易:"将我的十元给B "。则此时系统要不是(1)无可用性,即这两笔交易至少会有一笔交易不会被接受;要不就是(2)无一致性,一半看到的是A多了十元而另一半则看到B多了十元。要注意的是,CAP理论和扩展性(scalability)是无关的,他在分片(sharded)或非分片的系统皆适用。
* [ **FLP impossibility** ](http://the-paper-trail.org/blog/a-brief-tour-of-flp-impossibility/) -在非同步(asynchronous)的环境中(即两个正常运作的节点间,网路延迟没有上限),只要有一个恶意的节点存在,就没有演算法能在有限的时间内达成共识。但值得注意的是,[ "Las Vegas" algorithms ](https://en.wikipedia.org/wiki/Las_Vegas_algorithm)在每一轮皆有一定机率达成共识,随着时间增加,机率会越趋近于1 。而这也是许多成功的共识演算法会采用的解决办法。
* 容错的上限- 由[ DLS 论文](http://groups.csail.mit.edu/tds/papers/Lynch/jacm88.pdf) 我们可以得到以下结论: (1)在部分非同步(partially synchronous)的网路环境中(即网路延迟有一定的上限,但我们无法事先知道上限是多少),协议可以容忍最多1/3 的拜占庭故障(Byzantine fault)。(2)在非同步(asynchronous)的网路环境中,具deterministic 性质的协议无法容忍任何错误,但这篇论文并没有提及[ randomized algorithms](http://link.springer.com/chapter/ 10.1007%2F978-3-540-77444-0_7) 在这种情况可以容忍最多1/3的拜占庭故障。(3)在同步(synchronous)的网路环境中(即网路延迟有上限且上限是已知的),协议可以容忍100% 的拜占庭故障,但当超过1/2 的节点为恶意节点时,会有一些限制条件。要注意的是,我们考虑的是"具认证特性的拜占庭模型(authenticated Byzantine)",而不是"一般的拜占庭模型";具认证特性指的是将如今已经过大量研究且成本低廉的**公私钥加密机制**应用在我们的演算法中。
工作量证明机制[ 已被Andrew Miller及其他人分析过 ](https://socrates1024.s3.amazonaws.com/consensus.pdf),是一个仰赖同步的网路环境的模型。我们可以将网路设定为有接近无穷数量的节点,而每一个节点拥有非常小的算力,且在一定时间内有非常小的机率可以产生区块。在这个设定中,假如没有网路延迟存在,则此协议有50%的容错率。经过观察,以太坊有约46%而比特币拥有约49.5%的容错率,但如果网路延迟和产生区块时间相当时,容错率会降低至33% ,若网路延迟趋近无限,则容错率趋近零。
权益证明机制则是包含在拜占庭容错共识模型中,因为所有验证者皆是已知且系统会记录验证者的数量。权益证明机制的研究一般可分为两个路线,一个是同步的网路环境模型,一个是部分同步的网路环境模型。链型态的权益证明机制演算法几乎都仰赖同步的网路环境模型,而它们的安全性分析也都可用这些模型以相似于[ 工作量证明机制 ](http://nakamotoinstitute.org/static/ docs/anonymous-byzantine-consensus.pdf)的方式来分析证明。另一个路线将部分同步网路环境中的传统拜占庭容错演算法和权益证明机制做连结,但解释比较复杂,在后面的章节会有更深入的探讨。
工作量证明机制演算法和链型态的权益证明机制演算法都偏好资料的**可用性**而非资料的**一致性**,但拜占庭容错类的共识演算法更倾向于选择资料的**一致性**,[ Tendermint ](https://github.com/tendermint/tendermint)明确地选择资料一致性的特质。而Casper则采用混合的模型,此模型偏好资料的可用性,但尽可能的确保资料的一致性,它让链上的应用和使用者在任何时间都能知道当前资料的一致性有多大的保证。
Ittay Eyal和Emin Gun Sirer的[ selfish mining研究 ](https://bitcoinmagazine.com/articles/selfish-mining-a-25-attack-against-the-bitcoin-network-1383578440)结论-在不同网路环境的模型中,比特币挖矿的激励兼容性(incentive compatibility)分别受到25%及33%的限制,即只有在25%或33%的矿工同谋不可能发生的前提下,挖矿的机制才是激励兼容的(即矿工按照正常的方式挖矿:有多少算力获得多少报酬)。这个结论和传统的共识演算法的结论无关,因为传统共识演算法的结论并没有牵涉到激励兼容性。
### 什么是"无成本风险"问题及该如何解决这个问题?
在许多之前(链型态)的权益证明机制演算法,包含Peercoin,只有对产生区块给予相对应的奖赏但并没有惩罚。这在出现多条相竞争的链(即分叉)的情况时,会有非预期的影响,因为每个验证者皆有动机在每一条相互竞争中的链上产生区块(以下将下注和产生区块视为相同意思)来确保他们会获得奖赏,如下:
![](https://raw.githubusercontent.com/vbuterin/diagrams/master/possec.png)
在工作量证明机制中,这么做会导致矿工的算力被分散,导致获利下降:
![](https://github.com/vbuterin/diagrams/blob/master/工作量证明机制sec.png?raw=true)
当给予区块奖赏的同时却没有惩罚,结果就会造成-如果每个验证者都是狭义上(narrowly)经济理性的话,则即便在没有任何攻击者的情况下,区块链本身也没办法达成共识。因为每个验证者都在每条链上下注。如果有攻击者,攻击者只需要赢过那些执行利他行为(altruistic,即只会在单一条链下注)的节点即可,不需要赢过那些经济理性的节点。相反的在工作量证明机制中,攻击者必须要同时赢过利他节点和经济理性节点(但这确实是可行的攻击:参考SchellingCoin的[ P + epsilon攻击 ](https://blog.ethereum.org /2015/01/28/p-epsilon-attack/))。
有些人会认为下注者有动机按照规则来下注且只下注在最长的链上,好让他们的投资能够保值。然而这个论点忽略了这个动机受制于公地悲剧理论([ tragedy of the commons ](https://en.wikipedia.org/wiki/Tragedy_of_the_commons)):每个下注者可能只会有1%的机会成为关键(pivotal)的角色(即他的决定会影响一个攻击的成败),所以用来买通他们的贿络金额只需要是他们总赌注金额的1% 。因此,全部的贿赂金额只需要是下注总额的0.5-1% 。此外,本段开头的论点同时暗示着任何"不可能失败"的情况都不是一个稳定的平衡,因为不可能失败的情况代表每个下注者成为关键角色的机会是零,即只要贿赂金额超过0%都能让下注者有动机参与攻击。
有两种方式可以解决这个问题。第一个为"Slasher",在[ 这篇文章 ](https://blog.ethereum.org/2014/01/15/slasher-a-punitive-proof-of-stake-algorithm/)有大略地描述,并进一步由[ Iddo Bentov ](https://arxiv.org/pdf/1406.5694.pdf)开发。当验证者同时在不同条分叉的链上下注(产生区块)的情况发生时,将证据纪录进区块链中并以此销毁验证者的下注资本。这让动机结构改变如下:
![](https://github.com/vbuterin/diagrams/blob/master/slasher1sec.png?raw=true)
注意,这个演算法要能执行,**验证者是哪些人**需要事先就知道。否则验证者可以任意选择要下注的链:即当A链可下注就下注A链,当B链可下注就下注B链,当两条都可以下注就下注最长的链。所以事先确定验证者的名单可以避免这种情况发生。但这也有缺点存在,包括要求节点需要频繁地上线来获得安全可信的链的状态(即确认区块是不是由合格的验证者所产生),并且让medium-range的验证者共谋攻击有可能发生(例如连续三十个验证者中有25个预谋发起攻击来回复过去19个区块),因为验证者事先知道什么时候会轮到他产生区块。如果这些风险是可接受的那就没太大问题。
第二个方式单纯地惩罚在错的链产生区块的验证者。也就是当有两个互相竞争的A和B链,如果有一个验证者在B上面产生区块,则他可在B链上获得R 的奖赏,但这个区块的标头(header)资料会被记录在A链上(在Casper 中叫做"dunkle" )且他在A链上会受到F 的罚金( F 可能等于R )。这会将结构改变成:
![](https://github.com/vbuterin/diagrams/blob/master/slasher2sec.png?raw=true)
直觉来说,我们可以把工作量证明机制的经济模型复制到这来用。在工作量证明机制中,在错的链上产生区块同样有惩罚,但这个惩罚并不显而易见:矿工额外的电力或硬体成本花费(因为要同时在两条链上花费运算)。第二个方式的一个缺点是,它将些微的风险加注到验证者身上(因为验证者要承担在错的链上产生区块的成本),不过这个风险会随者时间慢慢减退,但另一方面,它的优点是不需要事先知道验证者有谁。
### 上一章节介绍链型态的权益证明机制如何解决"零风险成本"问题,那拜占庭容错相似的权益证明机制又是怎么运作的呢?
拜占庭容错类型(部分同步的网路环境)的权益证明机制演算法允许验证者藉由送出遵守两类别规则的签名讯息,来对区块进行"投票",这两类规则分别是:
* **终局条件(Finality conditions)** -规则用来决定某杂凑值是否可被视为不可更改的(finalized)。
* **删砍条件(Slashing condition)** -规则用来决定是否有足够理由怀疑某个验证者作弊(例如同时下注多个相冲突的区块)。
如果有验证者触发其中任何一条规则,他们的资本将全数被删去。
以下举两个例子来说明不同删砍条件的发生场景,下面的" 2/3的验证者"代表"全数验证者资本总和的2/3,而不是验证者数量的2/3 ",其他的比例亦相同。在这些例子中,"PREPARE"和"COMMIT"可单纯地理解为两种验证者可送的签名讯息(`MESSAGE`)。
1.如果`MESSAGE`包含:`["COMMIT", HASH1, view]`和`["COMMIT", HASH2, view]`,其中`view`为相同但`HASH1`和`HASH2`不同,且皆由同一个验证者所签名,则该验证者的资本被删去。即不能同时对相冲突的区块做签名。
2.如果`MESSAGE`包含:`["COMMIT", HASH, view1]`,则**除非** `view1 == -1`,或同时存在其他包含`["PREPARE", HASH, view1, view2 ]`的签名讯息(其中`view2 < view1`)且这些讯息由至少2/3的验证者所签名,则对`"COMMIT"`签名的验证者的资本被删去。即一个`HASH`值只有经过至少2/3 `PREPARE`才能被`COMMIT`。
合适的删砍条件需要有两个重要的要求:
* **可咎责的安全性(Accountable safety)** -如果相互冲突的`HASH1`和`HASH2`(即分叉)都被认定为不可更改,则至少有1/3的验证者肯定违反了某些删砍条件。
* **Plausible liveness** -除非至少1/3的验证者违反了某些删砍条件,否则必定存在某些合法的讯息是2/3的验证者可以签的,且这些讯息会让某些杂凑值变成不可更改(finalized)。即除非至少1/3的验证者违规,否则一定可以让新的杂凑值被finalize。
如果我们有一组删砍条件可以达成这两个要求,我们便可以提供验证者足够的动机,并开始从economic finality 的特性中得到成果。
### 一般来说,什么是"经济面上终局的特性"?
经济面上终局指的是:当区块被认定为不可更改,或更一般来说,有一种讯息获得足够数量的签名,则唯一让链在未来纳入另一个相冲突的区块的方法是有一大群的人愿意赔上一大笔钱。如果一个节点看到某个区块符合经济面上终局的特性,则他有经济面上非常大的保证这个区块会成为链的一部分历史(且这条链也是大家都认可的)。
达成经济面上终局有两种方法:
1.如果有足够多的验证者对以下形式的声明进行签名,则一个区块可被视为具有经济面上的终局:"当区块B没有被收入则我会失去X的资本"。这让使用者获得了如下的保证- (I)区块B是链的一部分,或是(II)若验证者想骗他们,让他们相信区块B是有被收入的,则验证者会损失一大笔钱。
2.如果有足够多的验证者签名表达支持收入区块B,而且有方式能在验证者违规时提出数学证明(_当不同于区块B的某区块B'也以同样方式被收入_)并让这些验证者损失一大笔钱,则一个区块可被视为经济面上的不可更改。如果使用者看到这个被收入的区块,并验证了链的有效性,且藉由有效性(validity)和不可更改性(finality)他们可以在发生分叉的链之中做出选择,则他们能获得如下的保证- (I)区块B是链的一部分,或是(II)若验证者同时也参与了另一条互相竞争且亦符合终局条件的链,则验证者会损失一大笔钱。
两种达成终局(finality)的方法分别继承自"零风险成本问题"的两个解决方法:藉由惩罚错误(如`"COMMIT"`不合法的区块)来达成终局及藉由惩罚不明确性(如`"COMMIT"`两个冲突区块)来达成终局。第一个方法的主要优点是轻客户端(light client)使用者也能验证且比较直觉易懂;第二个方法的主要优点有(I)比较容易了解为何诚实的验证者不会被惩罚及(II)干扰因素(griefing factors)对诚实的验证者比较有利-相比于不诚实者干扰诚实者所要付出的成本,诚实者干扰不诚实者的成本是比较低的。
Casper 遵循第二种方法。不过可以透过增加链上的机制,让验证者可以自行选择是否要对第一种方法的声明("当区块B没有被收入则我会失去X的资本")签名,此举可让更多轻客户端使用者增加效率。
### 所以这和拜占庭容错理论有什么关联?
传统的拜占庭容错理论在safety和liveness上和我们有相似的要求。首先,传统拜占庭容错理论要求当超过2/3的验证者是诚实的时候,safety必须要被达成。严格来说这是比较容易实现的模型,传统的拜占庭容错理论尝试证明"如果共识机制无法达成safety,则我们知道至少有1/3的验证者是恶意的";而我们的模型则是尝试证明"如果共识机制无法达成safety,则我们知道至少有1/3的验证者是恶意的,而且我们知道是哪些验证者,即便你在出现问题的当下不在线上"。从liveness的角度,我们的模型比较容易达成,因为我们不需要证明**共识会被达成**,我们只需要证明机制**没有卡住**。
不过幸运的是,额外的"可咎责的"(accountable)特性需求其实不难实现;事实上,只要协议有正确的防御机制(protocol armor),我们都可以将任何不管是部分同步或是非同步的传统拜占庭容错演算法转换成可咎责的演算法。这个证明基本上归结于一个事实--拜占庭故障(fault)可以被穷举并分类,而这每一类要不是(I)可咎责的(如果你`"COMMIT"`了这类的讯息,则你会被逮到,且我们可以为此建立一条删砍条件的规则),要不就是(II)无法被分辨是网路延迟还是故障(注意,即便是太早送出讯息这种故障,也没办法被分辨出来)。
### 什么是弱主观性(weak subjectivity)?
首先很重要的一点是,利用存款(deposit,也就是验证者加入的资本)来确保"风险成本不为零"的机制,改变了权益证明机制的安全模型假设(security model)。假设(I)存款会被锁住一个月,时间到之后可以提走, (II)有个51% 攻击尝试反转(revert)长达10 天的交易量,则这些攻击者产生的区块会被写入链里当作证据且验证者会被惩罚。然而,假设攻击变成长达40 天,则虽然这些攻击产生的区块可以再被写入链里,但验证者早已能把钱提走而不会受到惩罚。为了要解决这个问题,我们需要一个"反转限制(revert limit)"的规则,也就是当反转所影响的区块总时间长度超过存款锁住的期限,则节点可以拒绝接受这些区块(在上例,即拒绝影响超过一个月的反转区块)。这表示节点现在多了两项要求:
1.当节点第一次连上并要同步链的资料的时候,他们必须藉由链外的方式来验证最新的状态,即透过朋友节点们或各个Block Explorer等等的方式。如果他们得到的都是同一条一样的链,则可以确定这条是正确的。注意,只有在出现链分叉长度超过反转限制时(在上例,即得到两条在过去超过一个月的区块皆不相同的链)才需要这种采用这种链外的交际验证( social authentication)。
2.节点每隔一段的时间("反转限制"时间)就必须要上线同步。如果没定时同步,则需要再透过一次链外的交际验证来保证状态的可信度。
如果攻击者要利用链外交际这个管道来攻击,他们必须要说服社群里一大部分的人,让他们相信攻击者的链才是有效的;或是改为说服新加入社群的人:新加入的人可能会在下载软体时一并收到最近一次的检查点(checkpoint,即反转限制的临界点),但如果攻击者能窜改这个检查点的纪录,则他们要能直接窜改整个软体也不再是件难事,而且没有单纯的密码经济学的验证方式能解决这个问题。当一个节点连接上了,只要他够频繁地上线,他就能以密码经济学上安全的模型来确保连接上正确的链,而不需要额外的链外交际验证。
另外,这种交际验证如果需要,也可以直接加入进使用者使用的过程中:如(1)[ BIP 70 ](https://github.com/bitcoin/bips/blob/master/bip-0070. mediawiki)的交易就要求交易里要加入最近一段时间的某个区块的杂凑值,使用者的软体会在交易成立前,借此确保使用者和商家是在同一条链上(也可以透过其他链上的互动方式)。或(2),采用Jeff Coleman的[ universal hash time ](https://www.youtube.com/watch?v=phXohYF0xGo)。采用UHT的话,如果攻击要能成功,攻击者必须在被攻击链继续增长的**同时**,暗中产生另一条链(即攻击者没办法事先或在事后短时间内产生一条相抗衡的链),代表这需要大多数的验证者共谋了一段非常长的时间。
### 在权益证明机制里可以用经济上的方式来惩罚审查(censorship)行为吗?
审查行为比起交易反转要更难去证明。区块链本身无法分辨(1)"使用者A 尝试送出交易X 但被审查过滤掉了" 或是(2)"使用者A 送出交易X 但因为交易费不够而没被收入区块里" 或是(3)"使用者A 从未送出交易X "。但仍有一些方法可以对抗审查行为。
第一个是使用停机问题(halting problem)。这个方法比较弱的版本是将协议设计成图灵完备,使得验证者无法知道一笔交易会不会在花费他大量的运算后因为出现预期外的行为而出错,但这同时也让验证者面临潜在的DoS攻击。这也是当初[ the DAO软分叉 ](http://hackingdistributed.com/2016/07/05/eth-is-more-resilient-to-censorship/)没有实行的原因。
比较强的版本则是让交易在未来中短期的时间内触发特定的效果。使用者可以送出多笔相互关联的交易及利用可预期的第三方的资讯来导致未来事件的发生,想要进行审查的验证者要等到交易都被收入区块(并确认为不可更改)才能知道发生了什么事件,但此时要阻止交易又已经太迟。即便过滤掉所有相关的交易,审查者想阻止的事件还是会发生。审查者可以试着过滤掉每一笔交易,或是过滤掉没有附上相关证明(证明交易不会导致任何非预期的情况发生)的交易,但这么做会挡掉非常多不同类型的交易以至于让整个系统失灵,审查者的存款价值也会跟着该数位货币的价值崩盘而下降。
第二个方法是([ 如Adam Back在这篇文章 ](https://www.reddit.com/r/Bitcoin/comments/4j7pfj/adam_backs_clever_mechanism_to_prevent_miners/d34t9xa))所介绍,要求交易都经过[ timelock-encrypted ](https://www.gwern.net/Self-decrypting%20files)加密。所以审查者只能在不知道交易的内容的情况下将交易收入区块,直到之后某个时间点交易内容被揭露,但此时要过滤掉交易已经太迟。但是审查者可以选择只收入有附上解密证明(如利用zkSNARK等零知识证明)的交易;这虽然会强迫使用者必须要去下载相关的使用软体,但审查者可以直接提供所需软体。这在赛局理论中,使用者是有动机去配合的。
或许在权益证明机制中比较好的做法是使用者透过软体更新来执行硬分叉,将恶意的验证者移除。这个方法和下载解密软体来配合审查的方法相比,并没有多难。总之,第二个方法虽然会降低和链沟通互动的速度(注意,采用这个方法必须是强制的才会有效,否则审查者只需要过滤掉经过加密的交易并收入没加密的交易即可),却也是比较适度且有效的。
第三个方法是在链分叉发生时,将侦测审查行为发生的机制加进分叉选择的考量。原理很简单,节点持续观察着网路及交易,如果他们发现某笔交易带有够多的手续费却迟迟未被收入,就给没有收入这笔交易的链较低的评分。如果所有的节点都遵守这规则,则最终较弱势的链也会因为收入了这个交易而让其他诚实的节点都转而加入这条链。这个方法主要的缺点是,离线的节点还是纪录者强势的(有审查机制的)链,如果在他们重新上线之前审查行为就结束了,则会造成上线的(诚实的)节点间的分歧。因此这个方法比较适合被用来当作紧急情况如硬分叉发生时的一个节点间的协调工具,如果是用在几乎每天都会发生的链分叉选择考量则不太合适。
### 验证者是怎么选出的?什么又是stake grinding?
在任何链型态的权益证明机制演算法中,都需要一个机制来随机选出哪个验证者可以产生下个区块。例如,假设目前活跃中的验证者包含资本为40 元的的Alice、资本为30 元的Bob、资本为20 元的Charlie 及资本为10 元的David,则你希望他们各自被选出的机率分别为40%、30%、20%及10%(当然在实际情况中,你会希望选出来的是一连串无限的候选人而不是一个,这样当前面一位没出现,后面一位就可以递补,但这不影响根本的问题)。在非链形态的演算法中,一样会因为不同原因而需要随机性(randomness)。
"Stake grinding"是一种验证者试图透过一些计算或其他方式来影响随机性的攻击。例如:
1.在[ Peercoin ](https://bitcointalk.org/index.php?topic=131901.0)中,验证者可以搜寻各种参数的组合并找到特定的参数来增加他们产生有效区块的次数。
2.在一个目前已经不使用的方式里,第N+1个区块的随机性取决于第N个区块里的签章。这让验证者可以重复产生新的签章直到他们找到一个特别的签章来让他们能预测并掌握下一个区块,以借此控制系统。
3.在NXT中,第N+1个区块的随机性取决于产生第N个区块的验证者。这让验证者可以藉由跳过一个产生区块的机会来操纵随机性。虽然这么做的机会成本是损失一个区块奖赏,但有时候新产生的随机种子可以让验证者在未来数十个区块中获得高于平均区块奖赏的奖励。[ 这里 ](http://vitalik.ca/files/randomness.html)有更详细的分析。
\# 1和\# 2很容易解决;一般的做法是要求验证者事先存款来避免验证者一直改变身份(address)来找到可以影响随机性的值,并避免使用可以轻易被操纵的讯息,例如一个区块里的签章。有几个主要的策略来解决\# 3。第一个是利用[ secret sharing ](https://en.wikipedia.org/wiki/Secret_sharing)或是[ deterministic threshold signatures ](https://eprint.iacr.org/2002/081.pdf)并要求验证者一同产生随机值。这些方法在大多数验证者没有同谋的时候都足够稳固(看各种应用不同,33%-50%的验证者合谋就可以干预,使得协议对维持liveness的机率假设剩下67% )。
第二个方法是使用密码学的方式:验证者事先commit一些讯息(如公布`sha3(x)`),接着在区块内公布`x`值,最后将`x`值和其他人的随机值加在一起。理论上针对这个方法有两种潜在的攻击。
1.在commit时操纵`x`值。但因为结果会将许多人的`x`值一起加入考量,其中只需要一个人是诚实的,随机性的分布就会呈常态分布,所以这攻击不太可行。
2.选择性地不公开区块。这种攻击的机会成本是损失一个区块奖赏,而且这个方法顶多只能让一个人看到下一个区块的验证者是谁,所以最多可能的获益也是一个区块奖赏。唯一的例外是,如果一个验证者跳过,则递补上来的验证者和下一个区块的验证者有可能会是同样一个验证者。可以用惩罚的方式来抵消验证者跳过的动机。
第三个方法是使用[ Iddo Bentov的"majority beacon" ](https://arxiv.org/pdf/1406.5694.pdf),藉由之前产生的(也用beacon方式产生的) N个随机数字中的每个bit值的多数决来产生新的随机数字(即,如果大多数数字的第一个bit为1 ,则新的数字的第一个bit为1 ,否则为0 )。攻击的成本会是`~C * sqrt(N)`,其中C是攻击其他beacon产生的随机数字的成本。总之,有许多stake grinding的解决方法存在,这个问题比较像是[ differential cryptanalysis ](https://en.wikipedia.org/wiki/Differential_cryptanalysis)而不是[ halting problem ](https://en.wikipedia. org/wiki/Halting_problem) -权益证明机制的设计者最终会明了且会知道如何克服,不是很根本且无法弥补的缺陷。
### 针对Casper的51%算力攻击会是怎么样的攻击?
51%攻击最基本的形式就是**finality reversion**:验证者确立区块A的纪录为不可更改后又将另一个区块A'也列为不可更改,打破区块不可更改特性的保证。在这个情况中并存着两个彼此不相容的历史纪录,导致链产生分叉。这需要仰赖社群以链外的方式进行协调来决定应该选择哪条链,而哪条该被舍弃。
协调的管道有很多种,如社群媒体、block explorer及交易所间的沟通、线上论坛等等。决定该选哪条链的原则是"哪条先出现就选哪条" 。另一个方式是让市场机制去决定:在很短的时间里,两条分叉都可以在交易所中交易,直到其中一条因为价值更高而胜出。在这种情况中,"哪条先出现就选哪条"的原则会是市场机制的[ Schelling point ](https://zh.wikipedia.org/wiki/谢林点),即参与者会因为觉得其他人也会选择先出现的那条链而倾向选择先出现的那条,所有人在没有沟通的情况下按照这个倾向选择了先出现的那条链。所以实际中,这两种方式并用是非常有可能的。
当该选择哪条链的共识达成时,使用者(即验证者、light node 及full node)就可以手动地将胜出区块的杂凑值藉由特殊的选项写入软体中,之后他们的节点就会忽略其他不包含该杂凑值的链。之后不管是哪条链被选择,都有证据可以用来惩罚至少1/3 的违规验证者。
另外一种攻击是阻断liveness:一个由超过34% 验证者组成的集团可以拒绝和其余的验证者合作。在这种情况下,将没有区块能被变成不可更动。Casper 采用混合(链+ 拜占庭容错)型态的共识,因此链还是会持续增长,但安全性会大大降低(因为一直没有新的区块可以被视为不可更改)。如果很长一段时间(例如一天)都没有区块变成不可更改,则有以下几种选项:
1.可以采用一个自动化的功能来轮转验证者名单,瓦解集团的占比。在新的验证者名单中区块有机会被变为不可更改,但使用者会收到提醒告诉他们这些不可更改的区块还是不能全信的,因为很有可能旧的一组验证者会重新夺回控制权并改为将其他的区块变为不可更改。使用者如果确信旧的一组验证者不会再上线,就可以忽略这些警告。在这种情况发生时,所有旧的验证者如果没有再继续参与共识过程,则他们会受到相当大笔的罚款。
2.采用硬分叉的方式移除集团验证者的存款,并增加新的验证者。
在第二种方法中,分叉还是一样要由链外的共识来协调,且可能会由市场机制的方式(即两条拥有不一样验证者组成的链短暂的并存于交易市场上)。如果是藉由市场共识的方式,有个有力的论点是:市场会倾向选择"好人胜出" 的链,这条链的验证者展现了他们的诚意(或至少他们和使用者的利益是并存的),因此也是一条对应用开发者较有用的链。
选择攻击应对的策略如社交协调或机制内自动化,两者之间其实有如一道光谱,并不是非黑即白。通常设计越往自动化的解法越理想,因为这可以降低当51%攻击和社交层面(包含市场共识如交易所)的攻击同时发生时的风险。可以想像一个采用\# 1的措施:节点在超过一定时间都没有区块变为不可更改时自动更换验证者名单,这会降低交际协调的需要,但节点也因此要更频繁地保持上线。但不管是哪种方式,攻击者都会损失一大笔的钱。
另外一种比较不容易发觉的攻击是审查攻击:超过34% 的验证者拒绝将含有某些特定交易的区块变为不可更改,除此之外链的运作都正常。攻击的范围从轻微的,干扰特定应用的攻击(如过滤Raiden 或闪电网路的交易是较简单偷钱的方式)到阻挡所有交易的大范围攻击。
其中又分成两种情况,第一个是攻击者占34%-67%。在这种情况中,正常的验证者可以拒绝将他们主观认定为正在过滤交易的区块(即攻击者产生的区块)变成不可更改或接在后面,这让这种攻击变为一个标准的针对liveness 的攻击。比较危险的情况是当攻击者占超过67%,攻击者可以任意的阻挡他们不喜欢的交易并拒绝接在包含这些交易的区块后面。
面对这个攻击有两道防线。第一,以太坊具有图灵完备特性,[ 在本质上就具有抵抗审查的能力 ](http://hackingdistributed.com/2016/07/05/eth-is-more-resilient-to-censorship/) ,因为审查交易的过程在某种程度上相似于解决停机问题(halting problem)。但因为区块有gas限制,所以审查并不是不可能,不过用"简单"的方式来审查反而会让攻击者自己有被DoS的风险。
单纯具有这个抵抗能力[ 还不够好 ](https://pdaian.com/blog/on-soft-fork-security/),还有其他方式可以加强抵抗审查的能力。最有趣的方式是增加一个机制内的功能:让交易能自动规划未来的事件,因为预测一个事件的执行结果或是连锁事件是很难的。验证者可以藉由混淆事件规划的顺序来加入成为验证者,借此稀释攻击者的占比到低于33% 。
第二,引进"active fork choice rule" 的概念:当面临链分叉,其中一个选择链的考量是和链进行互动并借此验证该链是否有在过滤你的交易。最有效的方式是节点重复地送出一笔交易来规划下注并在最后一刻取消。如果节点侦测到审查机制,就不取消交易并暂时加入成为验证者之一,将攻击者的占比稀释到33% 。如果集团过滤掉他们的交易,则采用这个"active fork choice rule" 的节点就不会选择这条链。这会让审查攻击转变为liveness 攻击,此时就可以藉由解决liveness 攻击的方式来处理。
### 听起来似乎很仰赖链外的社交协调,这样难道不危险吗?
攻击Casper代价非常高。以下我们将会讲到,攻击Casper的代价至少和买矿机持续不断的对采用工作量证明机制的链发动51%攻击直到无效果为止的代价一样。因此,上面段落所描述的复原方法只有在非常极端的情形才会用到。事实上,工作量证明机制的提倡者亦表达在某些相似情况采用社交协调的意愿,例如[ 改变工作量证明机制的算法 ](https://news.bitcoin.com/bitcoin-developers-changing- proof-work-algorithm/)。所以权益证明机制需要的社交协调是否会比工作量证明机制所需要的社交协调还多还无明确的结果。
在现实中,我们预期用到社交协调的方式的次数会接近零次,因为攻击者会了解到单纯为了让区块链停摆一两天要花费这么大笔的钱是不符利益的。
### 边际成本趋近边际收益不就表示所有具有一定高度安全层级的共识演算法都一样有效(或一样地浪费)?
许多人都提出过这个论点,而解释最清楚的就属[ Paul Sztorc的这篇文章 ](http://www.truthcoin.info/blog/工作量证明机制-cheapest/)。其中的重点大概是:如果你创造一个有100元奖赏的机会,则大家为了得到它会愿意花费最高到99.9元(包含自己付出的劳力),此时边际成本趋近边际效益。因此,这个理论说:任何提供区块奖赏的演算法(不管是权益证明机制或工作量证明机制),其中为了获取奖赏而进行对社会无效益的活动的数量都是一样的,即它们都一样地浪费资源。
这个理论有三个盲点:
1. **单纯地说边际成本趋近边际效益是不够的,必须还要假设一个真的有人可以花费那些成本的机制存在。**例如,假设我明天宣布未来每一天我都会随机从一个十人名单中挑出一个人并给予他100元,然而没有人有办法花费99元来取得其中的随机值。他们要不是不在名单中拿不到奖赏,要不就是在名单中但没有任何有效的方法取得我的随机值,只能获得期望值为平均每天10元的奖赏。
2. **边际成本趋近边际效益不表示总成本趋近总收益。** 例如,假设存在一个演算法利用伪随机(pseudo-randomly)的方式从一大群验证者中选择1000 位验证者(一个验证者获得1 元奖赏)。如果你资本占总资本的10% 则你平均会获得100 元。假设你可以花费1 元来(无限次地)重设随机值,因为[central limit theorem](https://en.wikipedia.org/wiki/Central_limit_theorem),你可获得的奖赏的标准差是10 元,又因为[其他已知的数学结论](http://math.stackexchange.com/questions/89030/expectation-of-the-maximum-of-gaussian-random-variables), N 个随机抽样中最大的期望值约略小于` M + S * sqrt(2 * log(N))` ,其中M 是中间值且S 是标准差。因此增加重设随机值的次数(即增加N )所获得的奖赏会快速地下降,例如如果完全不尝试重设随机值你的期望获利是100 元,尝试一次是105.5 元,两次是108.5元,三次是110.3 元,四次是111.6 元,五次是112.6 元,六次是113.5元(只增加0.9 元的获利)。因此尝试超过五次之后就不值得再继续尝试。所以一个由经济因素所驱动的攻击者,如果他总资本占10% ,则他会花费5 元尝试重设随机值来获得额外的13 元的获利,虽然这么做很没效率。如果一个机制可被有心人士利用,但被利用的机率不高,则损失不会多。但这不适用于在工作量证明机制中因为出现一个漏洞而导致全部资源投入而造成浪费的情况。而这点也和下一章节要介绍的capital lockup costs 非常相关。
3. **权益证明机制要变得安全稳固所需要的奖赏比起工作量证明机制的奖赏少的非常多。**
### 什么又是capital lockup costs?
将X数量的ether锁进存库是有代价的,例如牺牲选择其他选项的机会。如果我有1000 ether,我想怎么使用就怎么使用,但如果我将它锁在存库里数个月,而且没有保险来支付可能的意外支出的时候该怎么办?在这段时间我同时也失去将ether转换成其他代币的自由。我可以透过卖空相等数量ether的方式来模拟卖掉我的ether,但会有交易手费续和利息的成本。有些人可能会认为: captital lockup造成的经济上的不便和工作量证明机制造成的经济层面上无效率的程度是一样的。但答案是否定的,如同上一章节的理由\# 2和理由\# 3。
我们先从理由\# 3开始讲起。考虑一种模型:权益证明机制存款是无限期的、ASICs可以永久持续运作、ASIC技术固定(即不适用摩尔定律)而且电力花费是零,并假设稳定的利率是每年5%。在工作量证明机制里,我花1000元买了矿机,矿机每年给我50元的利润直到永远。在权益证明机制中,我存1000元(因为存款是无限期的所以这笔钱当作花掉)并获得每年50元的利润直到永远。到目前为止,两种情况看起来是等价的(虽然技术上来说,在权益证明机制中当我的存款因违规被销毁时,会间接造成其他人的存款价值升高,但这边我们先不讨论)。在这个假设下,不管是权益证明机制或工作量证明机制,任何人要发动"Maginot-line" 51%攻击(即硬体买得比网路其他人加起来还多)的成本都会因为我的加入而再多上1000元。
现在假设模型依序做以下的变更:
1.摩尔定律适用,ASICs每2.772年贬值50%(为方便计算,假设其价值每年持续降低25%)。如果我要继续保持"付一次,永远都能持续拿回钱"的模式,我可以将1000变成一笔资金,其中167用来买ASICs ,833元花在5%报酬率的投资。833元的投资产生每年41.67元的利润刚好足够花在更新ASICs设备上(为方便计算,假设技术发展是稳定连续的)。这时挖矿的利润会降低至167 * 0.05 =每年8.33元,因此83.3%的矿工会退出竞争,直到回到每年50元利润的稳定状态,所以这时发动Maginot-line 51%攻击的成本会缩小至少六倍。
2. 电力加上硬体维护组成大约1/3 的挖矿成本。1/3 是从最近的数据估计而来的:Bitfury 的新资料中心[每gigahash 电力消耗为0.06 焦耳](http://www.coindesk.com/bitfury-details-100-million-georgia-data- center/),或每terahash 60 焦耳、每terahash 0.000017千瓦小时。如果假设比特币网路的平均消耗皆如此的话,以[比特币总共算力约1.67 million TH/s](http://bitcoinwatch.com/) 来算,每秒约消耗27.9 千瓦小时。中国电力成本为[每千瓦小时0.11 元](http://www.statista.com/statistics/477995/global-prices-of-electricity-by-select-country/),约为每秒3 元或每天26 万元。比特币区块奖赏加上手续费为600 * 13 * 144 = 一天112 万元。因此电力组成约23% 的成本,另外我们可以用简单的计算预估硬体维护成本为10% 。这表示你的1000 元资金里,只有111 元要拿来买ASICs,55 元要拿来付持续性的花费如电力和维护等,而833 元会花在投资上,因此现在要发动Maginot-line 51% 攻击的成本已经是一开始的至少九倍小了。
3.事实上存款是短暂而非永远(被视为拿不回来)的,当然你自愿永远存着的话也行。这让我多了一些空间选项,我可以在任何时间内结束并等待一段时间(如四个月)。这表示我愿意花更多的钱来获得更多的利润(因为投资不会再被当作拿不回来的钱),或许是3000元。因此,在权益证明机制里发动Maginot line 51%攻击的成本增加为原本的三倍,和工作量证明机制比起来是27倍的安全性。
以上包含了很多简化过的计算,但它的目的是为了指出经过许多因素考量,都显示出权益证明机制有更高的安全性。而这个[ 看似可疑的多重因素论点 ](http://lesswrong.com/lw/kpj/multiple_factor_explanations_should_not_appear/)为何这么强烈凸显权益证明机制的优点的主要理由是:在工作量证明机制中,我们操作并利用物理特性;而在权益证明机制中,我们可以设计出一套准确具有理想特性的机制-简而言之,我们可以用我们的方式来优化"物理特性"。在安全模型上的改变,特别是弱主观性(weak subjectivity)这个性质的出现,让我们能得到以下结论- **权益证明机制要变得安全稳固所需要的奖赏比起工作量证明机制的奖赏少的非常多。**。
接者我们可以讨论边际成本/效益和总成本/效益的不同。在capital lockup costs 的情况中这非常重要。例如假设一个情况,你有价值100000 的ether。锁住其中的50000 应该不会有什么问题,锁住80000 可能会有一点不方便虽然20000 还是够充足,锁住90000 就有点问题了,99000 问题就大了,全锁住那你可能是疯了,因为你会连交易费都出不起。因此你的边际成本快速的增加,我们可以用以下方式比较权益证明机制情况和工作量证明机制情况的不同:
![](https://blog.ethereum.org/wp-content/uploads/2014/07/liquidity.png)
可以看到在权益证明机制的总成本是远小于存入1 ether 的边际成本乘上现有所有的存款总量。
注意,这部分的论点可惜地并没有完全解释到"货币的安全发行量(safe level of issuance)"。但其显示出即使我们将货币发行量控制地很低,我们还是能获得可观的权益证明机制参与人数,虽然这也代表很大一部分的发行量会被用来奖赏验证者。
### 在权益证明机制的矿池会有类似工作量证明机制矿池中心化的风险吗?
从[ Bitcoin ](https://blockchain.info/pools)和[ Ethereum ](https://etherscan.io/stats/miner?range=7&blocktype=blocks)来看,大约需要三个矿池联合才能发动51%攻击(在写这篇文章的时候,Bitcoin约需四个、Ethereum约需三个)。假设在权益证明机制中,包含所有矿池、交易所一共有30%的参与率,则[ 三个矿池或交易所 ](https://etherscan.io/accounts)就足够发动51%攻击;如果参与率提高到40%则需要八个。另外矿池、交易所也不能将所有资本投入攻击中,因为他们需要保留部分金钱来应付客户。
再加上在权益证明机制中,组成的矿池的动机是较低的,因为这会需要较高的信任成本- 虽然矿池不偷钱,但是可以假装被骇去触发删砍条件而导致资本全被没收,同时扮成检举者领检举奖金。不过另一方面,即便需要信任对方,不需要自己跑一个full node 就能用自己的钱赚利润仍是很有吸引力的。总之,中心化和去中心化间的平衡需要经验累积,也只有等到系统真的上线一段时间了才有办法得到答案。但配上sharding 之后,我们预计会更进一步降低中心化,因为(i)需要考量的变化更少且(ii)在sharding 模型中,验证交易的负担和所投入的资本成正比,所以并不会因为组成矿池而节省成本支出。
最后一点是,中心化在权益证明机制中比其在工作量证明机制中的负面影响更小,因为从51% 攻击中复原容易且便宜多了,也不需要换新的挖矿演算法。
### 权益证明机制能被用在私有链或联盟链吗?
一般来说是可以的。任何权益证明机制演算法都可以被私有链或联盟链用做一个共识演算法。唯一不同是成为验证者的方式:一开始会由一群大家同意且信任的使用者成为验证者,接着再由这群验证者透过投票去加入新的验证者。