1、最大难度目标
中本聪规定:
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
为最大目标值,区块要被比特币网络接受其哈希值必须要小于最大目标值。
2、难度目标的存储
以压缩格式存储在区块头部的nbits字段中,公式如下:
target = coefficient*2^(8*(exponent-3))
例如创世块的难度目标为:0x1D00FFFF,根据公式展开为:
0x00FFFF * 2^(8*(0x1D-3)) = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
可见压缩后精度是有损失的。不过这个也无关紧要。
(8*(exponent-3))/4 = 2*(exponent-3) 可以得出十六进制难度系数后面有多少个0。
0x1D00FFFF 展开后 系数00FFFF后面可以算出有52个0。
3、难度目标的调整
比特币设定为每10分钟生成一个区块,每2016个区块,自动调整一次难度。
难度调整的公式为:
新难度值 = 旧难度值 * (之前2016个区块花费时长(单位秒) / 2016*10*60)
不难看出这个公式的意思是:如果当前算力比较大、出块的速度比较块,那么就加大挖矿难度,反之就降低挖矿难度。
4、难度目标的计算
先来一个小程序扫描一下区块网络中的难度信息。
通过命令 curl -s https://chain.api.btc.com/v3/block/0 来获取区块信息,然后解析出相关的难度信息。
btc.com不太稳定,有时会返回失败。可以多试几次。
// xmain.c
// by maxzero
#include "xutils.h"
int grab_block_info(int block_num, char *block_buf, int block_len)
{
FILE* f = NULL;
int n = 0;
int r = 0;
char url[1024];
char* buf = NULL;
int len = 0;
memset(url, 0x00, sizeof(url));
sprintf(url, "curl -s https://chain.api.btc.com/v3/block/%d", block_num);
f = popen(url, "r");
buf = block_buf;
len = block_len