区块用 hash 链接成链表,篡改任何历史区块都会断开链条——这就是区块链"不可篡改"的工程实现。
16.2.1 什么是"链"
graph LR
G[创世块] --> B1[区块1] --> B2[区块2] --> B3[区块3] --> Bx[...]
G -.-> |包含| GH[prevHash=000000..]
B1 -.-> |prevHash==hash(G)| hash1
B2 -.-> |prevHash==hash(B1)| hash2
B3 -.-> |prevHash==hash(B2)| hash3
style G fill:#fff3e0
style B1 fill:#e8f5e9
style B2 fill:#e8f5e9
style B3 fill:#e8f5e9
关键代码(分拆 Python 版核心逻辑):
python
# 区块头哈希计算
import json, hashlib
def compute_block_hash(block) -> str:
block_data = json.dumps({
"index": block.index,
"timestamp": block.timestamp,
"transactions": [tx.to_dict() for tx in block.transactions if not tx.signature],
"previous_hash": block.previous_hash,
"nonce": block.nonce,
}, sort_keys=True)
return hashlib.sha256(block_data.encode()).hexdigest()
# 为何 sort_keys=True?
# JSON 序列化必须稳定,dunderscore 顺序变化会改变哈希
# "a":1 总在 "b":2 之前,确保跨语言/版本哈希一致
# 上一节完整代码已验证:
# 篡改交易 → hash 变化 → 验证失败
# 重新计算 hash 后仍失败,因为 prevHash 不匹配16.2.2 创世块的特殊性
python
genesis = Block(
index=0,
timestamp=0.0, # 或 "2009-01-03 18:15:05"(致敬)
transactions=[], # 无交易(或包含一条 coinbase)
previous_hash="0"*64, # 64 个零,表示无前驱
difficulty=4,
)16.2.3 完整性验证
| 检查项 | 验证逻辑 |
|---|---|
| 哈希连续性 | block[n].prevHash == hash(block[n-1]) |
| 索引递增 | block[n].index == block[n-1].index + 1 |
| 自身有效性 | hash(block[n]) == block[n].hash |
| PoW 有效性 | block[n].hash < target |
python
def is_valid(self) -> bool:
"""验证单区块"""
return (self.hash == self.compute_hash() and
self.hash.startswith('0' * self.difficulty))
def is_valid_chain(chain: List[Block]) -> bool:
"""验证整条链"""
for i in range(1, len(chain)):
current = chain[i]
prev = chain[i-1]
# 1. 索引连续
if current.index != prev.index + 1: return False
# 2. 哈希链接
if current.previous_hash != prev.hash: return False
# 3. 自身有效
if not current.is_valid(): return False
return True, 前往 → 16.3 PoW 挖矿 |*
评论
0评论加载中…