PoW 验证
目录
PoW 验证概述
验证的目的
确保:
1. 区块包含充分的工作量证明
2. 找到有效区块需要大量计算
3. 防止低成本的伪造区块
验证过程很快(毫秒级)
但创建区块需要平均 10 分钟验证流程
1. 检查区块头格式
✓ 所有字段都存在
✓ 大小符合要求
2. 检查难度目标
✓ 目标值在允许范围内
3. 计算区块哈希
hash = SHA256(SHA256(block_header))
4. 比较哈希与目标
if hash < target:
✅ PoW 有效
else:
❌ PoW 无效难度目标
Bits 字段
区块头中的难度用 "bits" 表示:
格式:紧凑表示(4 字节)
例:
bits = 0x1d00ffff
解码:
前 1 字节(0x1d)= 指数
后 3 字节(0x00ffff)= 系数
target = coefficient × 2^(8 × (exponent - 3))
= 0x00ffff × 2^(8 × (0x1d - 3))
= 0x00ffff × 2^(8 × 26)难度的限制
最大目标(最小难度):
0x00000000FFFF0000000000000000000000000000000000000000000000000000
bits = 0x1d00ffff
难度 = 1
对应初始挖矿
最小目标(最大难度):
理论上可以任意低
实际由网络当前难度决定目标与难度的关系
difficulty = max_target / current_target
例:
当前 bits = 0x17000000
目标 = 0x00000000000000000000000000000000000000000000000017000000000000
max_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
difficulty = max_target / target ≈ 65,536 / (0x17)
≈ 3,864 (相对初始)哈希检查
哈希计算
过程:
1. 序列化区块头(80 字节)
version + prev_hash + merkle_root + timestamp + bits + nonce
2. 第一次 SHA-256
h1 = SHA256(serialized_header)
3. 第二次 SHA-256
hash = SHA256(h1)
4. 比较(小端序)
将 hash 转换为整数
检查 hash < target字节顺序
比特币中的复杂性:
内部计算:大端序(网络字节序)
比较时需小端序
例:
hash = 0x0000000012345678 (大端)
作为整数:0x12345678
与 target 比较(两个都转为整数)共识
全节点验证
每个节点都验证:
1. 所有交易有效
2. PoW 有效
3. 区块符合共识规则
所有节点使用相同规则
→ 达成一致
→ 形成单一真实的链最长链规则
选择标准:
1. 最长的有效链
2. 相同长度时选第一个看到的
意义:
修改历史区块需要重新计算该块之后的所有 PoW
成本极高
安全性依赖:
PoW 算力分散
多数诚实攻击与防护
51% 攻击
定义:
攻击者控制多数算力
可以:
1. 重组最近的区块
2. 执行双花
3. 审查交易
防护:
1. PoW 成本很高
2. 需要大量电力和硬件
3. 检测和响应机制其他攻击
Selfish Mining:
矿工隐藏区块,等待找到连续两个
试图获得不公平优势
防护:网络传播和快速验证
Eclipse 攻击:
隔离某个节点
防护:使用多个 P2P 连接
时间攻击:
伪造区块时间戳
防护:时间戳必须在中位数时间后常见问题
Q1: PoW 为什么必须这么难?
A:
- 保护网络成本很高
- 防止便宜的攻击
- 维护去中心化
Q2: 能加快验证速度吗?
A:
- 无法加快 SHA-256
- 但可以并行验证多个区块
- 或预验证(assume valid)
Q3: 为什么用两次 SHA-256?
A:
- 增加安全性
- 防止某些已知弱点
- 比特币的历史设计
Q4: 如果挖矿变得太容易怎么办?
A:
- 难度会自动调整
- 每 2 周检查一次
- 维持 10 分钟平均出块时间
Q5: 区块链有多安全?
A:
- 取决于确认数
- 6 确认:99.9% 安全
- 100+ 确认:极其安全
