以太坊经典被51%攻击之后, 国外大神用矿池让攻击者付出代价

2019-03-11 09:48 来源:区块链大本营 阅读:6707
众所周知,在区块链中,只有大部分人受利益(挖矿奖励等)的驱动表现出诚实行为整个区块链才能正常运行,但如果诚实行为获益低于欺骗行为,就会有人铤而走险,如果铤而走险的人占据大多数,整个区块链就会出现各种各样的问题,最典型的莫过于 51% 算力攻击。
众所周知,在区块链中,只有大部分人受利益(挖矿奖励等)的驱动表现出诚实行为整个区块链才能正常运行,但如果诚实行为获益低于欺骗行为,就会有人铤而走险,如果铤而走险的人占据大多数,整个区块链就会出现各种各样的问题,最典型的莫过于 51% 算力攻击。

那么问题来了,去中心化实现了权力的下放,而下放后权力又该如何制衡保证不作恶?

国外大神Tomaz Kariz受到矿池的启发,提出在选择区块链时将区块链中的“诸侯”矿池作为一个影响因素,引入区块链评分机制以及惩罚机制,奖惩结合从而让51%攻击的成本更高。

那么,矿池与区块链的选择如何结合?效果又会怎样?让我们跟着大神一探究竟!

前段时间,以太坊经典( ETC )区块链遭受了51%算力攻击,这引起了我深深的思考。

从理论上来说,我认为 51% 算力攻击并不是区块链网络设计的败笔,但我们是否有办法让这些 51% 算力攻击的攻击者付出更昂贵的代价?

当一个区块链节点客户端发现同时存在多个区块链时,它必须决定选择哪个区块链,这时节点客户端会分别计算每个区块链的评分 chainScore ,然后选择分数最高的区块链。

在PoW共识的区块链中,选择区块链的规则通常被称为“最长链规则”,其中区块链的评分 chainScore 等于该区块链上完成工作量的总和。这种根据评分来选择区块链的好处在于它是完全客观的。

一个主观评分的例子是,区块链节点客户端对区块链的打分标准不仅根据在该区块链上完成了多少工作量,还考虑到了如果切换到该区块链时将从本地维护的区块链中删除多少个区块,即对那些可能需要你更改本地维护区块链的区块链带有偏见。

11

基于将从本地维护区块链中删除的区块数量的主观区块链评分

另一个主观区块链选择规则的例子是照常计算区块链评分 chainScore ,但只有在切换到它需要从本地区块链中删除的区块数不超过 20 个时才切换到这个具有更高评分的区块链(该规则通常被称为最大化重组覆盖,max reorg cap )。

这个规则不仅会出现“新节点问题”(如上图所示),而且即使所有节点都运行着相同版本的客户端程序,它也可能会导致硬分叉。

所以我们要避免主观地对区块链进行评分,因为这样做我们的区块链选择逻辑就会很难解释,并且即使每个客户端节点都遵循相同的规则也可能会导致硬分叉

区块链选择规则

以太坊经典使用的区块链选择规则是选择完成工作量最多的区块链。假设一个名叫 Bob 的以太坊经典客户端正在第一次连接以太坊经典网络,Bob 必须在多个区块链之间做出选择,不过这并不是问题,他所要做的就是计算每个区块链上完成了多少工作量并选择完成工作量最多的区块链。

即使我们有任意多 Bob 这样的新入网以太坊经典客户端,对每个区块链它们都会计算出完全相同的评分 chainScore 。

在区块链系统中给定 N 个节点,这 N 个节点构成一个完全图(每个节点都连接到其他所有节点),区块链选择规则应具有以下属性:

每个节点都应将同一个区块链视为最佳选择。

区块链选择规则还应为区块链  C 提供相同的评分 chainScore ,不论任意时间点以及任意高度 H ,这意味着评分 chainScore 应该仅取决我们正在评估的区块链上的数据。

这些属性确保 Bob 和长寿命节点就需要追随的区块链达成一致,并使它们随时间的推移逐渐收敛到同一个区块链上。

需要注意的是,正如我们上面提到的,当下以太坊经典中评分chainScore最大的区块链是那些完成工作量最多的区块链。

区块链挖矿

对于单独挖矿的矿工而言,除非他掌控相当大的哈希算力,否则他不太可能会挖出区块。

矿池就是为了解决这个问题而被发明的,矿池借鉴了“众人拾柴火焰高”的思想,大量原本单独挖矿的矿工聚在一起抱团取暖,共同挖矿,共同分享收益,所以即使某些矿工可能都没有挖出一个区块,但始终能获得稳定的工作回报。

假设区块链网络中有多个矿池,它们总共占据网络中的大部分哈希算力。

每一个区块都包含一个被叫做 coinbase / etherbase 的数值,它用来指代挖出该区块的矿工,表示应该接收挖矿奖励的地址。

大多数区块都是由矿池开采的,每个矿池通常都会指定一个用来接收挖矿奖励的地址。

下面是以太坊经典区块链上从高度 7283680 到高度 7283695 开采出的 16 个连续区块,以及它们接收挖矿奖励的矿工地址:

12

以太坊经典区块链上高度 7283680 到高度 7283695 的区块,以及它们接收挖矿奖励的矿工地址

正如预期的那样,绝大多数区块都是由以太坊经典网络中运营的矿池开采出的,其中矿池 Ethermine 开采了 5 个区块,矿池 MiningPoolHub 开采了 4 个区块,矿池 NanoPool 开采了 3 个区块。

在灰色的区块中挖矿奖励被发送到我不知道所有者是谁的地址,但它们很可能也是矿池。

这似乎给了我们一点启发……

利用矿池降低51%攻击?真的!

假设我们有能连续挖出新区块的矿池,我们应该能经常看到区块的产出。当攻击者进行 51% 算力攻击时,他通常会离线连续挖掘 N 个区块,然后发布一个比当前共识链更长的区块链,从而导致当前共识链的重组。

攻击者开采的区块通常不使用我们过去观察到的矿池的地址。

如果对矿池挖矿的前后不一致性进行惩罚,我们就可以在共识规则大致不变的前提下大大增加攻击者发动攻击的成本,从而保护我们免受 51% 算力攻击。

在这里,我们需要先明确一下 51% 算力攻击是如何发生的:

  • 使用算力租赁服务(例如 NiceHash )来执行攻击(假设 NiceHash 并不是矿池)。

  • 一些矿池暗中勾结执行攻击。

  • 上面两者的结合:矿池暗中勾结+算力租赁服务执行攻击。

  • 使用专用集成电路(ASIC)执行攻击。

矿池前后一致性指数

区块链选择规则不仅可以考虑已完成的工作量,还可以考虑矿池的前后一致性。我们可以通过将 chainScore 的定义更改为以下公式来加入矿池的影响:

chainScore = parentChain.score +block.PoW_score * PCI

其中 parentChain.score 为前序区块链的评分,block.PoW_score 为该区块链所做的工作量, PCI(矿池前后一致性指数,Pools Consistency Index)为介于0和1之间的值。

这里的 PCI 表示矿池的前后一致性。让我们来看一个使用矿池信息来评估区块链“健康”程度的一个实现。

13

在最后 3000 个区块上使用滑动窗口来衡量工作量前后一致性的示例。

chainScore 函数的代码实现如下所示:

14

滑动窗口矿池前后一致性增量的参考实现

当网络中多个区块链共存时,我们认为最可能成为共识链的会是那些矿工在持续挖矿的区块链。这种说法并不是百分百正确,但对于大多数情况都是如此,除非出现掌握超过 51% 哈希算力的矿池叛变的情况

这种结合矿池信息的方法可以预测区块链的未来是什么样的,并惩罚那些恶意行为者,而这些在过去是不可能实现的。当我们对矿池的前后不一致设置非常高的惩罚时,会出现以下两种情况:

  1. 网络中仅存在一个区块链,一些矿池停止挖矿。由于对于所有的矿工而言,他们的 PoW 值都会相应的降低,所以这对矿工来说无关紧要,因为区块链评分 chainScore 很低并不会影响他们的挖矿收益。

  2. 网络中多个区块链共存,在这种情况下,矿池前后一致性较低的区块链(通常是 51% 算力攻击)将受到惩罚。

那么,这种方法在上面所提到的几种51%算力攻击面前效果如何?

使用算力租赁服务(例如 NiceHash )来执行攻击

由于其他矿池不会在他的区块链上继续挖矿,随着时间的推移攻击者会受到矿池前后不一致惩罚。

两个共掌握全网 60% 哈希算力的矿池联合执行攻击

为了解决这个问题,我们不仅需要考虑矿池的哈希算力,还需要考虑在区块链上挖矿的矿池的数量。如果我们有大于 10 个具有大致相同哈希算力的矿池,那么这个问题就会变得更容易解决。

两者的结合

例如一个掌握全网 40% 哈希算力的矿池又租用了全网 30% 的哈希算力执行攻击。

随着时间的推移攻击者会受到矿池前后不一致惩罚。值得注意的是,即使攻击者将租用哈希算力挖出区块的矿工地址设置为原本矿池的地址也无济于事,因为我们会查看已挖出区块过去的数据。

使用专用集成电路(ASIC)执行攻击

这看起来像是长期的 51% 算力攻击。攻击者会随着时间的推移受到矿池前后不一致惩罚,但如果他能继续坚持下去,他就可能会成为我们参考的“过去的矿池”。在这种情况下,问题演变成了如果一个矿池叛变。

虽然这种方法并没有解决 51% 算力攻击,但它能使攻击者的攻击成本变得更加高昂,因为攻击者会在很长一段时间内持续受到惩罚(很多个区块时间)。

如果几个矿池突然停止挖矿,监控系统可以发觉这种情况,社区会有一些时间来做出反应,例如开始自己挖矿(但由于惩罚机制的存在他们必须小心)或者只是在发生这种情况时等待更多后续区块的确认。

基于这些情况,我们先做了以下假设:

  • 将矿池作为网络的一部分从而加强区块链的安全性。当然了如果一个矿池可以通过各种手段掌握全网 51% 的哈希算力,那么他还是可以执行 51% 算力攻击,不过这并不是我们引起的新问题,就我目前的了解,业界还没有针对这种问题的解决方案。

  • 一旦矿池 A 挖出了一个区块,所有接下来的 29 个区块都将获得矿池 A 的前后一致性奖励,无论这些区块是由谁挖出的,因此,与其他人相比,矿池 A 并没有获得任何优势。

  • “墙头草”矿工仍然受欢迎,但如果他们突然开始挖出大量区块,他们可能会受到惩罚。如果他们有些前后一致性,我们不会对他们进行大量惩罚,他们可以轻松地挖出新的区块。有人可能会说这样会降低安全性,但我的预感是,你从获得矿池前后一致性指数获得的收益远远超过没有“墙头草”矿工而失去的收入。

  • 只要每个新区块保证为区块链添加一些积极价值,挖矿就可以在没有矿池存在的情况下继续运行。

  • 由于独自挖矿的矿工很难开采出一个区块,因此惩罚对他们的影响基本上为零。我认为他们中的大多数人都希望参与到矿池之中。

  • 新来的更大的矿池将不得不逐渐加入区块链中,否则它们会因为矿池挖矿前后不一致导致其挖出的区块受到惩罚。

  • 矿池前后一致性公式( PCI )以及区块链评分 chainScore 可以有多种定义方法。

  • 对于具有较低区块间隔时间的区块链,这种方法可以更好地工作,因为同样的一段时间里这种区块链可以获得更多有关矿池一致性的信息。

接下来,我们需要用博弈论的方法来对这个假设进行验证。需要注意的是,可以考虑不调整 PoW 的值,而是使用 PCI 作为附加值来保持 PoW 一致。

滑动窗口矿池前后一致性增量测试的结果

我通过模拟出一个理想的区块链从而在一系列的连续区块中检测矿池前后一致性的想法。

虽然结果显示,使用滑动窗口矿池前后一致性增量与最长区块链机制(当前被大部分区块链采用)相比, 51% 算力攻击的成本会更加昂贵,但应该注意的是,由于测试过程中可能存在瑕疵,代码中可能存在错误,或者是模拟出的环境过于理想/简单/错误,这样的结论可能会存在问题,因此离在区块链上实际使用可能还有很长的路要走。

在这次实验中我创建了大约 5500 个区块(过程持续了 5500 * 14 秒),攻击者在高度为4850的区块处进行分叉。默认情况下,区块的间隔时间约为 14 秒,在代码上我做了很多的简化,并没有完全符合在当前区块链中使用的逻辑(例如,区块时间的计算不一样,没有叔块)。

尽管存在差异,但我认为这个实验足以检验我们的想法。实验结果如下所示,结果中 Ratio (比值)表示主链和攻击者在区块高度 4850 处生成的分叉链之间区块链评分 chainScore 的比值,如果这个比值低于 1.0 意味着主链的区块链评分 chainScore 的总和低于攻击者分叉链的总和。

我们还可以从图中看到两个区块链达到的高度。

15

实验结果

从图中我们可以看出,较传统的最长链方法,滑动窗口矿池前后一致性增量方法更容易选中主链,不过即使这种方法获胜很多,在真实的区块链环境中这种方法的效用还有待检验。

从上面这个结果表中我们可以看到,在所有的情况下分叉链最终都挖出了更多的区块,但在滑动窗口评分方法中分叉链的评分 chainScore 从未超过主链(这并不完全正确,因为它可能在开始时获得了更高的分数,但在这次测试中,分叉链最少领先主链 30 个区块,并且评分也更高)。

如果攻击者能够坚持足够长的时间,他就有可能成为“矿池历史”的一部分,随着时间的推移分叉链的评分chainScore 会超过主链。

当然了,这次实验代码除了我以外还没有任何人检查过。如果你发现了代码中存在的问题,请向我提交。

已知的攻击向量

51%算力攻击

尽管如此,攻击的成本可能要贵得多。

矿池冒充攻击

攻击者可以挖出更长的区块链并在其中插入其他矿池的矿工地址,从而将攻击者挖出区块的矿池分布调整为与攻击前大致相同的分布。

为了防范这种情况,我们需要为矿工提供某种形式的身份证明。这可以通过在区块头中添加名为 minerSig (矿工签名)的身份验证信息来解决。 minerSig是使用矿工私钥签名的前序区块哈希值 parentHash 和该区块的随机数 nonce ,为了使区块有效,我们需要检查这个验证。

攻击者加入主网络

攻击者可以加入主网络并挖出一些区块,以避免以后被识别出突然大量挖矿。这种情况可以参考如果一个矿池叛变。

改进措施:摆脱矿池假设

在协议级别上实施矿池机制可以保证矿池确实存在。但即使我们没有矿池,协议也能够针对这种情况进行相应的优化。

就比如说,我们可以鼓励矿工聚集起来,组建一定数量的矿池,具体的方法就是根据每个矿池的哈希算力给予挖矿奖励,从而汇聚成总共 N 个矿池。假如我们想要大约 20 个矿池,那么对于占据全网哈希算力 5% 的矿池,挖矿奖励最高(4 ETC)。

如果矿池的算力多于/少于这个值,那么矿池获得较低的奖励,剩余的奖励将根据其他矿池的哈希算力分配给他们。由于我们最终为每个区块创建了相同数量的挖矿奖励(在这种情况下为 4 ),因此它并不会改变货币政策中定义的流通中的总货币。激励措施需要正确完成,以便矿工按照我们的想法聚集。

这里要提醒开发者以下,即使一个人拥有 5 个矿池,每个矿池都掌握全网 5% 的哈希算力,这也没有问题,因为它增强了矿池的前后一致性,从而为我们提供了额外的安全性。

如果已经存在矿池,就比如说当下的以太坊经典,那么如果需要,也可以在稍后阶段实施。

其他可能的矿池前后一致性定义

矿池前后一致性公式可以执行以下操作。

  • 基于矿池数据和相似分析的线性回归。

  • 惩罚哈希算力的增长(无论是对单独的矿工还是对整个网络)。对网络惩罚的想法是,如果没有恶意区块链,那么对每个人的惩罚都是相同的,如果存在一个想要抢占先机的恶意区块链,那么它将受到更多的惩罚。由于区块时间戳可能是伪造的,因此仅从区块链数据中很难给出这样的客观分数。

  • 如果独自挖矿的矿工或矿池在给定的区块窗口内过快地增加挖掘区块的比值,则给他们“超速罚单”。

  • 对矿工的数据进行统计分析。

协议级矿池的矿池前后一致性示例

假设我们有一个区块链,它具有内置的激励机制,用于让每个矿池的哈希算力收敛到全网的 1% ,从而形成总共约 100 个矿池。

为了使矿池能够对矿池前后一致性指数做出贡献,它需要在最后 3000 个区块上以大约 1% 的哈希算力进行一致地挖掘。矿池前后一致性指数将是通过此标准的矿池的比值。

比如说,如果最后 100 个区块由 50 个不同的矿池挖出,则矿池前后一致性指数将等于 0.5 ,因此贡献 0.5 难度。

在这种情况下,如果攻击者想要进行攻击,他需要挖最后 3000 个具有不同矿工地址的区块中的 50% 才能开始获得与主链相同的矿池前后一致性指数。除此之外,我们还可以对矿池发“超速罚单”。

假设我们有 100 个具有相同哈希算力的矿池,我们也可以做一些统计分析。所有矿池都具有相同的“被选择”的概率,这意味着我们可以计算最后 100 个区块状态的可能性,假设它们是随机选择的,那么我们可以对结果不太可能发生的事件进行惩罚。

写在最后

说了这么多,我并不是说人们应该改变他们的共识算法,而是应该有一个很好的理由来推进共识算法的改进,并且在考虑任何变动之前都应该很好地研究替代方案。

这只是我对共识算法改进的一些思考,我的想法能降低网络51%算力攻击发生的可能性。

无论如何,矿池将成为区块链网络的一部分,所以为什么不物尽其用来为区块链增加安全性呢?

我们仍然可以将这种方法看作一种最长链机制,不同之处在于我们改变了测量区块链长度的方式。我更青睐于人们使用更通用的描述,例如最大区块链评分规则。

希望这篇文章能对你有帮助。关于利用矿池减少51%攻击的尝试,你有什么想法,赶快留言告诉营长吧~

作者 | phyro — Tomaz Kariz

译者 | Guoxi

出品 | 区块链大本营(blockchain_camp)

声明:此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网站所提供的信息,只供参考之用。

点击阅读全文