【区块链开发指南】区块链基础之挖矿和矿池

什么是挖矿?

讨论到比特币时,经常会提到的一个名词就是“挖矿”,那么挖矿到底是什么呢?它的详细过程又是怎么的呢?对于我个人而言,以前我知道所谓挖矿大概就是要找一个随机数,使得区块的哈希值小于某个数,但具体是怎样的呢?不知道。。。当然,还不仅如此,很多其他的概念像区块的结构、交易的结构、脚本的类型、P2SH这些概念具体内容到底是什么,其实还是很模糊,只知道大概有某些内容,所以这系列的总结也是为了让自己对这些基本概念有个更加精确的理解。

在区块头中有一个Nonce,关于区块头的结构可以参考上一篇文章,挖矿的目标就是要寻找这个Nonce,使得满足以下等式:SHA256(SHA256(block header)) < current target。 而Nonce的大小是4个字节,能表示的范围也就是[0,2^32-1],这个与最终哈希值的范围相差太大了,那么当Nonce枚举到了2^32-1之后该怎么做呢?比特币采取的方法是,在每个区块的第一个交易,也就是Coinbase交易中有一个特殊的输入叫“coinbase”,这个参数中可以保存任意内容而不会被使用,所以比特币在这个参数里又设置了一个新的参数叫extraNonce(2-100字节),当block header中的Nonce溢出时,extraNonce就会发生变化,而extraNonce发生变化时Coinbase交易的哈希值也就发生了变化,然后传递到Merkle tree中,Merkle tree的根也就发生了变化,从而导致block header中的另一个变量也发生了变化,那么Nonce又可以重新枚举。除此以外,矿工还能通过修改时间戳来重新枚举Nonce。这几个参数共同作用才使得上述等式必然有解。

挖矿难度

挖矿难度也就是对上述current target的一个描述,用来表示矿工寻找满足条件的Nonce的难易程度,难度每隔2016个区块就会改变一次,每个区块10分钟,也就是大约两周的时间。难度的计算公式为:

difficulty=difficulty_1_target/current_target

其中 difficulty_1_target表示难度为1时的目标哈希值,除以当前目标哈希值,就是当前的难度。公式比较容易理解,难度为1相当于是所有解空间的大小,除以当前解空间的大小,来表示难度。在比特币当中,难度1被定义为 0x1d00ffff,比特币通过一个自定义的格式将这个32位的整数转换成256位的数值,

0x00ffff * 2**(8*(0x1d - 3)) = 0x00000000FFFF0000000000000000000000000000000000000000000000000000

在前一章中我们知道,block header中有一个字段叫Bits,用来保存的就是当前的难度,长度为32位,实际上它就是一个256位哈希的压缩形式,假设当前Bits0x1b0404cb,那么对应的256位哈希为

0x0404cb * 2**(8*(0x1b - 3)) = 0x00000000000404CB000000000000000000000000000000000000000000000000

这也就是上面公式中的current_target,此时难度difficulty就应该为,

0x00000000FFFF0000000000000000000000000000000000000000000000000000 /
0x00000000000404CB000000000000000000000000000000000000000000000000 
= 16307.420938523983 (bdiff,比特币难度)

根据这个计算方式,对难度一个更专业的表达是,difficulty的含义是平均需要计算difficulty*2^32次哈希才能找到一个解。当然这也只是比特币源码中定义的计算方式,在实际的矿池中,它们将难度为1定义为0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF。那么它们计算的难度就应该为,

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF /
0x00000000000404CB000000000000000000000000000000000000000000000000 
= 16307.669773817162 (pdiff,矿池难度)

关于难度更详细的介绍请参考:https://en.bitcoin.it/wiki/Difficulty,当前难度可以通过https://blockexplorer.com/api/status?q=getDifficulty获得,下一难度可以通过https://blockexplorer.com/api/status?q=estimate获得,难度变化可以通过http://bitcoin.sipa.be/查看。

算力

由于比特币对哈希压缩形式的定义方式,使得难度的哈希值前32位始终为0,那么就相当于浪费了32位的数值,所以最终难度要乘以2^32才表示寻找一个区块平均的哈希次数。而区块产生的速度是平均每10分钟1个,也就是600秒,意味着网络平均的哈希速率,也就是算力为Difficulty*2^32/600,这也是一般我们用来计算全网算力的近似表达式。根据https://blockexplorer.com/api/status?q=getDifficulty网站数据,当前难度为1347001430558.57,那么全网算力近似为9.642*10^18 hash/s。目前一台S9蚂蚁矿机的算力是13T/s,单独挖一个比特币需要1347001430558.57*2^32 /(13*10^12) = 445025160秒,也就是需要5150天。由此可见,现在对于单个矿工来说,每天的收益微乎其微,所以这也就导致了矿池的产生。

矿池

矿池的目标是稳定矿工的收益,降低矿工收益的方差。在一个矿池里,矿工通过贡献自己的算力,然后按照比例来分发收益,而矿工贡献的方式就是通过提交share,每一个share都有一定的概率是最终的有效解,所以这个share也就是矿工自己工作量证明,并且很短的时间内就能找到一个share。

你可能感兴趣的:(区块链开发指南)