flowchart LR
节点1[节点 5001] --> 节点2[节点 5002]
节点1 --> 节点3[节点 5003]
节点2 --> 节点3
测试[测试脚本] -->|单节点| 节点1
测试 -->|多节点共识| 全部节点
测试 -->|浏览器查询| API[HTTP API]
API --> 节点2
节点2 --> 验证[验证余额/区块/签名]
style 节点1 fill:#e3f2fd
style 验证 fill:#c8e6c9
单节点运行、多节点共识、浏览器查询——三个完整测试证明系统可用。
16.7.1 端到端测试脚本
python
# test_e2e.py — 自动化端到端
import requests, time, subprocess, sys, os
def start_node(port, peers=[]):
env = os.environ.copy()
env['NODE_PORT'] = str(port)
p = subprocess.Popen([sys.executable, 'mini_node.py', str(port)],
stdout=subprocess.PIPE, env=env)
time.sleep(2) # 等待启动
return p
def test_three_nodes():
"""三节点测试"""
p1 = start_node(4001)
p2 = start_node(4002)
p3 = start_node(4003)
# 注册为对等节点
for pair in [(4001,4002), (4001,4003), (4002,4003)]:
requests.post(f"http://localhost:{pair[0]}/register",
json={"node": f"http://localhost:{pair[1]}"})
# 节点1挖矿 → 发给 Alice
r1 = requests.get("http://localhost:4001/mine?address=Alice").json()
assert r1['index'] == 1
time.sleep(1) # 传播
# 节点2查询余额
r2 = requests.get("http://localhost:4002/balance/Alice").json()
assert r2['balance'] > 0, "余额未同步"
# 节点3转账
requests.post("http://localhost:4003/transactions/new",
json={"sender":"Alice","recipient":"Bob","amount":20})
# 节点2挖矿 → 包含转账
r3 = requests.get("http://localhost:4002/mine?address=Bob").json()
assert r3['index'] == 2
time.sleep(1)
# 验证三节点一致
for port in [4001, 4002, 4003]:
chain = requests.get(f"http://localhost:{port}/chain").json()
assert chain['length'] == 3
# 验证余额
alice_bal = requests.get(f"http://localhost:{port}/balance/Alice").json()['balance']
bob_bal = requests.get(f"http://localhost:{port}/balance/Bob").json()['balance']
assert alice_bal == 30 # 50 奖励 - 20 转出
assert bob_bal == 70 # 20 转入 + 50 奖励
print("✅ 三节点端到端测试通过")
# 停止
for p in [p1, p2, p3]: p.terminate()
if __name__ == "__main__":
test_three_nodes()16.7.2 篡改测试
python
def test_tamper():
chain = requests.get("http://localhost:4001/chain").json()
# 尝试修改块 1 的奖励地址
block1 = chain['chain'][1]
block1['transactions'][0]['recipient'] = 'Hacker'
# 重新计算 hash
import hashlib, json
tampered = hashlib.sha256(json.dumps({...}, sort_keys=True).encode()).hexdigest()
block1['hash'] = tampered
# 发送回节点
# ... 节点应拒绝无效块
# 共识会恢复为有效链
# 验证链仍然有效
assert requests.get("http://localhost:4001/nodes/resolve").json()['replaced'] == True16.7.3 学习成果
通过这个迷你链,你掌握了:
- ✅ 区块结构和哈希链接
- ✅ 工作量证明与出块竞争
- ✅ 动态难度调整
- ✅ 余额模型交易验证
- ✅ P2P 广播与共识(最长链)
- ✅ HTTP API 设计
- ✅ 端到端测试
这 200 行代码是理解比特币/Ethereum 核心机制的最小完整模型。
, 前往 → 16.8 选做扩展 |*
评论
0评论加载中…