在秘猿科技区块链小课堂 26/27 期中,我们分享了研究员 Ren Zhang 对于主流共识协议的分析(Ren Zhang 来自于前比特币技术实现公司 Blocksteam)。这一期小课堂,我们将会深入分析 PoW 共识协议的安全性,指出三种攻击 PoW 链的方法,以及解决方案。并且提出衡量协议安全性的共同指标!(PS:前排提示,理解本文需要一定共识方面背景知识,如果看不懂。那么,只需要了解结论:1/公链更适合 PoW 共识;2/PoW 共识性能能够被突破)
秘猿科技区块链小课堂第 28 期
在 Nakamoto 共识协议(Nakamoto Consensus 图片中简称 NC)中,为解决分叉问题,矿工们被要求在可能的情况下选择最长的链;在没有最长链时,矿工选择第一个接收到的区块加入到主链中。在发放奖励方面,主链区块会获得全部奖励,而孤块什么也得不到。
这样是否足够安全?
Nakamoto 共识的原始分析倾向于认为区块链本身具备完美的链质量,即低于全网 50% 算力的攻击者是无法修改区块链的。然而实际上攻击者完全可以有非常高的成功率去修改区块链。
有三种攻击方式会修改区块链:自私挖矿(Selfish Mining)、双花(Double Spending)和审查攻击(Censorship Attack)。其中,自私挖矿的攻击者可以获得与其算力不成正比的、不公平的区块奖励。他们可以将挖矿算力集中起来去获得更高的相对区块奖励,从而破坏区块链的去中心化特性;在双花攻击中,攻击者可以逆转已确认的交易,将自己利益最大化;审查攻击情况下,攻击者阻止交易被确认,造成诚实矿工的经济损失。
三种攻击
自私挖矿
红色方块表示块被传播到网络的时间,然后橙色圆圈表示攻击者的区块,三角形表示被诚实矿工挖出的区块。攻击者很幸运地找到了第一个区块,但没有将其发布到网络上,而是选择了扣留这个区块。
当诚实矿工找到一个块时,攻击者会在这时候抢在诚实矿工之前广播之前扣留的区块,则之后所有的矿工都将在攻击者的区块而不是诚实矿工的区块上挖矿。
如果攻击者足够幸运,能够连续找到多个区块,那么攻击者就可以毫无风险地孤立一个诚实区块。在这种情况下,攻击者的的链变得更长,并且全网的算力会到它的链上挖矿。通过这种方式,攻击者成功地增加了在整体区块奖励中获得的相对比例。
双花攻击
双花攻击与自私挖矿攻击非常相似,是通过秘密挖矿来获得额外奖励。如比特币中,按照惯例有 6 个区块确认交易后基本是完全确认了。如果攻击者秘密地扣留了 6 个区块,并一次性将它们广播到网络中,他就能够在收到商品或者服务之后逆转这个交易。
审查攻击
审查攻击试图孤立所有不符合审查要求的块,即我要广播我要审查的这些交易,如果你不听从我的命令,我会尽力孤立你的块。
两种解决方法
下面我们来说说解决 Nakamoto 共识安全问题的两种方法。
第一大类我们称之为「更佳链质量」协议。如图所示这一大类中有很多协议,这些协议声称它们可以提高链的质量。这次我将重点介绍「最小哈希平局打破协议(Smallest hash tie-breaking protocol ,简称 SHTB)」 和 「不可预测的确定性平局打破协议(Unpredictable deterministic tie-breaking,简称 UDTB)」。
第二大类称为「抗攻击」(Attack-resistant protocols)协议。这些协议声称,他们可以在链的质量并不完美的情况下抵御攻击,因此他们不需要提高链的质量。
抗攻击协议的三种类型
第一种是「全部奖励」(Reward-all)协议。这类协议给大多数最近做了工作量证明的以奖励, 符合要求的块无论如何都会获得奖励,如此攻击者无法进行自私挖矿攻击来迫使诚实矿工的奖励无效,从而攻击者没有动机进行自私挖矿攻击。
第二个被称为「惩罚」(Punishment)协议。这些协议将没收那些可疑的区块的奖励。惩罚规则希望通过损失厌恶, 让所有人不得不遵守协议。
第三个被称为「幸运奖励」(Reward-lucky)协议。这些协议根据区块内容对某些幸运区块进行奖励,希望这些幸运区块作为稳定网络的「锚点」。
接下来让我们更深入地了解这些协议。
首先我们分析 「更佳链质量」这一类协议,首先是「最小哈希平局打破协议」。在这个协议中,每当有平局时,协议都要求所有矿工选择哈希最小的块,不管它首先接收的是谁。
第二个称为「不可预测的确定性平局打破协议」。该协议规定,每当有平局时,每个人都使用不可预知的确定性伪随机函数来计算所有参与竞争链的顺序,而不管首先接收哪一个块。不可预测的确定性协议背后的原理是,由于攻击者无法预测他是否会以超过 50% 的几率赢得整块竞争,进行自私挖矿攻击是不明智的(因此不会选择这么做)。
对于抗攻击协议,我会从每种技术方法中选择一种协议来分析。对于「全部奖励」协议我们来分析水果链。在水果链中,对两种不同的产品使用了相同的挖矿程序。如果一个候选区块的哈希值最前面的 k bits 小于某个阈值,那么就判断它是一个块;如果某个候选区块的哈希值最后的 k bits 小于某个阈值,那么就判断它是水果。因此,当你运行哈希算法时,你可能会得到一个区块,也可能是得到一个水果。
该协议和 Nakamoto 共识一样,遵循最长链原则,并且根据最先收到的区块打破平局。
对于所有抵抗攻击协议,我们使用 Nakamoto 共识作为其分叉解决的规则。因此,当我们分析他们的攻击抗性时,他们被置于同一规则下。
水果是嵌入在区块中的。你可以把水果想象成 Nakamoto 共识中的交易,这个交易只是被嵌入到了水果中。
每个水果都有一个指针块,这是一个最近的块,水果矿工不会被孤立 。图中香蕉块的指针就是这样一个案例,如果指针块在主链中,则水果是有效的。如果指针块是孤块,就像图上的番茄一样,那么这个水果不再是有效的水果。
还有一个额外的规则,即水果出块的间隔需要小于预定义的超时阈值。间隔定义为主区块和指针区块之间的区块高度差。
比如,香蕉的间隔就是 2,这是因为主区块比指针区块晚 2 个区块。因此有效水果获得全额奖励,而区块则没有获得任何奖励。
对于惩罚协议,我们选择 DECOR 协议修改版本作为案例来讲解。在我们的修改版本中,我们将其称为「奖励分配」(Reward-Splitting ,简称 RS)协议,顾名思义,奖励在所有相同高度的竞争区块之间平分。这个协议允许一个区块引用之前的孤块为叔块,如果其间隔是低于超时阈值的,那么这个叔块就是有效的(也会获得一定的奖励)。
这是在奖励分配协议中间隔的定义和水果链类似。不同在于,在此协议中,间隔被定义为主区块和叔块的高度差,而不是主区块和指针区块的高度差。所以我们不考虑区块的亲缘关系,只考虑该区块本身的高度。每个区块奖励在相同高度的竞争区块和叔块之间平均分配。例如,在这个图中,区块 B 和区块 C 分别得到了一半的区块奖励,区块 A 和区块 D 则获得全部的区块奖励。
最后一个是子链。子链也是采用相同的挖矿程序,但是是两种不同的产品。子链中的出块规则和比特币相同,如果候选区块的哈希低于某个特定阈值,那判断这个块有效。如果候选区块的哈希值大于块阈值但小于另一个阈值,我们将其视为弱块(Weak Block)。弱块也计入链长度,也执行交易确认的功能。但是,弱块不会收到任何块奖励。只有区块能获得块奖励。
衡量协议安全性的共同指标
我非常激动,因为下面我们要一起设定一些衡量协议安全性的共同指标。你声称这是最安全的协议,你要向我证明它,就需要从这几个指标的维度来衡量你的协议有多安全。
在这个研究中共有四个指标,我们来分析一下。
第一个指标我们称之为链质量(Chain Quality),是指主链上诚实矿工的区块的最小百分比。在这个例子中,链质量是六分之三,因为主链中有六个区块,其中三个来自诚实矿工。
第二个称之为激励相容度(Incentive Compatibility),用来衡量对自私挖矿攻击的抗性,被定义为诚实矿工区块奖励的最小百分比。
在这种情况下,由于六个主链区块中有三个区块来自于诚实矿工,因此激励相容度是 50%。在 Nakamoto 共识中,这两个指标(指链质量和激励相容度)是相等的。但是,对于其他协议,这两个指标并不相同。链质量只是用来评估拜占庭敌手(也就是作恶节点),但激励相容度则把奖励也考虑在内。
第三个指标是另一个攻击抗性的指标,称为「作恶收益」(Subversion Gain),衡量抗双花攻击的性能。它被定义为「平均每个出块间隔能够获得的区块奖励加上双花奖励的最大值」。
在这种情况下,假设每隔 10 分钟能找到一个块,如果总共有 8 个块,那么总共需要 80 分钟(其中攻击者有 3 个块)。在这个例子里,平均每 10 分钟,攻击者获得 3/8 个区块奖励。双花奖励为 0,因为双花奖励需要连续孤立六个块。
因为在抗双花攻击中没有完整的百分比奖励,因此指标设定为「平均每个出块间隔获得区块奖励的最大值」。在这张图上,没有双花攻击奖励,因为你需要连续出孤立至少 6 个区块才能获得双花奖励。
最后一个指标称为「审查敏感性」(Censorship Susceptibility),即因为拒绝审查者的要求,导致诚实矿工的奖励损失的最大百分比。因为如果我拒绝审查请求,攻击者将开始孤立我的区块。此指标用来衡量我的区块可以被孤立的百分比。在这个案例中,有 5 个诚实的块,其中 2 个是孤块,所以审查敏感性是 2/5。
评估结果
现在我们来看看评估结果。在这次分享中我分析了 5 个协议,我们来看看第一个指标链质量。
我们先定义一个变量 γ ,它是在平局情况下,在攻击者的链上挖矿的诚实矿工算力占所有诚实矿工算力的百分比。
如果 γ 等于零,那么所有诚实矿工的算力都会用在挖诚实矿工的链上,没有诚实矿工的算力在攻击者的链上挖矿。如果 γ 等于1,则所有诚实矿工的算力将在攻击者链上挖矿,并且没有人会在诚实矿工的链上挖矿。
这是是用来评估 Nakamoto 共识的通用参数。这里有五个情况,分别是在 γ = 0,0.5,1 情况下的 Nakamoto 共识、最小哈希平局打破协议(SHTB)和 不可预测的确定性平局打破协议(UDTB) ,哪一个是链质量最佳的?
在这五个协议中,最小哈希平局打破协议(SHTB) 和 不可预测的确定性平局打破协议(UDTB) 仅关注如何打破平局。所以你并不能比 γ = 0 的平局的情况下的 Nakamoto 共识做的更好。因为当 γ = 0 的时候,所有的挖矿算力将会在诚实的链上。并且你不能比 γ = 1 的情况下的 Nakamoto 共识更差了,攻击者在这种情况下可以赢得所有的平局。
所以在剩下的三个协议里(SHTB、UDTB、γ = 0.5 的 Nakamoto 协议)哪一个是表现最差的?其实是最小哈希平局打破协议。那么对于剩下两个协议(UDTB、γ = 0.5 的 Nakamoto 协议)哪一个更好呢?
我来揭开这个答案。γ = 0.5 的 Nakamoto 共识是更好的。为什么?举例来说,在不可预测的确定性平局打破协议(UDTB)中,当一个攻击者找到了一个区块,但是此时诚实的矿工打包了这个区块并且先于攻击者将它广播了出去,那么有可能这个攻击者会计算伪随机函数并意识到如果他发布了他的区块,是没有人会继续在他的区块之上挖矿的,因为他在出块竞争的平局中失败了。那么这个攻击者能够做什么?
在 Nakamoto 共识中,攻击者注定会失败,因为最先收到的区块打破平局的规则,如果你不尽快把区块发布出去,没有人会在你的区块上面挖矿。但是在 UDTB 中则不同,即使下一个区块都被挖出来了,攻击者还是能够在这个区块之上继续挖矿,只要攻击者能够赢得下一个出块权,那么成功之后这个攻击者就能够在诚实矿工的区块之后同时发布两个区块。
如果这个伪随机函数表明攻击者赢得了出块竞赛,攻击者就能拿到出块奖励。因为 UDTB 允许一个称为“后发制人“的特殊攻击行为,因此 UDTB 的安全性会比 γ = 0.5 的 Nakamoto 共识更差。
那为什么最小哈希平局打破协议安全性那么差?因为当攻击者找到一个区块并且这个哈希值的确非常小的时候,攻击者会有大约 99% 的可能性,不论其他人的哈希是多少,他都能够赢得这个出块权。不论我先广播哪一个区块,我都能准确的预测出我能够赢得这个平局的可能性。这就允许攻击者在他足够幸运的时候能够发动扣块攻击。
当诚实的矿工找到下一个区块的时候,因为攻击者区块的哈希是足够小的,他有很高的可能性能够赢得出块权,因此他能够发布区块并且获得这个出块权。下一次当攻击者没有这么幸运的时候,他拿到的区块的哈希相对来说比较大,攻击者能够发布这个区块并直接获得奖励。
更佳链质量协议的一般性结论
下面是我们研究更佳链质量协议的一些一般性结论。
当攻击者所占算力 α > 1/4 时,没有一个协议能够达到一个理想的区块链的质量。只要攻击者的算力超过了全网算力的 1/4,它的收益就能够比它按照算力份额计算的正常收益更高。
只要攻击者的算力超过了全网算力的 1/4 ,它的收益就能够比它按照算力份额计算的正常收益更高。
对于任何一个 α 的值,在 γ = 0 的情况下,没有一个协议在安全性上表现比 Nakamoto 共识更好。
可能对于某一特定情况,某个协议在安全性上会比 Nakamoto 共识更好,但是在整体上 Nakamoto 共识在安全性上是最好的。
这是为什么?因为协议并不能区分诚实的区块和攻击者的区块。
为什么协议不能区分这些区块?
这是因为信息的不对称。攻击者是基于所有可得信息来行动的,也就是说他知道他发布了多少个区块,有多少个扣留的区块,我什么时候发布这些区块等等,攻击者是都知道的。然而诚实的矿工仅基于有限的公开信息来行动。
这又是为什么?
这是因为 PoW 的安全假设较弱。他们试图异步操作,规定所有的矿工只对非常有限的公开信息采取行动/进行操作。
那么现在我们来针对 Nakamoto 共识、水果链、奖励分配(Reward-Splitting,RS)协议、和子链来分析一下他们攻击抗性,首先是激励相容性。
其中奖励分配协议(执行)表现最好,因为惩罚总是激励正确行为的最有效方式。子链表现最差。
水果链表现有时比 Nakamoto 共识好,有时更糟。子链允许攻击者使用无价值的弱区块来使诚实的区块失效。如果所有东西都是有价值的,那么攻击者扣留区块则是有风险的。但是弱区块本身毫无价值,攻击者可以扣留这个弱区块,而不会有失去区块奖励的风险。既然无风险,那么为什么不尝试更大胆的扣留区块的行为?
更多的弱区块,协议行为越糟糕。所以更多的弱区块实际上使事情变得更糟。最好的情况就是不去使用弱区块。
当水果链的超时值小的时候,它的表现比 Nakamoto 共识差。攻击者可以使用无用的区块使他的水果失效。这也有类似的问题出现,因为区块在水果链中没有任何奖励,所以攻击者没有发布区块的动机,因为扣留区块也并无风险,结果是攻击者可以尝试更大胆的扣留区块行为。
结果是攻击者可以尝试更大胆的持有行为。
如果有更多的水果,那么情况会稍微好一点。有一个著名的 Newton-Pepys 问题,它是说一个概率问题,即
A. 6 个正常的骰子独立投掷,至少出现 1 个 6
B. 12 个正常的骰子独立投掷,至少出现 2 个 6
如果你掷 6 次骰子,得到 1 个 6 的概率比你掷 12 次骰子得到 2 个 6 的概率要大。
在水果链中有四种挖矿产品:诚实水果,诚实区块,攻击水果,攻击区块。
我们可以将「攻击者比诚实矿工拥有 1 个超时区块」——即攻击者可以成功地孤立一些水果——看作是一个条件事件。此事件完全独立于水果生成(fruit generation),因为它仅考虑区块。我们可以把它作为 Newton-Pepy's 问题中的条件去看待——因为它是独立的,所以我们可以直接把它扔掉。但当条件满足时,如果水果较少,则“攻击者有更多水果”的概率非常低。
更多的水果意味着更多的攻击者水果。因为攻击者是少数派,如果水果的总数更多,这意味着攻击者的水果的总占比会比实际上多一些。这里用赌博来做类比更好理解,因为我们有更多的水果,这意味着当攻击者有更多的水果, 那么他就会更少参与赌博。 人们更愿意在没有什么可失去的情况下赌博, 但如果有更多的资本可能会失去, 他就不想赌, 这意味着更多的水果稍微有助于提高激励相容性。
接下来在攻击抵抗性中我们分析攻击「作恶收益」,这个指标是越小越好的,如图所示,奖励分配协议优于 Nakamoto 共识,优于水果链,优于子链。
我们分析了另一个有趣的衡量方法,称为「作恶赏金」。我们定义其为最低双花奖励,来研究激励偏差。(也就是说,在双花攻击的奖励大于作恶赏金时,攻击者才有动力作恶)。( 图中右下角的表格,分别是 Nakamoto 共识和奖励分配协议在区块确认数 3 或 6 , α (攻击者算力占比在 0.1 ~ 0.4 的情况下,计算出来的作恶赏金)。
通过计算各个协议的「作恶赏金」可以发现,基本上可以零成本破坏水果链和子链,甚至可以尝试无奖励双花,因为毫无风险。
我们可以看到,随着交易确认次数的增加,对于一个弱攻击者,作恶赏金的增长几乎呈指数增长。这意味着更多的交易确认确实有助于抵抗双花,但是对于强攻击者来说效果就不那么明显了。
对于抗审查能力, 我们计算所有的数字和排名如下:
对于小 α,也就是攻击者算力占比较低的情况下, 水果链是最好的, 然后是 Nakamoto 共识, 再然后是奖励分配协议和子链。
对于大 α,也就是攻击者算力占比较高的情况下,奖励分配协议变成了最好的, 然后是水果链, Nakamoto 共识, 和子链。
显而易见的是,对于水果链来说, 如果你想使其他块无效, 要比其他协议要困难得多, 因为它们是在多个条件下获得奖励, 即使你是孤块也是如此。
为什么当 α 足够大的时候, 也就是攻击者算力占比较高的时候,奖励分配协议会比水果链更好呢?因为在水果链上, 间隔被定义为主区块和指针块之间的区块高度差。而在奖励分配协议中, 间隔被定义为主区块和区块本身之间的区块高度差。
因此在水果链中,若攻击者在长期的出块竞争中都获胜了,那么诚实的水果的奖励都会被拿走因为他们的指针块都被孤立了。也就是说如果你把他们的指针都孤立了,那么对他们来说就玩完了。然而在奖励分发协议中,最后的几个诚实的区块还是能够获得一些奖励。如果想要让诚实矿工失去所有奖励,将他们的指针孤立是不够的,你需要将大量连续的区块孤立起来才行。(这给攻击者增加了阻碍)。
这些图片能够说明这些问题。
在水果链中,如果你孤立了指针,那么你能够安心地获得所有的奖励。然而在奖励分配协议中,即使你在出块竞争中长期孤立了这些区块,但是这些区块还是会指向回主链。因为关键关系并没有考虑进去,这个区块仍会分走攻击者一半的出块奖励,这让它更能抵抗审查攻击。(因为就算被审查,诚实矿工还是能获得一部分奖励。)
抵抗攻击协议的通用结论
下面谈一下研究中对于抵抗攻击协议的一些通用结论。
合理的设置更长的区块确认时间和更大的带宽会增加安全性。
有一个两难困境,我们称为“奖励坏人,惩罚好人”的机制。这对于大家来有点颠覆对协议奖励的认知。因为在这里即使你分叉你仍然能够获得出块奖励,你分叉是没有风险的。所以这反而激励了攻击者去分叉和发动双花攻击。
在惩罚性协议中,因为审查攻击者不在乎他们自己的出块奖励,你的惩罚规则反而给攻击者另一个工具,来让诚实的矿工放弃出块奖励。
而对于幸运奖励协议,如果你不打破信息不对称,那么幸运并不意味着好。有时候幸运的块反而是坏的块,让事情变得更糟。
结论就是,想要解决所有的攻击,我们需要在底层规则中超越奖励。(奖励规则并不能很好解决攻击的问题)
具体怎么做?我提出一些想法和大家讨论一下。
我们不应该设计一个太复杂、太难分析的协议。我们需要设计一个设计者能够分析的协议。简单就是好的,复杂是安全的敌人。
仅针对单一攻击策略的安全性分析是很危险的。对于很多协议来说,它们的设计者经过模拟说他们的协议能够抵抗某种特定的攻击方式,但是这样的协议却启发了攻击者去研究其他的攻击策略。仅针对单一攻击动机的安全性分析也是很危险的。
攻击者可能会着眼于短期利益,长期利益或者损害其他矿工的利益。为了抵抗某一种攻击,你就可能启发了攻击者基于另一个目标发动另一种形式的攻击。在你的模型中你需要考虑到所有不同动机的攻击者。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。