比特币之挖矿与共识(一)

简介

“挖矿”,挖矿的主要目的不是这个奖励或者产生新币。 挖矿最重要的作用是巩固了去中心化的清算交易机制,通过这种机制,交易得到验证和清算/清除。挖矿是使得比特币与众不同的发明,它实现去中心化的安全机制,是P2P数字货币的基础,

挖矿确保了比特币系统安全,并且在没有中央权力机构的情况下实现了全网络范围的共识。

新币发行和交易费的奖励是将矿工的行动与网络安全保持一致的激励计划,同时实现了货币发行。

提示:挖矿的目的不是创造新的比特币。 这是激励机制。 挖矿是一种机制,这种机制实现了去中心化的安全。

每10分钟就会有一个新的区块被“挖掘”出来,每个区块里包含着从 上一个区块产生到目前这段时间内发生的所有交易,这些交易被依次添加到区块链中。我们把包含在区块内且被添加到 区块链上的交易称为“确认”(confirmed)交易,交易经过“确认”之后,新的拥有者才能够花费他在交易中得到的比特币。

矿工们在挖矿过程中会得到两种类型的奖励:

  • 创建新区块的新币奖励
  • 区块中所含交易的交易费。

为了得到这些奖 励,矿工们争相完成一种基于加密哈希算法的数学难题,这些难题的答案包括在新区块中,作为矿工的计算工作量的证 明,被称为“工作量证明”。该算法的竞争机制以及获胜者有权在区块链上进行交易记录的机制,这二者是比特币安全的基石。

新比特币

新比特币的生成过程被称为挖矿,是因为它的奖励机制被设计为速度递减模式。

矿工通过创造一个新区块得到的比特币数量大约 每四年(或准确说是每210,000个块)减少一半。

开始时为2009年1月每个区块奖励50个比特币,然后到2012年11月减 半为每个区块奖励25个比特币。之后在2016年7月 再次减半为每个新区块奖励12.5个比特币。基于这个公 式,比特币挖矿奖励以指数方式递减,直到2140年。届时所有的比特币(20,999,999,980)全部发行完毕。换句话说 在2140年之后,不会再有新的比特币产生。

手续费奖励

矿工们同时也会获取交易费。每笔交易都可能包含一笔交易费,交易费是每笔交易记录的输入和输出的差额。在挖矿过 程中成功“挖出”新区块的矿工可以得到该区块中包含的所有交易“小费”。目前,这笔费用占矿工收入的0.5%或更少,大 部分收益仍来自挖矿所得的比特币奖励。

然而随着挖矿奖励的递减,以及每个区块中包含的交易数量增加,交易费在矿 工收益中所占的比重将会逐渐增加。在2140年之后,所有的矿工收益都将由交易费构成。

通货膨胀与紧缩

总量有限并且发行速度递减创造了一种抗通胀的货币供应模式。法币可被中央银行无限制地印刷出来,而比特币永远不会因超额印发而出现通胀。

通货紧缩

最重要并且最有争议的一个结论是一种事先确定的发行速率递减的货币发行模式会导致货币通货紧缩(简称通缩)。通缩是一种由于货币的供应和需求不匹配导致的货币增值的现象。它与通胀相反,价格通缩意味着货币随着时间有越来越强的购买力。

许多经济学家提出通缩经济是一种无论如何都要避免的灾难型经济。因为在快速通缩时期,人们预期着商品价格会下跌,人们将会储存货币,避免花掉它。这种现象充斥了日本经济“失去的十年”,就是因为在需求坍塌之后导致了滞涨状态。

比特币专家们认为通缩本身并不坏。更确切地说,我们将通缩与需求坍塌联系在一起是因为过去出现的一个特例。在法币届,货币是有可能被无限制印刷出来的,除非遇到需求完全崩塌并且毫无发行货币意愿的情形,因此经济很难进入滞涨期。而比特币的通缩并不是需求坍塌引起的,它遵循一种预定且有节制的货币供应模型。

通货紧缩的积极因素当然是与通货膨胀相反。 通货膨胀导致货币缓慢但不可避免的贬值,这是一种隐性税收的形式,惩罚在银行存钱的人从而实现解救债务人(包括政府这个最大的债务人)。 政府控制下的货币容易遭受债务发行的道德风险,之后可能会以牺牲储蓄者为代价,通过贬值来抹去债务。

比特币这种不是因经济快速衰退而引起的通缩,是否会引发其他问题,仍有待观察。

去中心化共识

可以将区块链看作一本记录所有交易的公开总帐簿(列表),比特币网络中的每个参与 者都把能接受区块链,把它看作一本证明所有权的权威记录。

但在不考虑相信任何人的情况下,比特币网络中的所有参与者如何达成对任意一个所有权的共识呢?所有的传统支付系 统都依赖于一个中心认证机构,依靠中心机构提供的结算服务来验证并处理所有的交易。比特币没有中心机构,几乎所 有的完整节点都有一份公共总帐的备份,这份总帐可以被视为权威记录。区块链并不是由一个中心机构创造的,它是由比特币网络中的所有节点各自独立竞争完成的。

换句话说比特币网络中的所有节点,依靠着节点间的不稳定的网络连接所传输的信息,最终得出同样的结果并维护了同一个公共总帐。这一章将介绍比特币网络不依靠中心机构而达成共识的机制。

去中心化的自发共识

中本聪的主要发明就是这种去中心化的自发共识(emergent consensus)机制。这种自发,是指共识没有明确的完成点,因为共识达成时,没有明确的选举和固定时刻。换句话说,共识是数以千计的独立节点遵守了简单的规则通过异步交互自发形成的产物。

比特币的去中心化共识由所有网络节点的4种独立过程相互作用而产生:

  • 每个全节点依据综合标准对每个交易进行独立验证
  • 通过完成工作量证明算法的验算,挖矿节点将交易记录独立打包进新区块
  • 每个节点独立的对新区块进行校验并组装进区块链
  • 每个节点对区块链进行独立选择,在工作量证明机制下选择累计工作量最大的区块链。

在接下来的几节中,我们将审视这些过程,了解它们之间如何相互作用并达成全网的自发共识,从而使任意节点组合出 它自己的权威、可信、公开的总帐副本。

交易的独立校验

在交易一章中,我们知道了钱包软件通过收集UTXO、提供正确的解锁脚本、构造一个新的支出(支付)给接收者这一系列的方式来创建交易。产生的交易随后将被发送到比特币网络临近的节点,从而使得该交易能够在整个比特币网络中传播。

然而,在交易传递到临近的节点前,每一个收到交易的比特币节点将会首先验证该交易,这将确保只有有效的交易才会 在网络中传播,而无效的交易将会在第一个节点处被废弃。

每一个节点在校验每一笔交易时,都需要对照一个长长的标准列表:

  1. 交易的语法和数据结构必须正确。
  2. 输入与输出列表都不能为空。
  3. 交易的字节大小是小于 MAX_BLOCK_SIZE 的。
  4. 每一个输出值,以及总量,必须在规定值的范围内 (小于2,100万个币,大于0)。
  5. 没有哈希等于0,N等于-1的输入(coinbase交易不应当被传递)。
  6. nLockTime是小于或等于 INT_MAX 的。或者nLocktime and nSequence的值满足MedianTimePast(译者注:MedianTime是这个块的前面11个块按照block time排序后的中间时间)
  7. 交易的字节大小是大于或等于100的。
  8. 交易中的签名数量(SIGOPS)应小于签名操作数量上限。
  9. 解锁脚本( scriptSig )只能够将数字压入栈中,并且锁定脚本( scriptPubkey )必须要符合isStandard的格式 (该格式将会拒绝非标准交易)。
  10. 池中或位于主分支区块中的一个匹配交易必须是存在的。
  11. 对于每一个输入,引用的输出是必须存在的,并且没有被花费。
  12. 对于每一个输入,如果引用的输出存在于池中任何别的交易中(译者注:这笔输入引用的输出有人家自己的输入,不是你),该交易将被拒绝。
  13. 对于每一个输入,在主分支和交易池中寻找引用的输出交易。如果输出交易缺少任何一个输入,该交易将成为一个孤 立的交易。如果与其匹配的交易还没有出现在池中,那么将被加入到孤立交易池中。
  14. 对于每一个输入,如果引用的输出交易是一个coinbase输出,该输入必须至少获得 COINBASE_MATURITY(100)个确认。
  15. 使用引用的输出交易获得输入值,并检查每一个输入值和总值是否在规定值的范围内 (小于2100万个币,大于0)。
  16. 如果输入值的总和小于输出值的总和,交易将被中止。
  17. 如果交易费用太低以至于无法进入一个空的区块,交易将被拒绝。
  18. 每一个输入的解锁脚本必须依据相应输出的锁定脚本来验证。

这些条件能够在比特币标准客户端下的 AcceptToMemoryPool 、 CheckTransaction 和 CheckInputs 函数中获得更详细的阐述。 请注意,这些条件会随着时间发生变化,为了处理新型拒绝服务攻击,有时候也为交易类型多样化而放宽规则。

在收到交易后,每一个节点都会在全网广播前对这些交易进行独立校验,并以接收时的相应顺序,为有效的新交易建立一个验证池(还未确认),这个池可以叫做交易池,或者memory pool或者mempool。

挖矿节点

同其他节点一样,Jing的节点时刻监听着传播到比特币网络的新区块。而这些新加入的区块对挖矿节点有着特殊的意 义。矿工间的竞争以新区块的传播而结束,如同宣布谁是最后的赢家。对于矿工们来说,收到一个新区块进行验证意味着别人已经赢了,而自己则输了这场竞争。然而,一轮竞争的结束也代表着下一轮竞争的开始。新区块并不仅仅是象征着竞赛结束的方格旗;它也是下一个区块竞赛的发令枪。

打包交易至区块

验证交易后,比特币节点会将这些交易添加到自己的内存池中。内存池也称作交易池,用来暂存尚未被加入到区块的交 易记录。与其他节点一样,Jing的节点会收集、验证并传递新的交易。而与其他节点不同的是,Jing的节点会把这些交 易整合到一个候选区块中。

让我们继续跟进,看下Alice从Bob咖啡店购买咖啡时产生的那个区块。Alice的交易在区块 277,316。为了演示本章中提到的概念,我们假设这个区块是由Jing的挖矿系统挖出的,并且继续跟进Alice的交易,因 为这个交易已经成为了新区块的一部分。

过程

Jing的挖矿节点维护了一个区块链的本地副本。当Alice买咖啡 的时候,Jing节点的区块链已经收集到了区块277,314,并继续监听着网络上的交易,在尝试挖掘新区块的同时,也监 听着由其他节点发现的区块。当Jing的节点在挖矿时,它从比特币网络收到了区块277,315。这个区块的到来标志着终 结了产出区块277,315竞赛,与此同时也是产出区块277,316竞赛的开始。

Jing的节点立刻构建一个新的空区块,做为区块277,316的候选区块。称作候选区块是因为它还没有包含有效的工作量 证明,不是一个有效的区块,而只有在矿工成功找到一个工作量证明解之后,这个区块才生效。

现在,Jing的节点从内存池中整合到了全部的交易,新的候选区块包含有418笔交易,总的矿工费为0.09094925个比特币。

coinbase 创币交易

区块中的第一笔交易是笔特殊交易,称为创币交易或者coinbase交易。这个交易是由Jing的节点构造并用来奖励矿工们所做的贡献的。

注意:当块277,316开采时,每个块的奖励是25比特币。 此后,已经过了一个“减半”时期。 2016年七月份的奖励为12.5比特币,2020年达到210000区块时,将再次减半。

Jing的节点会创建“向Jing的地址支付25.09094928个比特币”这样一个交易,把生成交易的奖励发送到自己的钱包。Jing挖出区块获得的奖励金额是coinbase奖励(25个全新的比特币)和区块中全部交易矿工费的总和。

与常规交易不同,创币交易没有输入,不消耗UTXO。它只包含一个被称作coinbase的输入,仅仅用来创建新的比特 币。创币交易有一个输出,支付到这个矿工的比特币地址。

Coinbase奖励与矿工费
为了构造创币交易,Jing的节点需要计算矿工费的总额,将这418个已添加到区块交易的输入和输出分别进行求和,然 后用输入总额减去输出总额得到矿工费总额,公式如下:

Total Fees = Sum(Inputs) - Sum(Outputs)

紧接着,Jing的节点计算出这个新区块正确的奖励额。奖励额的计算是基于区块高度的,以每个区块50个比特币为开 始,每产生210,000个区块减半一次。这个区块高度是277,316,所以正确的奖励额是25个比特币。

详细的计算过程可以参看比特币核心客户端中的GetBlockValue函数

注意: 如果Jing的挖矿节点把coinbase交易写入区块,那么如何防止Jing奖励自己100甚至1000比特币? 答案是,不正确的奖励将被其他人视为无效,浪费了Jing用于工作证明的投入。 只有这个区块被大家认可,Jing才能得到报酬。

创币交易的结构

经过计算,Jing的节点构造了一个创币交易,支付给自己25.09094928枚比特币。

例10-4所示,创币交易的结构比较特殊,与一般交易输入需要指定一个先前的UTXO不同,它包含一个“coinbase“输 入。

常规交易输入结构:

比特币之挖矿与共识(一)_第1张图片
常规交易

coinbase交易输入结构:


比特币之挖矿与共识(一)_第2张图片
coinbase

在Coinbase交易中,“交易哈希”字段32个字节全部填充0,“交易输出索引”字段全部填充0xFF(十进制的255),这两个字段的值表示不引用UTXO。“解锁脚本”由coinbase数据代替,数据可以由矿工自定义。

Coinbase数据

创币交易不包含“解锁脚本“(又称作 scriptSig)字段,这个字段被coinbase数据替代,长度最小2字节,最大100字节。除 了开始的几个字节外,矿工可以任意使用coinbase的其他部分,随意填充任何数据。

以创世块为例,中本聪在coinbase中填入了这样的数据“The Times 03/Jan/ 2009 Chancellor on brink of second bailout for banks“(泰晤士报 2009年1月3日 财政大臣将再次对银行施以援手),表示对日期的证明,同时也表达了对银行系统的不信任。现在,矿工使用coinbase数据实现extra nonce功能,并嵌入字符串来标识挖出它的矿池。

coinbase前几个字节也曾是可以任意填写的,不过在后来的第34号比特币改进提议(BIP34)中 规定了版本2的区块(版本字段为2的区块),这个区块的高度必须跟在脚本操作“push“之后,填充在coinbase字段的起始处。

例子

我们以例10-4中的区块277,316为例,coinbase就是交易输入的“解锁脚本“(或scriptSig)字段,这个字段的十六进制值 为03443b0403858402062f503253482f。下面让我们来解码这段数据。

第一个字节是03,脚本执行引擎执行这个指令将后面3个字节压入脚本栈(见表4-1);紧接着的3个字节——0x443b04, 是以小端格式(最低有效字节在先)编码的区块高度。翻转字节序得到0x043b44,表示为十进制是277,316。

紧接着的几个十六进制数(03858402062)用于编码extra nonce(参见"10.11.1 随机值升位方案"),或者一个随机值,从而求解一个适当的工作量证明。

coinbase数据结尾部分(2f503253482f)是ASCII编码字符 /P2SH/,表示挖出这个区块的挖矿节点支持BIP0016所定义的 pay-to-script-hash(P2SH)改进方案。在P2SH功能引入到比特币的时候,曾经有过一场对P2SH不同实现方式的投票, 候选者是BIP0016和BIP0017。支持BIP0016的矿工将/P2SH/放入coinbase数据中,支持BIP0017的矿工将 p2sh/CHV 放入他们的coinbase数据中。最后,BIP0016在选举中胜出,直到现在依然有很多矿工在他们的coinbase中填 入/P2SH/以表示支持这个功能。

构造区块头

为了构造区块头,挖矿节点需要填充六个字段

比特币之挖矿与共识(一)_第3张图片
header

在区块277,316被挖出的时候,区块结构中用来表示版本号的字段值为2,长度为4字节,以小端格式编码值为 0x20000000。

接着,挖矿节点需要填充“前区块哈希”,在本例中,这个值为Jing的节点从网络上接收到的区块277,315的区块头哈希值,它是区块277316候选区块的父区块。区块277,315的区块头哈希值为:

0000000000000002a7bbd25a417c0374cc55261021e8a9ca74442b01284f0569

提示:通过选择候选块头中的先前块哈希字段指定的特定父区块,Jing正在通过确认挖矿能力来扩展区块链。 从本质上讲,这是用他的采矿权为最长难度的有效链进行的“投票”,即,选择难度总值最大的最长链

为了向区块头填充merkle根字段,要将全部的交易组成一个merkle树。创币交易作为区块中的首个交易,后将余下的 418笔交易添至其后,这样区块中的交易一共有419笔。在之前,我们已经见到过“Merkle树”,树中必须有偶数个叶子 节点,所以需要复制最后一个交易作为第420个叶子节点,每个叶子节点是对应交易的哈希值。这些交易的哈希值逐层地、成对地组合,直到最终组合并成一个根节点。merkle数的根节点将全部交易数据摘要为一个32字节长度的值

c91c008c26e50763e9f548bb8b2fc323735f73577effbc55502c51eb4cc7cf2e

挖矿节点会继续添加一个4字节的时间戳,以Unix纪元时间编码,即自1970年1月1日0点到当下总共流逝的秒数。本例 中的1388185914对应的时间是

2013年12月27日,星期五,UTC/GMT

接下来,Jing的节点需要填充Target字段(难度目标值),为了使得该区块有效,这个字段定义了所需满足的工作量证明的难度。难度在区块中以“尾数-指数”的格式,编码并存储,这种格式称作target bits(难度位)。这种编码的首字节表示指数,后面的3字节表示尾数(系 数)。

以区块277316为例,难度位的值为0x1903a30c,0x19是指数的十六进制格式,后半部0x03a30c是系数。

最后一个字段是nonce,初始值为0

区块头完成全部的字段填充后,挖矿就可以开始进行了。挖矿的目标是找到一个使区块头哈希值小于难度目标的 nonce。挖矿节点通常需要尝试数十亿甚至数万亿个不同的nonce取值,直到找到一个满足条件的nonce值。

构建区块

既然Jing的节点已经构建了一个候选区块,那么就轮到Jing的矿机对这个新区块进行“挖掘”,求解工作量证明算法以使这个区块有效。从本书中我们已经学习了比特币系统中不同地方用到的哈希加密函数。比特币挖矿过程使用的是 SHA256哈希函数。

用最简单的术语来说,挖矿就是重复计算区块头的哈希值,不断修改该参数,直到与哈希值匹配的一个过程。哈希函数 的结果无法提前得知,也没有能得到一个特定哈希值的模式。哈希函数的这个特性意味着:得到哈希值的唯一方法是不断的尝试,每次随机修改输入,直到出现适当的哈希值。

只能暴力破解

工作量证明算法

哈希函数输入一个任意长度的数据,输出一个长度固定且绝不雷同的值,可将其视为输入的数字指纹。对于特定输 入,哈希的结果每次都一样,任何人都可以用相同的哈希函数,计算和验证哈希结果。一个加密哈希函数的主要特征就是不同的 输入几乎不可能出现相同的数字指纹。因此,有意的选择一个输入去生成一个想要的哈希值值是几乎不可能的,更别提用随机的方式生成想要的哈希值了。

无论输入的大小是多少,SHA256函数的输出的长度总是256bit。

竞争Target目标阈值

为了使这个哈希算法变得富有挑战,我们来设定一个具有任意性的目标:找到一个语句,使之哈希值的十六进制表示以 0开头。幸运的是,这很容易!在例10-10中语句 "I am Satoshi Nakamoto13" 的哈希值是

0ebc56d59a34f5082aaef3d66b37a661696c2b618e62432727216ba9531041a5

刚好满足条件。我们得到它用了13次。用概率的角度 来看,如果哈希函数的输出是平均分布的,我们可以期望每16次得到一个以0开头的哈希值(十六进制个位数字为0到 F)。从数字的角度来看,我们要找的是小于 0x1000000000000000000000000000000000000000000000000000000000000000 的哈希值。

我们称这个为Target目标阈值,我们的目的是找到一个小于这个目标的哈希值。如果我们减小这个目标值,那找到一个小于它的哈希值会越来越难。

简单打个比方,想象人们不断扔一对骰子以得到小于一个特定点数的游戏。第一局,目标是12。只要你不扔出两个6, 你就会赢。然后下一局目标为11。玩家只能扔10或更小的点数才能赢,不过也很简单。假如几局之后目标降低为了5。

现在有一半机率以上扔出来的骰子加起来点数会超过5,因此无效。随着目标越来越小,要想赢的话,扔骰子的次数会 指数级的上升。最终当目标为2时(最小可能点数),只有一个人平均扔36次或2%扔的次数中,他才能赢。从一个知道骰子游戏目标为2的观察者的角度来看,如果有人要成功中奖,假设他平均尝试了36次。

换句话说,可以估计从实现目标难度取得成功所需的工作量。 当算法是基于诸如SHA256的确定性函数时,输入本身就成为证据,必须要一定的工作量才能产生低于目标的结果。 因此,称之为工作量证明

在例10-10中,成功的nonce为13,且这个结果能被所有人独立确认。任何人将13加到语句 "I am Satoshi Nakamoto" 后面再计算哈希值都能确认它比目标值要小。这个正确的结果同时也是工作量证明(Proof of Work),因为它证明我们的确花时间找到了这个nonce。验证这个哈希值只需要一次计算,而我们找到它却花了13次。如果目标值更小(难度更大),那我们需要多得多的哈希计算才能找到合适的nonce,但其他人验证它时只需要一次哈希计算。此外,知道目标值后,任何人都可以用统计学来估算其难度,因此就能知道找到这个nonce需要多少工作。

比特币的工作量证明和例10-10中的挑战非常类似。矿工用一些交易构建一个候选区块。接下来,这个矿工计算这个区块头信息的哈希值,看其是否小于当前目标值。如果这个哈希值不小于目标值,矿工就会修改这个nonce(通常将之加 1)然后再试一次。按当前比特币系统的难度,矿工得试10^15次(10的15次方)才能找到一个合适的nonce使区块头信息哈希值足够小。

在写这本书的时候,比特币网络要寻找区块头信息哈希值小于

0000000000000000029AB9000000000000000000000000000000000000000000

可以看出,这个目标哈希值开头的0多了很多。这意味 着可接受的哈希值范围大幅缩减,因而找到正确的哈希值更加困难。生成下一个区块需要网络每秒计算1.8 septa-hashes((thousand billion billion次哈希)。这看起来像是不可能的任务,但幸运的是比特币网络已经拥有3EH/sec的处理能力,平均每10分钟就可以找到一个新区块。

难度表示

在例10-3中,我们在区块中看到难度目标,其被标为"难度位"或简称"bits"。在区块277,316中,它的值为 0x1903a30c。 这个标记的值被存为系数/指数格式,前两位十六进制数字为幂(exponent),接下来得六位为系数(coefficient)。在这个区块里,0x19为幂,而 0x03a30c为系数。

//计算难度目标的公式为:

target = coefficient \* 2^\(8 \* \(exponent – 3\)\)

//按十进制计算为:

=> target = 238,348 * 2^176^

=> target = 22,829,202,948,393,929,850,749,706,076,701,368,331,072,452,018,388,575,715,328

//转化为十六进制后为:

=> target = 0x0000000000000003A30C00000000000000000000000000000000000000000000

也就是说高度为277,316的有效区块的头信息哈希值是小于这个目标值的。这个数字的二进制表示中前60位都是0。在 这个难度上,一个每秒可以处理1万亿个哈希计算的矿工(1 tera-hash per second 或 1 TH/sec)平均每8,496个区块才能找到一个正确结果,换句话说,平均每59天,才能为某一个区块找到正确的哈希值。

难度目标与难度调整

如前所述,目标决定了难度,进而影响求解工作量证明算法所需要的时间。那么问题来了:为什么这个难度值是可调整 的?由谁来调整?如何调整?

比特币的区块平均每10分钟生成一个。这就是比特币的心跳,是货币发行速率和交易达成速度的基础。不仅是在短期 内,而是在几十年内它都必须要保持恒定。在此期间,计算机性能将飞速提升。此外,参与挖矿的人和计算机也会不断变化。

为了能让新区块的保持10分钟一个的产生速率,挖矿的难度必须根据这些变化进行调整。事实上,难度是一个动 态的参数,会定期调整以达到每10分钟一个新区块的目标。简单地说,难度被设定在,无论挖矿能力如何,新区块产生 速率都保持在10分钟一个。

自动调整

难度的调整是在每个完整节点中独立自动发生的。 每2,016个区块中的所有节点都会调整难度。难度的调整公式是由最新2,016个区块的花费时长与20,160分钟(即 这些区块以10分钟一个速率所期望花费的时长)比较得出的。难度是根据实际时长与期望时长的比值进行相应调整的 (或变难或变易)。简单来说,如果网络发现区块产生速率比10分钟要快时会增加难度。如果发现比10分钟慢时则降低 难度。

工作量证明的难度调整 源文件( pow.cpp文件钟的CalculateNextWorkRequired() 函数)

第43行函数 GetNextWorkRequired()// Limit adjustment step

// Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
    LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
    if (nActualTimespan < params.nPowTargetTimespan/4)
        nActualTimespan = params.nPowTargetTimespan/4;
    if (nActualTimespan > params.nPowTargetTimespan*4)
        nActualTimespan = params.nPowTargetTimespan*4;

    // Retarget
    const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
    arith_uint256 bnNew;
    arith_uint256 bnOld;
    bnNew.SetCompact(pindexLast->nBits);
    bnOld = bnNew;
    bnNew *= nActualTimespan;
    bnNew /= params.nPowTargetTimespan;

    if (bnNew > bnPowLimit)
        bnNew = bnPowLimit;

注意:虽然目标校准每2,016个块发生,但是由于Bitcoin Core客户端的一个错误,它是基于之前的2,015个块的总时间(不应该是2,016个),导致重定向偏差向较高难度提高0.05%。

参数Interval(2,016区块)和TargetTimespan(1,209,600秒即两周) 的定义在文件chainparams.cpp中。

简单总结就是

New Difficulty = Old Difficulty \* \(Actual Time of Last 2016 Blocks / 20160 minutes\)

为了防止难度的变化过快,每个周期的调整幅度必须小于一个因子(值为4)。如果要调整的幅度大于4倍,则按4倍调 整。由于在下一个2,016区块的周期不平衡的情况会继续存在,所以进一步的难度调整会在下一周期进行。因此平衡哈 希计算能力和难度的巨大差异有可能需要花费几个2,016区块周期才会完成。

提示:寻找一个比特币区块需要整个网络花费10分钟来处理,每发现2,016个区块时会根据前2,016个区块完成的时间对难度进行调整。

题外话

值得注意的是目标难度与交易的数量和金额无关。这意味着哈希算力的强弱,即让比特币更安全的电力投入量,与交易 的数量完全无关。换句话说,当比特币的规模变得更大,使用它的人数更多时,即使哈希算力保持当前的水平,比特币 的安全性也不会受到影响。哈希算力的增加表明更多的人为得到比特币回报而加入了挖矿队伍。只要为了回报,公平正 当地从事挖矿的矿工群体保持足够的哈希算力,"接管"攻击就不会得逞,让比特币的安全无虞。

目标难度和挖矿电力消耗与将比特币兑换成现金以支付这些电力之间的关系密切相关。高性能挖矿系统就是要用当前硅 芯片以最高效的方式将电力转化为哈希算力。挖矿市场的关键因素就是每度电转换为比特币后的价格。因为这决定着挖 矿活动的营利性,也因此刺激着人们选择进入或退出挖矿市场。

比如最近BTC大跌,矿机入不敷出,因此矿工减少,难度下降,电力消耗下降,营利增加。

成功构建区块

前面已经看到,Jing的节点创建了一个候选区块,准备拿它来挖矿。Jing有几个安装了ASIC(专用集成电路)的矿机, 上面有成千上万个集成电路可以超高速地并行运行SHA256算法。这些定制的硬件通过USB连接到他的挖矿节点上。接 下来,运行在Jing的桌面电脑上的挖矿节点将区块头信息传送给这些硬件,让它们以每秒亿万次的速度进行nonce测 试。

在对区块277,316的挖矿工作开始大概11分钟后,这些硬件里的其中一个求得了解并发回挖矿节点。当把这个结果放进 区块头时,nonce 4,215,469,401 就会产生一个区块哈希值:

0000000000000002a7bbd25a417c0374cc55261021e8a9ca74442b01284f0569

而这个值小于难度目标值:

0000000000000003A30C00000000000000000000000000000000000000000000

Jing的挖矿节点立刻将这个区块发给它的所有相邻节点。这些节点在接收并验证这个新区块后,也会继续传播此区块。当这个新区块在网络中扩散时,每个节点都会将它作为区块277,316加到自身节点的区块链副本中。当挖矿节点收到并验证了这个新区块后,它们会放弃之前对构建这个相 同高度区块的计算,并立即开始计算区块链中下一个区块的工作。

下节将介绍节点进行区块验证、最长链选择、达成共识,并以此形成一个去中心化区块链的过程。

你可能感兴趣的:(比特币之挖矿与共识(一))