我们使用余额模型(Account Model)而非 UTXO 模型,因为状态更新更直观、适合教学。真实公链(如以太坊)也是余额模型。
16.4.1 余额模型核心
graph LR
Alice[Alice: 50] --> |支付 20| Bob[Bob: 0 → 20]
Alice --> |剩余| Alice2[Alice: 30]
style Alice fill:#fff3e0
style Bob fill:#e8f5e9
状态转换
双重花费检查
python
def create_transaction(chain, tx):
"""交易验证"""
balance = chain.balances.get(tx.sender, 0)
if balance < tx.amount:
raise ValueError(f"余额不足: 需要 {tx.amount}, 仅有 {balance}")
# 防重放:nonce 检查
used_nonces = [t.nonce for t in chain.pending_transactions +
sum([b.transactions for b in chain.chain], [])]
if tx.nonce in used_nonces:
raise ValueError("nonce 已使用 (重放攻击)")
chain.pending_transactions.append(tx)16.4.2 签名(简化教学版)
python
import ecdsa # pip install ecdsa
def sign_transaction(tx: Transaction, private_key) -> str:
"""用私钥签名交易"""
sk = ecdsa.SigningKey.from_string(bytes.fromhex(private_key), curve=ecdsa.SECP256k1)
payload = tx.hash_payload() # 不含 signature 的哈希
signature = sk.sign_deterministic(bytes.fromhex(payload), hashfunc=hashlib.sha256)
return signature.hex()
def verify_signature(tx: Transaction) -> bool:
"""用 sender (公钥) 验证签名"""
try:
vk = ecdsa.VerifyingKey.from_string(bytes.fromhex(tx.sender), curve=ecdsa.SECP256k1)
return vk.verify(bytes.fromhex(tx.signature), bytes.fromhex(tx.hash_payload()), hashfunc=hashlib.sha256)
except:
return False
# 完整示例见 16.1 的扩展代码16.4.3 UTXO 模型(认知补充)
graph LR
UTXO0[10 BTC] --> |5| Receiver1[Alice]
UTXO0 --> |4.999| Receiver2[找零: Bob]
UTXO0 --> |0.001| Receiver3[矿工手续费]
style UTXO0 fill:#fff3e0
| 方面 | 余额模型 | UTXO 模型 |
|---|---|---|
| 状态表示 | {address: balance} | 未花费输出列表 |
| 交易验证 | 查字典 | 引用旧 UTXO + 生成新 UTXO |
| 并行性 | 单账户串行 | 自然并行(不同 UTXO) |
| 隐私性 | 账户全局可见 | 更灵活(每次新地址) |
| 复杂度 | 低 | 高 |
16.8 有选做实验:将余额模型改写成 UTXO 模型。
, 前往 → 16.5 P2P 网络 |*
评论
0评论加载中…