区块链: 技术驱动金融 - 第5章 比特币挖矿
这一章将着重讨论比特币挖矿(bitcoin mining)。前面章节讨论了比特币是如何依赖这些矿工们而运行的——他们查证交易记录、制造和存储所有的区块、对被写入区块链的区块达成共识、从中获取一些奖励。但是还有一些问题:这些矿工是谁?他们是如何进入这个行业的?他们是怎么运作的?他们的商业模式是什么?他们对环境造成什么影响?本章将回答这些问题。
5.1 比特币矿工的任务
要成为比特币矿工,你必须加入比特币网络并与其他节点相连,建立连接后,你还需要完成六个任务:
- 监听交易广播。监听网络上的交易广播,然后验证它们的签名是正当有效的,交易输出没有被重复支付。
- 维护区块链网络和监听新的区块。必须先维护区块链。为此,一开始你可以要求其他节点把区块链上的历史记录同步过来。然后,监听那些被广播到网络上的新区块。你的任务是验证你收到的每个区块,这里的验证是指保证区块里的每笔交易都是有效的,且这个区块包含了一个有效的临时随机数。
- 组装一个备选区块。一旦拥有最新的全部区块链数据备份,你就可以开始制造自己的区块了。你要把监听到的交易进行组合并放进一个新的区块,然后把该区块排在这个链条中最新的区块的后面。你必须保证你建立的新区块中每笔交易都是正当有效的。
- 找到一个让你的区块有效的临时随机数。这一步工作量很大,也是矿工工作中最难的一个环节。
- 希望你的区块被全网接受。即时你找到了一个区块,也不能保证该区块会成为共识链(consensus chain)的一部分。这取决于其他矿工是否接受你的区块,并在此基础上接龙下去。
- 利润。如果所有其他矿工接受了你的区块,那你就能获得区块奖励和交易费。
矿工的任务可以分为两类:1.验证交易和区块。这是比特币网络赖以生存和运转的基础,这些任务也是比特币协议需要矿工的首要原因。2.和其他矿工竞争。争取找到区块并获得奖励,不是比特币网络存在所必须的,而是为了鼓励矿工去完成第一类任务而设置的。当然,这两类任务都是使比特币成为一个数字货币的必要条件,因为矿工必须获得奖励才会去完成这些重要任务。
寻找有效区块
在第3章中我们看到,区块链主要有两层基于哈希函数的结构。1.区块链上,每个区块头部都有一个哈希指针指向前一个区块。2.每一个区块里,包括所有交易的默克尔树。
作为矿工,首先需要从你的交易池中选出一系列有效的交易并且编译成默克尔树。然后,组装出一个新的区块,让它的头部指向区块链的上一个区块。在新区块的头部,有一个32位的随机数区域。你需要尝试不同的临时随机数,直到该随机数能使整个区块的哈希值小于目标值。这个目标值一般体现在以0开始的特定位数的数值。作为一名矿工,你可能使随机数从0开始,每次增加1,直到该随机数能使区块有效为止,如下图所示。
图5.1.1 寻找有效区块。矿工尝试了一串都是0的随机数,但没有产生有效的哈希值,所以矿工继续尝试其他不同的临时随机数
如果你在尝试了所有32为可能的取值后,仍然不能产生一个有效的哈希值,那么你就必须做出更多改变。注意,上图中(前面章节也有提到过)币基交易(coinbase)中还有一个随机数可以改动,你可以改变这个随机数,比如加1,然后就可以重新改变区块头部的随机数来寻找有效的哈希值。
改变币基里的随机数后,整个默克尔树上交易的哈希值都会改变,因为币基值的改变会向上传递,所以改变币基的随机数比改变区块头部的随机数代价要大。所以,一般而言,矿工都是更改头部随机数,除非在头部找不到有效的随机数,才会选择改变币基里的随机数。
当你坚持足够长的时间,你总能找到一对正确的临时随机数组合——头部随机数和币基随机数,用来产生一个符合哈希值要求的新区块,然后立即宣布,就有希望获得相应区块的奖励和交易费。
决定难度
每挖出2016个区块,挖矿难度就会改变一次,而一个区块的产生平均需要10分钟,因此,大约两个星期挖矿难度会调整一次,以维持产生有一个区块所需的平均时间是10分钟,调整的方式如下公式:
下一个难度=(上一个难度 * 2016个区块 * 10分钟)/ 产生2016个区块所花费的时间
挖矿难度改变的周期是两周,并没有什么特比的含义,只是一个权衡的结果。周期太短,难度会随着每一个周期找到的区块数目不同而波动(概率问题);周期太长,整个网络的哈希算力会与难度大大地失去平衡。
每个矿工独立地计算难度,只接受达到这个难度的区块。两个在不同分叉上的矿工可能会有不同的计算难度,但是在同一个区块上工作的矿工一定会对计算难度达成共识。
5.2 挖矿所需硬件
矿工所要做的计算是十分困难的,其核心在于,对SHA-256哈希函数的运算。SHA-256是SHA-2这个家族里的一员,是目前被公认的最安全的哈希函数。当然,不排除随着时间的推移,其安全性可能会降低。
矿工的任务就是尽可能快地进行SHA-256函数运算,而且,在比特币中,这个运算还要进行两轮。为什么要进行两轮,原因并不清楚,但是这就是比特币的个性,作为比特币矿工只能服从。
比特币挖矿工作经历了好几代的发展历程。
1.CPU挖矿。假如一个高端个人电脑每秒计算大约2千万次哈希函数(20MH/s),根据2015年早期的难度水平(2的67次方),大概需要几十万年来找到一个有效区块。所以,通过CPU挖矿,不可能赚到钱。
2.GPU挖矿。第二代矿工使用GPU来挖矿,因为GPU具有高吞吐量和高并行处理能力。但是,大量GPU堆放在一起,冷却处理是一个突出的问题,而且GPU也非常耗电。假如一个非常高端的显卡经过超频后能达到每秒计算大约2亿次哈希函数(200MH/s),那么,100个显卡一起,在2015年早期,仍需要几百年才能找到一个有效区块。因此,GPU挖矿也不赚钱。
3.FPGA挖矿(现场可编程门阵列挖矿)。FPGA比GPU性能好,特别是在数位操作方面。精心使用FPGA可以使运算速度达到每秒计算大约10亿次哈希函数(1GH/s),那么,100块FPGA一起,在2015年早期,平均仍需要100年的时间才能找到一个有效区块。因此,FPGA挖矿也只是昙花一现,没有持续多久。
4.ASIC挖矿(专用集成电路技术挖矿)。专门为比特币挖矿而生产的ASIC矿机,由专门的供应商制造和出售。
如今,挖矿已经从个人领域转到了大型专业的挖矿中心,这些中心可以购买大量的ASIC矿机进行挖矿,从而维持利润。
未来
现在,用ASIC挖矿是唯一一种可以赚钱的比特币挖矿手段,而这对于个体矿工来说,是十分不友好的。人们不禁要问,未来如何发展?小规模矿工是否永远不可能再参与挖矿过程?更重要的是,现在使用ASIC和专业挖矿中心是否已经违反了比特币当初的设计初衷:一个完全去中心化的系统,所有人都可以用自己的电脑去挖矿。这些问题将在第8章中探讨。
5.3 能源消耗和生态环保
比特币挖矿需要消耗大量的能源,这种“浪费”能源的形式经常被人诟病,因为SHA-256的运算没有其他任何用处。但是,我们必须认识到,任何一种支付系统都需要能源和电力的消耗。如纸币印刷、ATM机器运行、硬币分类器、点钞机、支付服务系统、运行现钞和金条的运钞车,无一不在消耗各种能源。你也可以一样说这些能源除了维护整个货币系统外,没有任何其他用处。所以,如果我们认可比特币作为一个有用的货币体系,那么支持比特币体系的能耗就不能认为是浪费。
5.4 矿池
对于单个矿工来说,挖矿就是一个赌博游戏,你可能一年都找不到一个区块,而白白浪费成本,也有可能一年之内你找到了好几个区块,然后赚了一笔钱。
矿池
历史上,当小商人遇到大风险时,会自发组建一个互助保险公司来降低风险。对于比特币矿工来说,也可以采取类似的方式。
矿池应运而生——矿池就是一个比特币矿工互相之间的保险。一组矿工可以形成一个矿池共同挖矿,并指定一个币基接受人。这个接受人就是矿池管理员。只要有人找到一个有效区块,矿池管理员就会收到这个区块的奖励,继而根据每个参与人贡献的工作量按比例分配给所有矿池的参与者。
挖矿工分(mining shares)
挖矿工分用于衡量每个参与人的贡献。工分,就是那些接近有效区块的区块。比如,目标值是个前面67位是0的数字,输出的哈希值必须要低于这个目标才算有效。在寻找这个哈希值的过程中,矿工可能会找到其他一些区块,它们的哈希值也有许多0,但是达不到67个。矿工们可以用这些区块来证明他们确实在工作,一个合格的工分可能要求40-50个0,这取决于矿池的要求。
有了工分之后,管理员就可以按照工分来分配奖励。最常见最简单的分配方式有工分分红和按实际比例分红。
矿池跳换(pool hopping)
矿工在具有不同分配方案的矿池之间进行切换,以获得更高的收益。
历史和标准化
矿池兴起于2010年比特币的GPU时代。已有很多矿池管理协议应运而生。甚至有人建议这些矿池管理协议应该被标准化,作为比特币本身的一部分。
51%矿池
2015年早期,绝大部分矿工都通过加入矿池来挖矿,只有很少的矿工还在单独挖矿。2014年6月,网络里最大的矿池GHash.IO,其算力甚至超过了比特币全网算力的50%,主要是因为这个矿池给矿工优厚的奖励,以至于大家都想加入。
一个矿池掌握了全网51%的算力是比特币社区里一个令人担忧的问题,GHash也因此遭到反击,到2014年8月,GHash不再接受新用户而主动下调了一些比例。
无论如何,矿池有可能会掩盖一个事实:实际上的算力集中在几个大的挖矿机构手上,这些大的机构可以同时参与多个不同的矿池以掩盖它们的真实规模。这种做法称为“洗算力”(laundering hashes,类似于洗钱)。因为矿池的原因,发现洗算力变得非常困难,这也使得外人无法知晓矿机的实际物理控制有多集中。
矿池是有益的吗
矿池的一大问题就是中心化管理。矿池管理员实际掌握了多少算力是一个问题。此外,这减少了比特币网络中全节点的数目,即要存储整个区块链、交易每一个交易,现在这些都可以交给矿池管理员了。如果你对矿池的中心化模式感到不安,你可能会问:是否可以重新设计挖矿流程,大家必须自己进行挖矿。将在第8章讨论这个问题。
5.5 挖矿的激励和策略
矿工在挑选一个区块开挖之前,都需要做一些策略上的选择:
- 需要包含哪些交易?矿工可以选择将哪些交易放进他的区块里。默认策略:选择那些交易费比较高的交易。
- 对哪一个区块进行挖矿运算?矿工可以选择在哪个区块上进行挖矿。默认策略:在最长的那条区块链上继续挖下去。
- 在同一高度的多个区块中做选择。如果两个不同的区块在同一时间被宣布发现,这就造成一个分叉,每个区块都是可以被延续下去的,因为它们都符合最长区块链原则。矿工必须选择在哪一个区块后面接龙下去。默认策略:选择最先被监听到的那一个区块。
- 什么时候宣布区块?当矿工找到一个有效区块后,他们要决定什么时候向比特币网络宣布这一个区块。默认策略:立刻宣布。
下面看看几种不同的策略,有可能会使得挖矿收益更高。
分叉攻击(forking attack)
分叉攻击,即重复支付。一个恶意矿工给受害者Bob发送了一些比特币购买服务,Bob看到了这笔交易被放进了最长链,甚至还等到了6次确认,于是开始提供服务。但是,现在这个矿工创建了一个包含另一个交易——双重支付交易的更长的分叉。如下图所示。
图5.5.1 分叉攻击
拥有51%算力的矿工可以通过发起分叉攻击来获得更高的收益。
通过贿赂来进行分叉攻击
通过购买足够的矿机来发起分叉攻击,是很困难且非常昂贵的。相反,可以通过贿赂那些有能力的矿工来为你工作而发起分叉攻击,是有可能的。
临时保留区块攻击(temporary block-withholding attacks)
攻击场景:当你找到一个区块后,你不是立刻宣布,而是在此基础上继续寻找下一个区块。如果你的运气很好,在其他矿工找到下一个区块之前,你连续找到了两个区块,并且秘密保留它们。这时候,当一个其他矿工宣布找到一个区块之后,你就立刻同时宣布你找到的两个区块,这样,另一个矿工的那个区块就会成为孤岛,因为你的两个区块是更长的分叉,其他矿工会在你的区块后面接龙下去。这样,就导致了另一个矿工的算力浪费。这种行为成为自私挖矿(selfish mining),如下图所示。
图5.5.2 自私挖矿。1是攻击之前的区块链,2和3是攻击者的两个区块,4是非攻击者的区块,会成为孤岛。
黑名单和惩罚分叉攻击
如果一个矿工想把一个来自地址X的交易列入黑名单,换句话说,想冻结从该地址出来的钱。传统观点都认为在比特币里这种黑名单没有办法实施,因为即使有些矿工拒绝把交易放进区块链,其他一些矿工还是会放进区块链。但是,如果你拥有网络的大部分算力,你可以对所有矿工宣布:我将拒绝在包含来自该地址的交易的区块链上工作。这是因为你拥有网络的大部分算力,区块链的延展基本是你说了算,如果有的矿工执意要把这些交易(来自地址X)放进区块链,那么他们的区块必将是区块链的分叉,而最终成为孤岛,浪费算力。
羽量级分叉
如果你没有那么大的算力,那么你的宣布就是自找麻烦。因为,如果其他矿工没有按照你宣布的意愿来,那么你就可能会被排除在最长的共识链之外。一个重要的原因是,你的说法——我将拒绝在包含来自该地址的交易的区块链上工作——太绝对了,这会导致一个硬分叉。所以,你应该对其他矿工宣布:我将尝试发起分叉,但过一段时间我可能会放弃封杀的尝试。例如,你可以宣布:当k个区块证实从地址X出来的交易是正当的,那么我就回到最长共识链上。
这种情况下,只要你有一定的算力,你就有可能说服其他矿工来加入你,一起拒绝来自地址X的交易。只要你把你的计划公布出来,其他矿工就会知道:如果他们胆敢把这个来自地址X的交易放入自己的区块,那么就有一定的可能会丧失自己已经发现的区块【被你的羽量级分叉攻击(feather forking)所消灭】。
最终就演化成:其他矿工经过理性思考,将决定是否加入你对X地址的封杀行动。所以,这个攻击,即封杀地址X,要想成功,关键在于确保其他矿工相信你将会进行分叉攻击。
逐渐转移到用交易费来奖励挖矿
随着挖矿奖励逐渐发完,交易费将变得越来越重要,因为如果一笔交易没有交易费,那么矿工不会打包这笔交易,或者最后再打包。
未解的问题
1.矿工可以自由选择挖矿策略,但是目前,大多数矿工还是选择默认策略,现在比特币运行得很好,也很稳定,但是在理论上,我们暂时无法论证这是一个稳定的机制。
2.默认策略能够在实际中一直保持有效,我们没有把握。
3.这个系统将如何演化,是尚不清楚的。基于博弈论对此进行预测也是一个非常有趣的前沿研究领域。