主页 > imtoken苹果版下载官网怎样下载 > 共识算法PoW的算力与挖矿难度

共识算法PoW的算力与挖矿难度

大家好,我是余双奇,本文是关于区块链共识算法系列文章。 在上一篇《共识算法PoW的由来》中,我们讲解了工作量证明的基本原理。 核心是用穷举法暴力寻找一个满足难度值的随机数。 这篇文章解释了比特币的计算能力。 通过这一部分,你可以掌握算力的概念,了解算力造成的悲剧。

大家好,我是余双奇,本文是关于区块链共识算法系列文章。 在上一篇《共识算法PoW的由来》中,我们讲解了工作量证明的基本原理。 核心是用穷举法暴力寻找一个满足难度值的随机数。 这篇文章解释了比特币的计算能力。 通过这一部分比特币难度值计算公式,你可以掌握算力的概念,了解算力造成的悲剧。

比特币的难度是什么_比特币难度值计算公式_比特币全网难度走势

计算能力

比特币挖矿就像猜数字。 矿工需要找到一个随机数(Nonce)参与哈希运算[1]

Hash(Block+Nonce)

使区块哈希值满足难度要求。 计算能力是指计算机每秒可以进行哈希运算的次数,也称为哈希率(hashrate)。

比特币算力

上图是当前比特币算力走势图[2]。 到 2017 年,比特币挖矿所需的计算能力猛增。 这与不断研发新的矿机投入市场有关——这些矿机采用新技术,拥有更强的算力比特币难度值计算公式,即单位成本下的算力增长迅速,带来了算力的增加。综合计算能力。

算力单元

算力以每千位为一个单位进行划分,最小单位为H=1次,其他划分为:

如果不知道单位的缩写,可以查看下面的国际单位前缀表[3]:

因子名称符号

10^24

尤塔

10^21

泽塔

Z

10^18

exa

E、

10^15

善待动物组织

比特币难度值计算公式_比特币全网难度走势_比特币的难度是什么

P

10^12

特拉

10^9

千兆

G

10^6

巨型

10^3

公里

k

10^2

H

10^1

德卡

挖矿难度计算挖矿难度Difficulty动态调整

比特币全网难度走势_比特币的难度是什么_比特币难度值计算公式

上图红线是比特币从推出到现在的难度值变化图。 可以看出,难度一直在增加,难度越大,矿工找到随机数的时间就越长。 同时可以观察到难度值是周期性调整的。 这是因为比特币协议预计每十分钟产生一个区块,而 2016 年的区块需要两周才能完成。 每2016个区块,全网节点根据前2016个区块的支付时间自动调整难度值。 如果超过两周,则降低难度,否则增加难度。 为了保持一个块是10分钟。 更多图表数据可在bitcoinwisdom网站查看。

难度值代表了寻找随机数的耗时程度,耗时越长,计算机需要进行哈希计算的次数就越多。 普通笔记本电脑每秒可以进行 800 次哈希运算,中端显卡可以进行 2000 多次哈希运算。

比特币的难度是什么_比特币难度值计算公式_比特币全网难度走势

中本聪在自己的电脑上挖出了创世区块(比特币区块链的第一个区块)。 本来,中本聪设计了一个公平的、完全去中心化的数字货币系统,每个人都可以用个人电脑来挖矿(他还预言网络上会有挖矿服务商(矿池))。 但是在盈利的时候,不断有大量新的算力加入,矿工之间的竞争激烈,以至于单个矿工的挖矿成功率几乎为零。 2011年开始出现矿池,大量矿工加入矿池稳定收益,摊薄成本。 大量算力的融合,使得比特币的挖矿难度越来越大。 数字货币挖矿行业就像一场军事竞赛。 挖矿设备不断更新迭代,不再遵循摩尔定律。 专业矿机针对哈希算法、散热、能耗进行了优化,背离了比特币网络节点运行数千次普通计算、公平参与挖矿的初衷。 矿池占用的算力也让比特币的风险始终存在:51%算力攻击。

挖矿难度计算公式

找到一个随机数需要多少算力取决于当前区块的挖矿难度。 难度越大,需要的计算能力就越大。 但是,挖矿难度不包含在区块信息中。 它只是根据规则在网络节点中动态计算。 公式如下:

$D = T_1/T $

字母T是Target的缩写,字母D是DiFFiculty的缩写。 $T_1$和T都是一个256位的大数,其中$T_1$是一个非常大的常数$2^{256-32}-1=2^224-1$。 根据公式,T越小,挖矿难度D越大。

根据公式,当T=0时,D为无穷大,即无法计算结果。 好在T不会为0,最小值为1,此时难度值最大,为$2^{256-32}-1=2^224-1$。 当$T = T_1$时,难度值为最小值1。

目标值 目标与挖矿难度换算

为了方便人类直观估计难度,比特币协议将大数T压缩成浮点数记录在区块头中,字段为bits。

如果一个块的目标值是0x1b0404cb,它会被转换成一个目标值$$0x0404cb * 256^{0x1b-3}$$

T采用类浮点压缩表示[4]进行压缩,压缩计算过程如下:

将数字转为256进制,如果第一位大于127(0x7f),则在前面加0。 压缩结果中的第一位存储了 256 进制数的位数。 后三位存放256进制数的前三位,不足三位则从后面补零。

例如,要压缩数字1000,首先将其转换为256的数字: $$1000=0x03 256^{2-1} + 0xe8 256^{1-1}$$ 结果为[0x03,0xe8]。 如果第一个数不超过0x7f,则可以不填0。但是两位长度小于三位,后面补零,最终表达式为:0x0203e800。

再比如数字$$2^{256-32}-1$$,转换为256的十六进制:

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

第一个数字0xFF大于0x7f,所以前面加零后就变成了:

00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

其长度等于28+1=29(0x1d),长度超过三位,不补零,压缩结果为:0x1d00FFFF。 因为压缩后的存储容量只有4个字节,前两个字节已经被长度和添加的00占用,只剩下2个字节存储数字,所以后面的26个FF值被丢弃。

如果我们对压缩后的结果0x1d00FFFF进行解压,它还会是原来的值吗? 事实上,结果是:$$T=0x00FFFF × 256 ^{0x1b−3}$$ =

0x00000000FFFF0000000000000000000000000000000000000000000000000000

这个数字在解压的时候被截断了,不再是原来的$$2^{256-32}-1$$了。 比特币的 $$T_1$$ 值就是这个 0x1d00FFFF。 如果区块中的比特位为0x1d00FFFF,则表示该区域的区块挖矿难度为最小挖矿难度1。

事实上,专业的矿池程序保留了截断的 FF:

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

我们称上述号码池难度为1(pool diFFiculty 1)。 所以根据公式,区块目标值的挖矿难度为0x1b0404cb,在挖机上看到:

比特币的难度是什么_比特币难度值计算公式_比特币全网难度走势

D = 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF /  
      0x00000000000404CB000000000000000000000000000000000000000000000000
    = 16307.669773817162 (pdiFF)

称为 pdiFF。 但有些比特币客户端可能无法精确到这么大的尺寸,所以尾随的 FF 没有保留:

0x00000000FFFFFF0000000000000000000000000000000000000000000000000000

此时挖矿难度为:

D = 0x00000000FFFF0000000000000000000000000000000000000000000000000000 /
    0x00000000000404CB000000000000000000000000000000000000000000000000 
  = 16307.420938523983 (bdiFF)

称为 bidFF。

在哪里可以查看当前的比特币挖矿难度

您可以在一些提供服务的网站上查看图表数据,例如:

下图是撰写本文时比特币区块 546336 的摘要。

如何根据难度值计算算力

既然我们知道了挖矿难度是如何计算的,那么需要进行多少次哈希运算才能找到随机数才能挖出一个区块,使得该区块的哈希值小于目标值呢?

之前已经确定$T_1=0x1d00FFFF$,解压后为$:0xFFFF×2^208$,对于难度D的目标值:

比特币的难度是什么_比特币难度值计算公式_比特币全网难度走势

因此,估计挖出一个难度为D的区块所需的哈希数为:

比特币的难度是什么_比特币全网难度走势_比特币难度值计算公式

目前的难度计算速度要求是在10分钟内找到,即在600秒内完成计算,也就是说最低的网络算力必须是:

比特币难度值计算公式_比特币的难度是什么_比特币全网难度走势

根据上面的计算,当D=1时,每秒需要计算7158278个哈希,即:7.15Mhahs/s。

目标值计算源码

比特币的难度是什么_比特币难度值计算公式_比特币全网难度走势

调整难度时,调整的是目标值。 目标值的计算公式如下,但在实际计算中有一些特殊处理,将目标值控制在一定范围内。

新目标值= 当前目标值 * 实际2016个区块出块时间 / 理论2016个区块出块时间(2周)。 

计算过程,Go代码如下,点击

var (
    bigOne = big.NewInt(1)
    // 最大难度:00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,2^224,0x1d00FFFF
    mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne)
    powTargetTimespan = time.Hour * 24 * 14 // 两周
)
func CalculateNextWorkTarget(prev2016block, lastBlock Block) *big.Int {
    // 如果新区块(+1)不是2016的整数倍,则不需要更新,仍然是最后一个区块的 bits
    if (lastBlock.Head.Height+1)%2016 != 0 {
        return CompactToBig(lastBlock.Head.Bits)
    }
    // 计算 2016个区块出块时间
    actualTimespan := lastBlock.Head.Timestamp.Sub(prev2016block.Head.Timestamp)
    if actualTimespan < powTargetTimespan/4 {
        actualTimespan = powTargetTimespan / 4
    } else if actualTimespan > powTargetTimespan*4 {
        // 如果超过8周,则按8周计算
        actualTimespan = powTargetTimespan * 4
    }
    lastTarget := CompactToBig(lastBlock.Head.Bits)

比特币难度值计算公式_比特币全网难度走势_比特币的难度是什么

// 计算公式: target = lastTarget * actualTime / expectTime newTarget := new(big.Int).Mul(lastTarget, big.NewInt(int64(actualTimespan.Seconds()))) newTarget.Div(newTarget, big.NewInt(int64(powTargetTimespan.Seconds()))) //超过最多难度,则重置 if newTarget.Cmp(mainPowLimit) > 0 { newTarget.Set(mainPowLimit) } return newTarget }

测试代码如下,计算是出块高度为497951+1时计算的新目标值。

func TestGetTarget(t *testing.T) {
    firstTime, _ := time.Parse("2006-01-02 15:04:05", "2017-11-25 03:53:16")
    lastTime, _ := time.Parse("2006-01-02 15:04:05", "2017-12-07 00:22:42")
    prevB := Block{Head: BlockHeader{Height: 497951, Bits: 0x1800d0f6, Timestamp: lastTime}}
    prev2016B := Block{Head: BlockHeader{Height: 495936, Bits: 0x1800d0f6, Timestamp: firstTime}}
    result := CalculateNextWorkTarget(prev2016B, prevB)
    bits := BigToCompact(result)
    if bits != 0x1800b0ed {
        t.Fatalf("expect 0x1800b0ed,unexpected %x", bits)
    }
}

比特币哈希算法使用 SHA256 进行工作证明。 在比特币上实时查看比特币算力。 二进制浮点运算的 IEEE 标准 (IEEE 754)

本文参与登联社区写作激励计划,好文章好收益,欢迎正在阅读的你加入。