比特币开发者指南(2)--挖矿

挖矿(Mining)

挖矿向区块链添加新的区块,使交易历史难以修改。当前挖矿有两种形式:

单独挖矿,就是矿工试图单独生成区块,块的收益和交易费用完全归他自己,允许他收到较大的分成收益(支付之间需要更长时间)。

矿池挖矿,其中矿池资源和其他矿工一块能更快的找到区块,矿池里的矿工共享收益,大致于它们共享的哈希运算能力有关,它们获得较小的分成收益(支付之间所需时间更短)。

 

单独挖矿

如下图所示,比较典型地,独立矿工使用bitcoind来从网络中获取新交易。他们的挖矿软件周期性地使用getblocktemplate轮询bitcoind,以提供币基交易所需要发送的新的交易列表和公钥。

比特币开发者指南(2)--挖矿_第1张图片

采矿软件使用模板(如下所述)构建一个块,并创建一个块头。然后它将80字节块头以及目标阈值(难度设置)一起发送到其挖矿硬件(ASIC)。挖矿硬件遍历块头 nonce的每个可能值,并生成相应的哈希值。

若没有哈希值低于阈值,挖矿硬件就从挖矿软件那得到一个具有新的merkle根的更新过的块头,这个新块头以添加额外的nonce数据到币基交易的币基字段方式创建。

另一方面,如果发现一个哈希低于目标阈值,挖矿硬件会返回一个具有成功nonce的块头给挖矿软件。挖矿软件组合块头和块并把这个完整的块发送给bitcoind,让其在网络中广播以添加到区块链上。

 

矿池挖矿

矿池挖矿遵循类似的工作流程,如下所示,它允许矿池管理者根据矿工的工作完成情况支付给他们。矿池使用bitcoin的从网路中获取新的交易。使用下面讨论的方法之一,每个矿工的 挖矿软件连接到矿池,并请求构建块头所需的信息。

比特币开发者指南(2)--挖矿_第2张图片

在矿池挖矿中,矿池设定目标阈值设置为比网络难度高几个数量级(更简单)。这导致挖矿硬件返回很多不适合区块链需要的哈希值的块头,但是此哈希值却低于矿池的目标阈值,来证明矿工参与了一部分求解合适哈希值的工作。

然后,矿工发送给矿池一个信息副本,矿池需要验证块头的哈希值低于目标,块头的merkle根所链接的交易块是满足矿池的目标的。(这通常意味着币基交易必须支付给矿池。)

矿工发送到矿池的信息成为共享信息,以此证明矿工参与了部分工作。矿池偶尔会接收到一些共享信息也低于网络目标阈值,那矿池就会发送它们到网络上以便能添加到区块链上。

挖矿的区块奖励和交易费支付给矿池。矿池根据矿工的贡献支付一部分收益给个体矿工。例如,如果矿池的目标阈值比网络 目标阈值低100倍,则100股将需要平均生成以创建成功的块,所以矿池可以为每个收益者支付1/100。不同的矿池使用基于这种基本共享系统的不同的奖励分配方案。

 

块原型

无论单独挖矿和矿池挖矿,挖矿软件都需要获取必要信息来构造块头.本小节以线性方式描述了信息的传输和使用。然而,在实际实现中,使用并行线程和队列来保持ASIC哈希运算以最大能力工作。

 

网络RPC

最简单和最早的方法是现在已经弃用的Bitcoin Core getwork RPC,它为矿工直接构建了一个块头。由于标头仅包含一个4字节的随机数,对于大约4个gigahash,许多现代矿工需要制作数十或数百个getwork请求一秒。独立矿工仍然可以在v0.9.5或更低版本上使用getwork,但是今天的大多数矿池都会阻止或禁止使用。

 

getblocktemplate RPC

一个改进的方法是Bitcoin Core getblocktemplate RPC。这为挖矿软件提供了更多信息:

1. 构造一个支付给矿池或独立矿工的bitcoind钱包的币基交易所需要的信息。

2. bitcoind或矿池所推荐的交易记录的完整备份,可以用于挖矿软件检查交易,可选地增加额外交易和删除不必要的交易。

3. 构建下一个块的块头所需的其他信息:块版本,以前的块散列,以及比特(目标)。

4. 矿池的当前目标阈值用于接受分成收益。(对于独立矿工来说,这就是网络 目标。)

使用收到的交易记录,挖矿软件想币基额外nonce字段里面添加nonce值,并转化所有的交易到一个merkle树,这棵树有一个可以在块头使用的merkle根。每当额外的nonce字段需要改变时,挖矿软件都会重建merkle树的必要部分,并更新时间及块头中的merkle根字段。

 像所有bitcoind RPC一样,getblocktemplate也是通过HTTP发送的。为了确保最大工作量,大多数矿工使用HTTP longpoll可以始终保持getblocktemplate请求打开。这允许矿池,一旦矿工在P2P中发布一个新快,尽快推送一个新的getblocktemplate给矿工或矿池希望发送更多的交易记录给挖矿软件。

 

层次挖矿协议

getblocktemplate的广泛使用的替代方法是层次挖掘协议。层次挖矿协议专注于提供给矿工自己构建块头所需的最小信息:

1. 构建支付矿池的币基交易所需的信息。

2. 当币基交易更新一个新的额外的nonce值时候需要再求哈希去创建一个新的merkle根的merkle树的一部分。merkle树的其他部分(如果有的话)可以不发送

,基于当前交易的规模可以有效限制发送的数据量至多约1千字节。

3. 所有其他构造下一块的块头所需要的非markle根信息。

4. 采矿池的当前目标阈值用于接受分成收益。

收到币基交易,挖矿软件将一个nonce值添加到币基额外的nonce字段中,求币基交易的哈希并添加到merkle树的接收部分。对整棵树求哈希以创建一个merkle根,树根被添加到接收到的块头里面。每当额外的nonce字段需要改变,挖矿软件对币基交易更新和再求哈希,重建merkle根,更新块头的markle根字段。

与getblocktemplate不同,使用Stratum的矿工无法检查或添加交易到他们目前挖矿的区块。与getblocktemplate不同,Stratum协议直接使用双向TCP套接字,所以矿工当一个新块被广播到P2P网络中时候不需要使用HTTP longpoll来确保它们立刻从矿池获取更新。

资源:GPLv3许可的BFGMiner采矿软件和AGPLv3许可的Eloipool 采矿池软件在矿工和池中广泛使用。MIT许可的libblkmaker C库和python-blkmaker库可以为您的程序解释GetBlockTemplate。

你可能感兴趣的:(比特币)