字段 | 大小 | 格式 | 描述 |
---|---|---|---|
Version | 4 字节 | 小端序 | 区块版本号 |
Previous Block | 32 字节 | 自然字节序 | 前一个区块的区块哈希 |
Merkle Root | 32 字节 | 自然字节序 | 区块中包含的所有交易ID的默克尔根 |
Time | 4 字节 | 小端序 | 当前时间的 Unix 时间戳 |
Bits | 4 字节 | 小端序 | 目标值的紧凑表示 |
Nonce | 4 字节 | 小端序 | 随机数,用于尝试找到有效哈希 |
Transaction Count | 动态 | compact size | 区块中包含的交易数量 |
Transactions | 动态 | 交易数据 | 区块中包含的所有原始交易数据 |
Bits
字段当前目标值的压缩格式。原始目标值是 32 字节, 通过压缩成 4 字节的 Bits
字段, 可以节省区块头的空间。
转换
Bits
字段占据4个字节, 由指数和系数组成。指数占据一个字节, 系数占据三个字节。
Bits
转换为目标值
为方便验证, 先介绍如何将 Bits
转换为目标值。
如下是区块 860636 的区块头数据
Bits
字段是 0x5b250317
, 转换为正常字节序为 0x1703255b
。
指数是 0x17
即10进制的 23, 系数是 0x03255b
。
一开始, 假设目标值是 32 字节的 0 构成:
将系数左移指数个字节, 即左移23个字节, 即得到目标值:
由此可以得到 0x5b250317
对应的目标值是:
目标值转换为Bits
将目标值转换为 Bits
, 需要找到第一个非零字节并往后取3个字节, 然后计算其左移的字节数。
以上面的目标值为例, 第一个非零字节是 0x03
, 包括其自身在内的后三个字节是 0x03255b
, 左移了 23 个字节, 转换为 16 进制为 0x17
。
得出 Bits
字段为 0x1703255b
。
如果第一个非零字节值大于或等于 0x80
, 则需要往前进一个字节, 以确保系数不会被解释为负数。 例如目标值是
第一个非零字节是 0x80
, 往前进一个字节后, 系数为 008004
, 左移了 29 个字节, 转换为 16 进制为 0x1d
。
得出 Bits
字段为 0x1d008004
。
比特币使用自定义的 uint256
编码, 当系数大于 0x800000
时会被解释为负数。而目标值显然不能为负数。
0x800000
转换为二进制为 1000 0000 0000 0000 0000 0000
二进制的最高位是符号位, 设置为 1 表示负数。
-
系数只取 3 个字节可能会导致无法表达完整的目标值。但总体上还是接近目标值, 只是有一些精度上的损失, 并没有太大的影响。
-
节点内部会计算完整的目标值。
相关RPC
参数名 | 类型 | 必选 | 默认值 | 描述 |
---|---|---|---|---|
template_request | json | {} | 控制区块模板返回的内容 |
名称 | 类型 | 描述 |
---|---|---|
version | string | 区块版本号 |
previousblockhash | string | 前一个区块的哈希 |
curtime | number | 当前时间戳 |
target | string | 目标值 |
bits | string | 目标值的压缩格式 |
height | number | 区块高度 |
transactions | array | 建议包含的交易列表 |
名称 | 类型 | 描述 |
---|---|---|
n | number | 当前难度值 |