精通比特币 – 第8章 区块链分叉、矿池、共识攻击

8.10 区块链的组装与选择

比特币去中心化的共识机制的最后一步是将区块集合至有最大工作量证明的链中。一旦一个节点验证了一个新的区块,它将尝试将新的区块连接到到现存的区块链,将它们组装起来。
节点维护三种区块:第一种是连接到主链上的,第二种是从主链上产生分支的(备用链),最后一种是在已知链中没有找到已知父区块的。在验证过程中,一旦发现有不符合标准的地方,验证就会失败,这样区块会被节点拒绝,所以也不会加入到任何一条链中。
任何时候,主链都是累计了最多难度的区块链。在一般情况下,主链也是包含最多区块的那个链,除非有两个等长的链并且其中一个有更多的工作量证明。主链也会有一些分支,这些分支中的区块与主链上的区块互为“兄弟”区块。这些区块是有效的,但不是主链的一部分。 保留这些分支的目的是如果在未来的某个时刻它们中的一个延长了并在难度值上超过了主链,那么后续的区块就会引用它们。在“8.10.1 区块链分叉”,我们将会看到在同样的区块高度,几乎同时挖出区块时,候选链是如何产生的。
当节点接收到新区块,它会尝试将这个区块插入到现有区块链中。节点会看一下这个区块的“previous block hash”字段,这个字段是该区块对其父区块的引用。同时,新的节点将尝试在已存在的区块链中找出这个父区块。大多数情况下,父区块是主块链的“顶点”,这就意味着这个新的区块延长了主链。举个例子,一个新的区块——区块277,316引用了它的父区块——区块277,315。大部分收到了区块277,316的节点将区块277,315作为主链的顶点,连接这个新区块并延长区块链。
有时候,新区块所延长的区块链并不是主链,这一点我们将在“8.10.1 区块链分叉”中看到。在这种情况下,节点将新的区块添加到备用链,同时比较备用链与主链的难度。如果备用链比主链积累了更多的难度,节点将收敛于备用链,意味着节点将选择备用链作为其新的主链,而之前那个老的主链则成为了备用链。如果节点是一个矿工,它将开始构造新的区块,来延长这个更新更长的区块链。
如果节点收到了一个有效的区块,而在现有的区块链中却未找到它的父区块,那么这个区块被认为是“孤块”。孤块会被保存在孤块池中,直到它们的父区块被节点收到。一旦收到了父区块并且将其连接到现有区块链上,节点就会将孤块从孤块池中取出,并且连接到它的父区块,让它作为区块链的一部分。当两个区块在很短的时间间隔内被挖出来,节点有可能会以相反的顺序接收到它们,这个时候孤块现象就会出现。
选择了最大难度的区块链后,所有的节点最终在全网范围内达成共识。随着更多的工作量证明被添加到链中,链的暂时性差异最终会得到解决。挖矿节点通过“投票”来选择它们想要延长的区块链,当它们挖出一个新块并且延长了一个链,新块本身就代表它们的投票。
相互竞争的链之间是存在差异的,下节我们将看到节点是怎样通过独立选择最长难度链来解决这种差异的。

8.10.1 区块链分叉

因为区块链是去中心化的数据结构,所以不同副本之间不能总是保持一致。区块有可能在不同时间到达不同节点,导致节点有不同的区块链视角。解决的办法是,每一个节点总是选择并尝试延长代表累计了最大工作量证明的区块链,也就是最长的或最大累计难度的链。节点通过将记录在每个区块中的难度加总起来,得到建立这个链所要付出的工作量证明的总量。只要所有的节点选择最长累计难度的区块链,整个比特币网络最终会收敛到一致的状态。分叉即在不同区块链间发生的临时差异,当更多的区块添加到了某个分叉中,这个问题便会迎刃而解。
在下面的图例中,我们可以了解网络中发生分叉的过程。图例代表简单的全球比特币网络,在真实的情况下,比特币网络的拓扑结构不是基于地理位置组织起来的。相反,在同一个网络中相互连接的节点,可能在地理位置上相距遥远,我们采用基于地理的拓扑是为了更加简洁地描述分叉。在真实比特币网络里,节点间的距离按“跳”而不是按照真实位置来衡量。为了便于描述,不同的区块被标示为不同的颜色,传播这些区块的节点网络也被标上颜色。
在第一张图(图8-2)中,网络有一个统一的区块链视角,以蓝色区块为主链的“顶点”。


图8-2 形象化的区块链分叉事件——分叉之前

当有两个候选区块同时想要延长最长区块链时,分叉事件就会发生。正常情况下,分叉发生在两名矿工在较短的时间内,各自都算得了工作量证明解的时候。两个矿工在各自的候选区块一发现解,便立即传播自己的“获胜”区块到网络中,先是传播给邻近的节点而后传播到整个网络。每个收到有效区块的节点都会将其并入并延长区块链。如果该节点在随后又收到了另一个候选区块,而这个区块又拥有同样父区块,那么节点会将这个区块连接到候选链上。其结果是,一些节点收到了一个候选区块,而另一些节点收到了另一个候选区块,这时两个不同版本的区块链就出现了。
在图8-3中,我们看到两个矿工几乎同时挖到了两个不同的区块。这两个区块是顶点区块——蓝色区块的子区块,可以延长这个区块链。为了便于跟踪这个分叉事件,我们设定有一个被标记为红色的、来自加拿大的区块,还有一个被标记为绿色的、来自澳大利亚的区块。


图8-3 形象化的区块链分叉事件:同时发现两个区块

假设有这样一种情况,一个在加拿大的矿工发现了“红色”区块的工作量证明解,在“蓝色”的父区块上延长了块链。几乎同一时刻,一个澳大利亚的矿工找到了“绿色”区块的解,也延长了“蓝色”区块。那么现在我们就有了两个区块:一个是源于加拿大的“红色”区块;另一个是源于澳大利亚的“绿色”。这两个区块都是有效的,均包含有效的工作量证明解并延长同一个父区块。这个两个区块可能包含了几乎相同的交易,只是在交易的排序上有些许不同。
当这个两个区块传播时,一些节点首先收到“红色”区块,一些节点收到“绿色”区块。如图8-4所示,比特币网络上的节点对于区块链的顶点产生了分歧,一派以红色区块为顶点,而另一派以绿色区块为顶点。


图8-4 形象化的区块链分叉事件:两个区块的传播将网络分裂了

从那时起,比特币网络中邻近(网络拓扑上的邻近,而非地理上的)加拿大的节点会首先收到“红色”区块,并建立一个最大累计难度的区块,“红色”区块为这个链的最后一个区块(蓝色-红色),同时忽略晚一些到达的“绿色”区块。相比之下,离澳大利亚更近的节点会判定“绿色”区块胜出,并以它为最后一个区块来延长区块链(蓝色-绿色),忽略晚几秒到达的“红色”区块。那些首先收到“红色”区块的节点,会即刻以这个区块为父区块来产生新的候选区块,并尝试寻找这个候选区块的工作量证明解。同样地,接受“绿色”区块的节点会以这个区块为链的顶点开始生成新块,延长这个链。
分叉问题几乎总是在一个区块内就被解决了。网络中的一部分算力专注于“红色”区块为父区块,在其之上建立新的区块;另一部分算力则专注在“绿色”区块上。即便算力在这两个阵营中平均分配,也总有一个阵营抢在另一个阵营前发现工作量证明解并将其传播出去。在这个例子中我们可以打个比方,假如工作在“绿色”区块上的矿工找到了一个“粉色”区块延长了区块链(蓝色-绿色-粉色),他们会立刻传播这个新区块,整个网络会都会认为这个区块是有效的,如图8-5所示。


图8-5 形象化的区块链分叉事件:新区块延长了分支

所有在上一轮选择“绿色”区块为胜出者的节点会直接将这条链延长一个区块。然而,那些选择“红色”区块为胜出者的节点现在会看到两个链:“蓝色-绿色-粉色”和“蓝色-红色”。如图8-6所示,这些节点会根据结果将“蓝色-绿色-粉色”这条链设置为主链,将“蓝色-红色”这条链设置为备用链。这些节点接纳了新的更长的链,被迫改变了原有对区块链的观点,这就叫做链的重新共识。因为“红”区块做为父区块已经不在最长链上,导致了他们的候选区块已经成为了“孤块”,所以现在任何原本想要在“蓝色-红色”链上延长区块链的矿工都会停下来。全网将“蓝色-绿色-粉色”这条链识别为主链,“粉色”区块为这条链的最后一个区块。全部矿工立刻将他们产生的候选区块的父区块切换为“粉色”,来延长“蓝色-绿色-粉色”这条链。


图8-6 形象化的区块链分叉事件:全网在最长链上重新共识

从理论上来说,两个区块的分叉是有可能的,这种情况发生在因先前分叉而相互对立起来的矿工,又几乎同时发现了两个不同区块的解。然而,这种情况发生的几率是很低的。单区块分叉每周都会发生,而双块分叉则非常罕见。
比特币将区块间隔设计为10分钟,是在更快速的交易确认和更低的分叉概率间作出的妥协。更短的区块产生间隔会让交易清算更快地完成,也会导致更加频繁地区块链分叉。与之相对地,更长的间隔会减少分叉数量,却会导致更长的清算时间。

8.11 挖矿和算力竞赛

比特币挖矿是一个极富竞争性的行业。自从比特币存在开始,每年比特币算力都成指数增长。一些年份的增长还体现出技术的变革,比如在2010年和2011年,很多矿工开始从使用CPU升级到使用GPU,进而使用FGPA(现场可编程门阵列)挖矿。在2013年,ASIC挖矿的引入,把SHA256算法直接固化在挖矿专用的硅芯片上,引起了算力的另一次巨大飞跃。一台采用这种芯片的矿机可以提供的算力,比2010年比特币网络的整体算力还要大。
下表表示了比特币网络开始运行后最初五年的总算力:
2009
0.5 MH/秒–8 MH/秒 (16倍增长)
2010
8 MH/秒–116 GH/秒 (14,500倍增长)
2011
16 GH/秒–9 TH/秒 (562倍增长)
2012
9 TH/秒–23 TH/秒 (2.5倍增长)
2013
23 TH/秒–10 PH/秒 (450倍增长)
2014
10 PH/秒–150 PH/秒 到8月为止 (15倍增长)
在图8-7的图表中,我们可以看到近两年里,矿业和比特币的成长引起了比特币网络算力的指数增长(每秒网络总算力)。


图8-7 近两年的总算力,G次hash/秒

随着比特币挖矿算力的爆炸性增长,与之匹配的难度也相应增长。图8-8中的相对难度值显示了当前难度与最小难度(第一个块的难度)的比例。


图8-8 近两年的比特币难度值

近两年,ASIC芯片变得更加密集,特征尺寸接近芯片制造业前沿的22纳米。挖矿的利润率驱动这个行业以比通用计算更快的速度发展。目前,ASIC制造商的目标是超越通用CPU芯片制造商,设计特征尺寸为16纳米的芯片。对比特币挖矿而言,已经没有更多飞跃的空间,因为这个行业已经触及了摩尔定律的最前沿。摩尔定律指出计算能力每18个月增加一倍。尽管如此,随着更高密度的芯片和数据中心的部署竞赛,网络算力继续保持同步的指数增长。现在的竞争已经不再是比较单一芯片的能力,而是一个矿场能塞进多少芯片,并处理好散热和供电问题。

8.11.1 随机值升位方案

2012年以来,比特币挖矿发展出一个解决区块头基本结构限制的方案。在比特币的早期,矿工可以通过遍历随机数(Nonce)获得符合要求的hash来挖出一个块。难度增长后,矿工经常在尝试了40亿个值后仍然没有出块。然而,这很容易通过读取块的时间戳并计算经过的时间来解决。因为时间戳是区块头的一部分,它的变化可以让矿工用不同的随机值再次遍历。当挖矿硬件的速度达到了4GH/秒,这种方法变得越来越困难,因为随机数的取值在一秒内就被用尽了。当出现ASIC矿机并很快达到了TH/秒的hash速率后,挖矿软件为了找到有效的块,需要更多的空间来储存nonce值。可以把时间戳延后一点,但将来如果把它移动得太远,会导致区块变为无效。区块头需要一个新的“差异性”的信息来源。解决方案是使用coinbase交易作为额外的随机值来源,因为coinbase脚本可以储存2-100字节的数据,矿工们开始使用这个空间作为额外随机值的来源,允许他们去探索一个大得多的区块头值范围来找到有效的块。这个coinbase交易包含在merkle树中,这意味着任何coinbase脚本的变化将导致Merkle根的变化。8个字节的额外随机数,加上4个字节的“标准”随机数,允许矿工每秒尝试296(8后面跟28个零)种可能性而无需修改时间戳。如果未来矿工可以尝试所有的可能性,他们还可以通过修改时间戳来解决。同样,coinbase脚本中也有更多额外的空间可以为将来随机数的扩展做准备。

8.11.2 矿池

在这个激烈竞争的环境中,个体矿工独立工作(也就是solo挖矿)没有一点机会。他们找到一个区块以抵消电力和硬件成本的可能性非常小,以至于可以称得上是赌博,就像是买彩票。就算是最快的消费型ASIC也不能和那些在巨大机房里拥有数万芯片并靠近水电站的商业矿场竞争。现在矿工们合作组成矿池,汇集数以千计参与者们的算力并分享奖励。通过参加矿池,矿工们得到整体回报的一小部分,但通常每天都能得到,因而减少了不确定性。
让我们来看一个具体的例子。假设一名矿工已经购买了算力共计6,000GH/S,或6TH/S的设备,在2014年8月,它的价值大约是1万美元。该设备运行功率为3千瓦(KW),每日耗电72度,每日平均成本7或8美元。以目前的比特币难度,该矿工平均每155天或5个月可能solo出一个块。如果这个矿工确实在这个时限内挖出一个区块,奖励25比特币,如果每个比特币价格约为600美元,可以得到15,000美元的收入。这可以覆盖整个时间周期内的设备和电力成本,还剩下大约3,000美元的净利润。然而,在5个月的时间周期内能否挖出一个块主要靠矿工的运气。他有可能在五个月中得到两个块从而赚到非常大的利润。或者,他可能10个月都找不到一个块,从而遭受经济损失。更糟的是,比特币的工作证明(POW)算法的难度可能在这段时间内显著上升,按照目前算力增长的速度,这意味着矿工在设备被下一代更有效率的矿机取代之前,最多有6个月的时间取得成果。如果这个矿工加入矿池,而不是等待5个月内可能出现一次的暴利,他每周能赚取大约500-700美元。矿池的常规收入能帮他随时间摊销硬件和电力的成本,并且不用承担巨大的风险。在7到9个月后,硬件仍然会过时,风险仍然很高,但在此期间的收入至少是定期的和可靠的。
矿池通过专用挖矿协议协调成百上千的矿工。个人矿工在建立矿池账号后,设置他们的矿机连接到矿池服务器。他们的挖矿设备在挖矿时保持和矿池服务器的连接,和其他矿工同步各自的工作。这样,矿池中的矿工分享挖矿任务,之后分享奖励。
成功出块的奖励支付到矿池的比特币地址,而不是单个矿工的。一旦奖励达到一个特定的阈值,矿池服务器便会定期支付奖励到矿工的比特币地址。通常情况下,矿池服务器会为提供矿池服务收取一个百分比的费用。
参加矿池的矿工把搜寻候选区块的工作量分割,并根据他们挖矿的贡献赚取“份额”。矿池为赚取“份额”设置了一个低难度的目标,通常比比特币网络难度低1000倍以上。当矿池中有人成功挖出一块,矿池获得奖励,并和所有矿工按照他们做出贡献的“份额”数的比例分配。
矿池对任何矿工开放,无论大小、专业或业余。一个矿池的参与者中,有人只有一台小矿机,而有些人有一车库高端挖矿硬件。有人只用几十度电挖矿,也有人会用一个数据中心消耗兆瓦级的电量。矿池如何衡量每个人的贡献,既能公平分配奖励,又避免作弊的可能?答案是在设置一个较低难度的前提下,使用比特币的工作量证明算法来衡量每个矿工的贡献。因此,即使是池中最小的矿工也经常能分得奖励,这足以激励他们为矿池做出贡献。通过设置一个较低的取得份额的难度,矿池可以计量出每个矿工完成的工作量。每当矿工发现一个小于矿池难度的区块头hash,就证明了它已经完成了寻找结果所需的hash计算。更重要的是,这些为取得份额贡献而做的工作,能以一个统计学上可衡量的方法,整体寻找一个比特币网络的目标散列值。成千上万的矿工尝试较小区间的hash值,最终可以找到符合比特币网络要求的结果。
让我们回到骰子游戏的比喻。如果骰子玩家的目标是扔骰子结果都小于4(整体网络难度),一个矿池可以设置一个更容易的目标,统计有多少次池中的玩家扔出的结果小于8。当池中的玩家扔出的结果小于8(矿池份额目标),他们得到份额,但他们没有赢得游戏,因为没有完成游戏目标(小于4)。但池中的玩家会更经常的达到较容易的矿池份额目标,规律地赚取他们的份额,尽管他们没有完成更难的赢得比赛的目标。
时不时地,池中的一个成员有可能会扔出一个小于4的结果,矿池获胜。然后,收益可以在池中玩家获得的份额基础上分配。尽管目标设置为8或更少并没有赢得游戏,但是这是一个衡量玩家们扔出的点数的公平方法,同时它偶尔会产生一个小于4的结果。
同样的,一个矿池会将矿池难度设置在保证一个单独的矿工能够频繁地找到一个符合矿池难度的区块头hash来赢取份额。时不时的,某次尝试会产生一个符合比特币网络目标的区块头hash,产生一个有效块,然后整个矿池获胜。

8.11.2.1 托管矿池

大部分矿池是“托管的”,意思是有一个公司或者个人经营一个矿池服务器。矿池服务器的所有者叫矿池管理员,同时他从矿工的收入中收取一个百分比的费用。
矿池服务器运行专业软件以及协调池中矿工们活动的矿池采矿协议。矿池服务器同时也连接到一个或更多比特币完全节点并直接访问一个块链数据库的完整副本。这使得矿池服务器可以代替矿池中的矿工验证区块和交易,缓解他们运行一个完整节点的负担。对于池中的矿工,这是一个重要的考量,因为一个完整节点要求一个拥有最少15-20GB的永久储存空间(磁盘)和最少2GB内存(RAM)的专用计算机。此外,运行一个完整节点的比特币软件需要监控、维护和频繁升级。由于缺乏维护或资源导致的任何宕机都会伤害到矿工的利润。对于很多矿工来说,不需要跑一个完整节点就能采矿,也是加入托管矿池的一大好处。
矿工连接到矿池服务器使用一个采矿协议比如Stratum (STM)或者 GetBlockTemplate (GBT)。一个旧标准GetWork (GWK) 自从2012年底已经基本上过时了,因为它不支持在hash速度超过4GH/S时采矿。STM和GBT协议都创建包含候选区块头模板的区块模板。矿池服务器通过聚集交易,添加coinbase交易(和额外的随机值空间),计算MERKLE根,并连接到上一个块hash来建立一个候选区块。这个候选区块的头部作为模板分发给每个矿工。矿工用这个区块模板在低于比特币网络的难度下采矿,并发送成功的结果返回矿池服务器赚取份额。

8.11.2.2 P2P矿池

托管矿池存在管理人作弊的可能,管理人可以利用矿池进行双重支付或使区块无效。(参见“8.12 共识攻击”) 此外,中心化的矿池服务器代表着单点故障。如果因为拒绝服务攻击服务器挂了或者被减慢,池中矿工就不能采矿。在2011年,为了解决由中心化造成的这些问题,提出和实施了一个新的矿池挖矿方法。P2Pool是一个点对点的矿池,没有中心管理人。
P2Pool通过将矿池服务器的功能去中心化,实现一个并行的类似区块链的系统,名叫份额链。一个份额链是一个难度低于比特币区块链的区块链系统。份额链允许池中矿工在一个去中心化的池中合作,以每30秒一个份额区块的速度在份额链上采矿,并获得份额。份额链上的区块记录了贡献工作的矿工的份额,并且继承了之前份额区块上的份额记录。当一个份额区块上还实现了比特币网络的难度目标时,它将被广播并包含到比特币的区块链上,并奖励所有已经在份额链区块中取得份额的池中矿工。本质上说,比起用一个矿池服务器记录矿工的份额和奖励,份额链允许所有矿工通过类似比特币区块链系统的去中心化的共识机制跟踪所有份额。
P2Pool采矿方式比在矿池中采矿要复杂的多,因为它要求矿工运行空间、内存、带宽充足的专用计算机来支持一个比特币的完整节点和P2Pool节点软件。P2Pool矿工连接他们的采矿硬件到本地P2Pool节点,它通过发送区块模板到矿机来模拟一个矿池服务器的功能。在P2Pool中,单独的矿工创建自己的候选区块,聚合交易,非常类似于solo矿工,但是他们在份额链上合作采矿。P2Pool是一种比单独挖矿有更细粒度收入优势的混合方法。但是不需要像托管矿池那样给管理人太多权力。
最近,在集中式矿池已经接近产生51%攻击的担忧下,P2Pool的份额增长显著。(参见参见“8.12 共识攻击”)P2Pool协议的进一步发展有望去除对完整节点的需要,这将使去中心化采矿更容易。

8.12 共识攻击

比特币的共识机制指的是,被矿工(或矿池)试图使用自己的算力实行欺骗或破坏的难度很大,至少理论上是这样。就像我们前面讲的,比特币的共识机制依赖于这样一个前提,那就是绝大多数的矿工,出于自己利益最大化的考虑,都会通过诚实地挖矿来维持整个比特币系统。然而,当一个或者一群拥有了整个系统中大量算力的矿工出现之后,他们就可以通过攻击比特币的共识机制来达到破坏比特币网络的安全性和可靠性的目的。
值得注意的是,共识攻击只能影响整个区块链未来的共识,或者说,最多能影响不久的过去几个区块的共识(最多影响过去10个块)。而且随着时间的推移,整个比特币块链被篡改的可能性越来越低。理论上,一个区块链分叉可以变得很长,但实际上,要想实现一个非常长的区块链分叉需要的算力非常非常大,随着整个比特币区块链逐渐增长,过去的区块基本可以认为是无法被分叉篡改的。同时,共识攻击也不会影响用户的私钥以及加密算法(ECDSA)。共识攻击也不能从其他的钱包那里偷到比特币、不签名地支付比特币、重新分配比特币、改变过去的交易或者改变比特币持有纪录。共识攻击能够造成的唯一影响是影响最近的区块(最多10个)并且通过拒绝服务来影响未来区块的生成。
共识攻击的一个典型场景就是“51%攻击”。想象这么一个场景,一群矿工控制了整个比特币网络51%的算力,他们联合起来打算攻击整个比特币系统。由于这群矿工可以生成绝大多数的块,他们就可以通过故意制造块链分叉来实现“双重支付”或者通过拒绝服务的方式来阻止特定的交易或者攻击特定的钱包地址。区块链分叉/双重支付攻击指的是攻击者通过不承认最近的某个交易,并在这个交易之前重构新的块,从而生成新的分叉,继而实现双重支付。有了充足算力的保证,一个攻击者可以一次性篡改最近的6个或者更多的区块,从而使得这些区块包含的本应无法篡改的交易消失。值得注意的是,双重支付只能在攻击者拥有的钱包所发生的交易上进行,因为只有钱包的拥有者才能生成一个合法的签名用于双重支付交易。攻击者只能在自己的交易上进行双重支付攻击,但当这笔交易对应的是不可逆转的购买行为的时候,这种攻击就是有利可图的。
让我们看一个“51%攻击”的实际案例吧。在第1章我们讲到,Alice 和 Bob 之间使用比特币完成了一杯咖啡的交易。咖啡店老板 Bob 愿意在 Alice 给自己的转账交易确认数为零的时候就向其提供咖啡,这是因为这种小额交易遭遇“51%攻击”的风险和顾客购物的即时性(Alice 能立即拿到咖啡)比起来,显得微不足道。这就和大部分的咖啡店对低于25美元的信用卡消费不会费时费力地向顾客索要签名是一样的,因为和顾客有可能撤销这笔信用卡支付的风险比起来,向用户索要信用卡签名的成本更高。相应的,使用比特币支付的大额交易被双重支付的风险就高得多了,因为买家(攻击者)可以通过在全网广播一个和真实交易的UTXO一样的伪造交易,以达到取消真实交易的目的。双重支付可以有两种方式:要么是在交易被确认之前,要么攻击者通过块链分叉来完成。进行51%攻击的人,可以取消在旧分叉上的交易记录,然后在新分叉上重新生成一个同样金额的交易,从而实现双重支付。
再举个例子:攻击者Mallory在Carol的画廊买了描绘伟大的中本聪的三联组画,Mallory通过转账价值25万美金的比特币与Carol进行交易。在等到一个而不是六个交易确认之后,Carol放心地将这幅组画包好,交给了Mallory。这时,Mallory的一个同伙,一个拥有大量算力的矿池的人Paul,在这笔交易写进区块链的时候,开始了51%攻击。首先,Paul利用自己矿池的算力重新计算包含这笔交易的块,并且在新块里将原来的交易替换成了另外一笔交易(比如直接转给了Mallory的另一个钱包而不是Carol的),从而实现了“双重支付”。这笔“双重支付”交易使用了跟原有交易一致的UTXO,但收款人被替换成了Mallory的钱包地址。然后,Paul利用矿池在伪造的块的基础上,又计算出一个更新的块,这样,包含这笔“双重支付”交易的块链比原有的块链高出了一个块。到此,高度更高的分叉区块链取代了原有的区块链,“双重支付”交易取代了原来给Carol的交易,Carol既没有收到价值25万美金的比特币,原本拥有的三幅价值连城的画也被Mallory白白拿走了。在整个过程中,Paul矿池里的其他矿工可能自始至终都没有觉察到这笔“双重支付”交易有什么异样,因为挖矿程序都是自动在运行,并且不会时时监控每一个区块中的每一笔交易。
为了避免这类攻击,售卖大宗商品的商家应该在交易得到全网的6个确认之后再交付商品。或者,商家应该使用第三方的多方签名的账户进行交易,并且也要等到交易账户获得全网多个确认之后再交付商品。一条交易的确认数越多,越难被攻击者通过51%攻击篡改。对于大宗商品的交易,即使在付款24小时之后再发货,对买卖双方来说使用比特币支付也是方便并且有效率的。而24小时之后,这笔交易的全网确认数将达到至少144个(能有效降低被51%攻击的可能性)。
共识攻击中除了“双重支付”攻击,还有一种攻击场景就是拒绝对某个特定的比特币地址提供服务。一个拥有了系统中绝大多数算力的攻击者,可以轻易地忽略某一笔特定的交易。如果这笔交易存在于另一个矿工所产生的区块中,该攻击者可以故意分叉,然后重新产生这个区块,并且把想忽略的交易从这个区块中移除。这种攻击造成的结果就是,只要这名攻击者拥有系统中的绝大多数算力,那么他就可以持续地干预某一个或某一批特定钱包地址产生的所有交易,从而达到拒绝为这些地址服务的目的。
需要注意的是,51%攻击并不是像它的命名里说的那样,攻击者需要至少51%的算力才能发起,实际上,即使其拥有不到51%的系统算力,依然可以尝试发起这种攻击。之所以命名为51%攻击,只是因为在攻击者的算力达到51%这个阈值的时候,其发起的攻击尝试几乎肯定会成功。本质上来看,共识攻击,就像是系统中所有矿工的算力被分成了两组,一组为诚实算力,一组为攻击者算力,两组人都在争先恐后地计算块链上的新块,只是攻击者算力算出来的是精心构造的、包含或者剔除了某些交易的块。因此,攻击者拥有的算力越少,在这场决逐中获胜的可能性就越小。从另一个角度讲,一个攻击者拥有的算力越多,其故意创造的分叉块链就可能越长,可能被篡改的最近的块或者或者受其控制的未来的块就会越多。一些安全研究组织利用统计模型得出的结论是,算力达到全网的30%就足以发动51%攻击了。
全网算力的急剧增长已经使得比特币系统不再可能被某一个矿工攻击,因为一个矿工已经不可能占据全网哪怕的1%算力。但是中心化控制的矿池则引入了矿池操作者出于利益而施行攻击的风险。矿池操作者控制了候选块的生成,同时也控制哪些交易会被放到新生成的块中。这样一来,矿池操作者就拥有了剔除特定交易或者双重支付的权力。如果这种权利被矿池操作者以微妙而有节制的方式滥用的话,那么矿池操作者就可以在不为人知的情况下发动共识攻击并获益。
但是,并不是所有的攻击者都是为了利益。一个可能的场景就是,攻击者仅仅是为了破坏整个比特币系统而发动攻击,而不是为了利益。这种意在破坏比特币系统的攻击者需要巨大的投入和精心的计划,因此可以想象,这种攻击很有可能来自政府资助的组织。同样的,这类攻击者或许也会购买矿机,运营矿池,通过滥用矿池操作者的上述权力来施行拒绝服务等共识攻击。但是,随着比特币网络的算力呈几何级数快速增长,上述这些理论上可行的攻击场景,实际操作起来已经越来越困难。近期比特币系统的一些升级,比如旨在进一步将挖矿控制去中心化的P2Pool挖矿协议,也都正在让这些理论上可行的攻击变得越来越困难。
毫无疑问,一次严重的共识攻击事件势必会降低人们对比特币系统的信心,进而可能导致比特币价格的跳水。然而,比特币系统和相关软件也一直在持续改进,所以比特币社区也势必会对任何一次共识攻击快速做出响应,以使整个比特币系统比以往更加稳健和可靠。

==目录==

简介
前言
第1章 介绍
第2章 比特币的原理
第3章 比特币客户端
第4章 密钥、地址、钱包
第4章 高级密钥和地址
第5章 交易
第6章 比特币网络
第7章 区块链
第8章 挖矿与共识
第8章 区块链分叉、矿池、共识攻击
第9章 竞争币、竞争块链和应用程序
第10章 比特币安全
附录1 交易脚本的操作符、常量和符号
附录2 比特币改进协议
附录3 pycoin库、ku程序和tx交易程序
附录4 sx工具下一些的命令本文原链接: http://zhibimo.com/read/wang-miao/Mastering-Bitcoin/Chapter08.html

发表回复