主页 > imtoken钱包苹果版下载官网 > 共识算法PoW的算力和挖矿难度

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

大家好,我叫于双琪。本文是关于区块链共识算法的系列文章。在上一篇《共识算法PoW的由来》中,我们解释了工作量证明的基本原理,其核心是使用蛮力法找到一个满足难度值的随机数。这篇文章解释了比特币的计算能力。通过本节,您可以掌握算力的概念,了解算力带来的悲剧。

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

算力

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

Hash(Block+Nonce)

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

比特币算力

上图是当前比特币算力图表[2]。到 2017 年,比特币挖矿所需的计算能力猛增。这与新矿机不断涌入市场有关——这些矿机采用新技术,算力更强在单位挖矿如何解释,即单位成本算力增长较快,带来了整体的提升。计算能力。

算力单位

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

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

因子名称符号

10^24

约塔

是的

10^21

在单位挖矿如何解释

泽塔

Z

10^18

例如

E

10^15

宠物

P

10^12

T

10^9

千兆

G

10^6

超级

在单位挖矿如何解释

M

10^3

公斤

k

10^2

百合

h

10^1

德卡

挖矿难度动态调整

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

难度值表示找到一个随机数需要多长时间。时间越长,计算机需要执行哈希计算的次数就越多。普通笔记本每秒可以进行 800 次哈希运算,中端显卡可以进行 2000 多次计算。

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

挖矿难度计算公式

在单位挖矿如何解释

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

$D = T_1/T$

字母T是Target Abbreviation在单位挖矿如何解释,字母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

第一个A位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),长度超过3位,不补零,压缩结果为:0x1d00FFFF。因为压缩后的存储容量只有4个字节,前两个字节已经被长度和添加的00占用了,只剩下2个字节来存储数字,所以接下来的26个FF值就被丢弃了。

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

在单位挖矿如何解释

0x00000000FFFF0000000000000000000000000000000000000000000000000000

这个数字在解压的时候被截断了,不再是原来的$$2^{256-32}-1$$,比特币的$$T_1$$值就是这个0x1d00FFFF,如果block里面的bits就是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秒内求出,也就是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)

p>

本文参与Chainlink社区写作激励计划,好文好收入,欢迎阅读加入。