主页 > imtoken限制中国用户该咋办 > 说说比特币的“全网难度”

说说比特币的“全网难度”

最近,很多朋友问我如何理解比特币的“全网难度”。每个人都在纠结这个东西是什么,它意味着什么,以及它是如何调整的。本文将尝试澄清这些问题。

0.基础知识

请先对区块链、比特币、比特币挖矿有所了解。

1.区块头结构及挖矿

比特币区块头共80字节

struct header_structure {      // BYTES   NAME
 uint32_t nVersion;            // 4       version
 uint8_t hashPrevBlock[32];    // 32      previous block header hash
 uint8_t hashMerkleRoot[32];   // 32      merkle root hash
 uint32_t nTime;               // 4       time
 uint32_t nBits;               // 4       target
 uint32_t nNonce;              // 4       nonce
};

比特币区块头结构

简单地说

比特币难度查询

2.目标值(目标)

区块头中的Bits字段标识Hash后应该小于或等于当前区块头的目标值(target)。注意块头的SHA256结果有256位,而Bits只有32位(4字节)。 Bits 通过以下操作获得目标。以277316区块为例

Bits的值为0x1903a30c(十进制的419668748),这个值以系数/指数格式存储,前2位十六进制数字为幂,后面取6位为系数。在此块,0x19为指数,0x03a30c为系数比特币难度查询,计算公式为

target = coefficient * 256^(exponent – 3)

所以这个块的目标值为

target = 0x03a30c * 256^(0x19 - 3)
       = 238,348 * 256^22
       = 22,829,202,948,393,929,850,749,706,076,701,368,331,072,452,018,388,575,715,328

十六进制为 0x0000000000000003a30c0000000000000000000000000000000000000000000

比特币难度查询

即有效块的高度为 277316 头信息的哈希值必须小于或等于这个目标值。区块高度277136的hash值其实是0x0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b31b2cc7bdc4

3.难度(难度)

Satoshi Nakamoto在创世区块中可以看到Bits为0x1d00ffff(小数点为48660479时9),难度(difficulty)为1(注意区块头中没有存储难度字段)

根据Bits计算得到的目标是0x00ffff * 256^26,即0x00000000ffff0000000000000000000000000000000000000000000000000。也就是说,为了构造下一个合法区块,需要不断地对区块头进行SHA256运算,直到找到区块头的Hash结果,并且前32位都是0(小于目标)

SHA256运算的结果被认为是一致的随机序列。可以说SHA256结果中某位的值是0或者1的概率是一样的,所以做一次计算,满足以上条件(前32位都是0)的概率为1 / (2^32),即平均需要2^32次运算才能找到这个值

为了便于理解,我们定义为了使区块头的SHA256结果小于某个目标值(target)而要尝试的平均计算次数,作为难度,1难度≈2^32次= 4294967296 次 ≈ 4.2 * 10^9 次 ≈ 4G 操作

以几天前的区块501509为例,Bits值为0x18009645(十进制为402691653),目标是0x009645 * 256^21。创世块的目标是0x00ffff * 256 ^ 26,难度为1,因此获得区块501509的难度为

比特币难度查询

(0x00ffff * 256 ^ 26)/ (0x009645 * 256 ^ 21)
= 65535/38469 * (256^5)
= 1.703579505575918 * 2^40
= 1873105475221.611
≈ 1.87 * 10^12

即1.@ >87T (1T = 10^11.6@>

1.7@>

方块高度#501509

综上,可以得出公式

1.8@>

其中,target_genesis块为固定值0x00000000ffff00000000000000000000000000000000000000000000000000,target_目前是根据当前块头中的Bits字段计算得到

比特币难度查询

同时可以得出另一个结论

1.9@>

当前比特币网络难度1.93T,全网算力15.32EH/s(15.32E每秒哈希次数),计算出块时间为关于

1.93T * 2^32 / 15.32EH/s
= 1.93 * 10^12 * 4.295 * 10^9 / 15.32 * 10^18
= 8289.35 * 10^18 / 15.32 * 10^18
≈ 541 秒

总结

4.难度调整

如前所述,区块头目标哈希值(target)决定了难度(difficulty),进而影响比特币的出块时间。按照设计,比特币应该保证每10分钟的平均出块速度比特币难度查询,这是发行新币和完成交易的基础,需要长期保持相对稳定。

比特币难度查询

挖矿设备不断更新淘汰,矿工不断加入和流失,导致全网算力实时变化,但整体上在不断提升。为了保证比特币的平均出块时间稳定在十分钟,需要定期调整难度。

难度调整逻辑写在代码中,在每个全节点中独立自动发生。每产生 2016 个区块,网络中的所有全节点都会调整难度。难度调整公式由生成最新的 2016 块所需的时间与 20160 分钟(两周,即以 10 分钟的速率生成这些块的预期时间)进行比较。难度是基于实际时间与预期时间的比率。调整(或更难或更容易),简单来说,如果网络发现出块速度快于 10 分钟,则增加难度。如果发现慢于 10 分钟,则降低难度。

这个逻辑可以简单表示为

Difficulty_新 = Difficulty_原 * ( 20160分钟 / 产生2016个区块的实际花费时长 )

从代码中可以看出,为了防止难度变得太快,在每个周期调整的时候,如果需要调整幅度超过4倍,就只调整4倍(难度是调整为原来的4倍或1/4)调整

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
    if (params.fPowNoRetargeting)
        return pindexLast->nBits;
    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
    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;
    bnNew.SetCompact(pindexLast->nBits);
    bnNew *= nActualTimespan;
    bnNew /= params.nPowTargetTimespan;
    if (bnNew > bnPowLimit)
        bnNew = bnPowLimit;
    return bnNew.GetCompact();
}

再次请注意,难度调整是通过调整区块头中的Bits字段来实现的。区块头不直接存储全网的难度(难度)。字段

5.总结

说到这里,相信你已经知道文章开头问题的答案了。简单来说就是比特币全网的难度(难度)

6.参考