Bitcoin Taproot Script Path Spending 验证完整指南
概述
本文记录了一次深入的 Bitcoin Taproot script path spending 机制验证过程,包括 BIP-341 tapleaf hash 算法的实现、Control Block 结构解析,以及与 bitcoinutils 库的对比验证。通过这次探索,我们完整验证了 Taproot 的底层密码学机制。
背景
在 Bitcoin 的 Taproot 升级(BIP-341)中,script path spending 允许通过 Merkle tree 结构验证脚本执行。当使用 script path 花费时,需要提供:
脚本内容(Script)
Control Block(包含 Merkle proof)
满足脚本条件的输入
本文重点验证 tapleaf hash 计算 与 Control Block 结构解析。
测试场景
我们有一个包含两个脚本的 Taproot 地址:
Hash Script (Script Path 1)
OP_SHA256 <helloworld_hash> OP_EQUALVERIFY OP_TRUE
任何人提供 preimage "helloworld" 即可花费
Bob Script (Script Path 2)
<bob_pubkey> OP_CHECKSIG
Bob 使用私钥签名即可花费
链上 Control Block 数据
从实际交易中提取的 Control Block 数据:
Hash path Control Block:
c050be5fc44ec580c387bf45df275aaa8b27e2d7716af31f10eeed357d126bb4d32faaa677cb6ad6a74bf7025e4cd03d2a82c7fb8e3c277916d7751078105cf9df
Bob path Control Block:
c050be5fc44ec580c387bf45df275aaa8b27e2d7716af31f10eeed357d126bb4d3fe78d8523ce9603014b28739a51ef826f791aa17511e617af6dc96a8f10f659e
Control Block 结构
[1 byte: leaf_version + parity] + [32 bytes: internal_pubkey] + [32 bytes: sibling_hash]
Leaf version:
c0
(TAPSCRIPT_VERSION)Internal key:
50be5fc44ec580c387bf45df275aaa8b27e2d7716af31f10eeed357d126bb4d3
Hash path sibling:
2faaa677cb6ad6a74bf7025e4cd03d2a82c7fb8e3c277916d7751078105cf9df
Bob path sibling:
fe78d8523ce9603014b28739a51ef826f791aa17511e617af6dc96a8f10f659e
BIP-341 Tapleaf Hash 算法
算法规范
根据 BIP-341,tapleaf hash 的计算方式为:
tapleaf_hash = SHA256(tag_hash + tag_hash + leaf_data)
其中:
- tag_hash = SHA256("TapLeaf")
- leaf_data = leaf_version + compact_size(script) + script
- leaf_version = 0xc0 (TAPSCRIPT_VERSION)
手工实现
import hashlib
def tapleaf_hash(script_hex, leaf_version=0xc0):
"""
BIP-341 tapleaf hash 计算
"""
script_bytes = bytes.fromhex(script_hex)
# Compact size (varint) 编码
script_len = len(script_bytes)
if script_len < 0xfd:
varint = bytes([script_len])
elif script_len <= 0xffff:
varint = bytes([0xfd]) + script_len.to_bytes(2, 'little')
else:
raise NotImplementedError("脚本太长")
# 构造 leaf data
leaf_data = bytes([leaf_version]) + varint + script_bytes
# TapLeaf tagged hash
tag_hash = hashlib.sha256(b"TapLeaf").digest()
final_hash = hashlib.sha256(tag_hash + tag_hash + leaf_data).digest()
return final_hash.hex()
脚本构造与序列化
正确的脚本内容
import hashlib
from bitcoinutils.script import Script
# Hash Script
helloworld_hash = hashlib.sha256(b'helloworld').hexdigest()
# helloworld_hash = '936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af'
hash_script = Script([
'OP_SHA256',
helloworld_hash,
'OP_EQUALVERIFY',
'OP_TRUE'
])
# Bob Script
bob_pubkey = '84b5951609b76619a1ce7f48977b4312ebe226987166ef044bfb374ceef63af5'
bob_script = Script([
bob_pubkey,
'OP_CHECKSIG'
])
脚本序列化结果
hash_script_hex = hash_script.to_hex()
# 结果: 'a820936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af8851'
bob_script_hex = bob_script.to_hex()
# 结果: '2084b5951609b76619a1ce7f48977b4312ebe226987166ef044bfb374ceef63af5ac'
脚本字节结构分析
Hash Script: a820936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af8851
a8 - OP_SHA256
20 - 长度字节 (32 字节)
936a... - 32字节哈希数据
88 - OP_EQUALVERIFY
51 - OP_TRUE
Bob Script: 2084b5951609b76619a1ce7f48977b4312ebe226987166ef044bfb374ceef63af5ac
20 - 长度字节 (32 字节)
84b5... - 32字节公钥数据
ac - OP_CHECKSIG
完整验证代码
"""
Bitcoin Taproot Tapleaf Hash 完整验证
"""
import hashlib
from bitcoinutils.script import Script
from bitcoinutils.utils import tapleaf_tagged_hash
def verify_taproot_mechanism():
"""完整验证 Taproot script path spending 机制"""
# === 1. 链上 Control Block 数据 ===
hash_path_cb = 'c050be5fc44ec580c387bf45df275aaa8b27e2d7716af31f10eeed357d126bb4d32faaa677cb6ad6a74bf7025e4cd03d2a82c7fb8e3c277916d7751078105cf9df'
bob_path_cb = 'c050be5fc44ec580c387bf45df275aaa8b27e2d7716af31f10eeed357d126bb4d3fe78d8523ce9603014b28739a51ef826f791aa17511e617af6dc96a8f10f659e'
# 解析 sibling hash
hash_sibling = hash_path_cb[66:] # Bob script 的 tapleaf hash
bob_sibling = bob_path_cb[66:] # Hash script 的 tapleaf hash
print("=== 链上 Control Block 数据 ===")
print(f"Hash path sibling: {hash_sibling}")
print(f"Bob path sibling: {bob_sibling}")
# === 2. 构造脚本 ===
helloworld_hash = hashlib.sha256(b'helloworld').hexdigest()
hash_script = Script([
'OP_SHA256',
helloworld_hash,
'OP_EQUALVERIFY',
'OP_TRUE'
])
bob_script = Script([
'84b5951609b76619a1ce7f48977b4312ebe226987166ef044bfb374ceef63af5',
'OP_CHECKSIG'
])
print(f"\n=== 脚本信息 ===")
print(f"Hash Script hex: {hash_script.to_hex()}")
print(f"Bob Script hex: {bob_script.to_hex()}")
# === 3. 手工实现 tapleaf hash ===
def my_tapleaf_hash(script_hex):
script_bytes = bytes.fromhex(script_hex)
varint = bytes([len(script_bytes)])
leaf_data = bytes([0xc0]) + varint + script_bytes
tag_hash = hashlib.sha256(b"TapLeaf").digest()
return hashlib.sha256(tag_hash + tag_hash + leaf_data).digest().hex()
# === 4. 计算 tapleaf hash ===
my_hash_tapleaf = my_tapleaf_hash(hash_script.to_hex())
my_bob_tapleaf = my_tapleaf_hash(bob_script.to_hex())
lib_hash_tapleaf = tapleaf_tagged_hash(hash_script).hex()
lib_bob_tapleaf = tapleaf_tagged_hash(bob_script).hex()
print(f"\n=== Tapleaf Hash 计算结果 ===")
print(f"Hash Script:")
print(f" 我的实现: {my_hash_tapleaf}")
print(f" 库的实现: {lib_hash_tapleaf}")
print(f" 实现一致: {'✅' if my_hash_tapleaf == lib_hash_tapleaf else '❌'}")
print(f"Bob Script:")
print(f" 我的实现: {my_bob_tapleaf}")
print(f" 库的实现: {lib_bob_tapleaf}")
print(f" 实现一致: {'✅' if my_bob_tapleaf == lib_bob_tapleaf else '❌'}")
# === 5. 与链上数据验证 ===
hash_match = my_hash_tapleaf == bob_sibling
bob_match = my_bob_tapleaf == hash_sibling
print(f"\n=== 链上数据验证 ===")
print(f"Hash script tapleaf == Bob sibling: {'✅' if hash_match else '❌'}")
print(f"Bob script tapleaf == Hash sibling: {'✅' if bob_match else '❌'}")
if hash_match and bob_match:
print(f"\n🎉 验证成功!")
print("✅ BIP-341 tapleaf hash 算法实现正确")
print("✅ 与 bitcoinutils 库结果一致")
print("✅ 与链上 Control Block 数据完美匹配")
print("✅ Taproot script path spending 机制验证通过")
else:
print(f"\n❌ 验证失败,需要进一步调试")
if __name__ == "__main__":
verify_taproot_mechanism()
验证结果
运行上述代码的输出结果:
=== 链上 Control Block 数据 ===
Hash path sibling: 2faaa677cb6ad6a74bf7025e4cd03d2a82c7fb8e3c277916d7751078105cf9df
Bob path sibling: fe78d8523ce9603014b28739a51ef826f791aa17511e617af6dc96a8f10f659e
=== 脚本信息 ===
Hash Script hex: a820936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af8851
Bob Script hex: 2084b5951609b76619a1ce7f48977b4312ebe226987166ef044bfb374ceef63af5ac
=== Tapleaf Hash 计算结果 ===
Hash Script:
我的实现: fe78d8523ce9603014b28739a51ef826f791aa17511e617af6dc96a8f10f659e
库的实现: fe78d8523ce9603014b28739a51ef826f791aa17511e617af6dc96a8f10f659e
实现一致: ✅
Bob Script:
我的实现: 2faaa677cb6ad6a74bf7025e4cd03d2a82c7fb8e3c277916d7751078105cf9df
库的实现: 2faaa677cb6ad6a74bf7025e4cd03d2a82c7fb8e3c277916d7751078105cf9df
实现一致: ✅
=== 链上数据验证 ===
Hash script tapleaf == Bob sibling: ✅
Bob script tapleaf == Hash sibling: ✅
🎉 验证成功!
✅ BIP-341 tapleaf hash 算法实现正确
✅ 与 bitcoinutils 库结果一致
✅ 与链上 Control Block 数据完美匹配
✅ Taproot script path spending 机制验证通过
调试过程回顾
初始问题
最初遇到 tapleaf hash 计算结果与预期不匹配的问题,怀疑是算法实现或库的问题。
调试历程
系统性分析:逐步验证 BIP-341 算法的每个环节
对比测试:手工实现与 bitcoinutils 库的对比
脚本构造验证:确认脚本内容和序列化正确性
Control Block 解析:理解 Merkle proof 结构
链上数据验证:与实际交易数据对比
关键发现
BIP-341 算法理解正确:手工实现与标准完全一致
bitcoinutils 库可信:库的实现正确且稳定
脚本内容正确:使用正确的 "helloworld" SHA256 哈希
Taproot 机制验证:完整的 script path spending 流程验证
技术要点总结
1. BIP-341 Tapleaf Hash 关键点
Tagged Hash:使用 "TapLeaf" 作为 tag
Leaf Version:TAPSCRIPT_VERSION = 0xc0
Compact Size:脚本长度的 varint 编码
字节顺序:leaf_version + compact_size + script
2. Control Block 结构
第一字节:leaf_version + parity bit
内部公钥:32 字节 x-only public key
Merkle Path:sibling hash(es)
3. Script Path Spending 验证
Sibling Relationship:一个脚本的 tapleaf hash 是另一个脚本 Control Block 的 sibling
Merkle Proof:Control Block 提供 Merkle tree 的验证路径
Script 执行:满足脚本条件后验证 Merkle proof
实际应用价值
开发者收益
深入理解 Taproot:掌握 BIP-341 的核心机制
调试技能提升:系统性的密码学算法验证方法
库验证能力:独立验证第三方库的正确性
链上数据分析:从实际交易中提取和验证技术细节
安全审计价值
算法验证:确保关键算法实现的正确性
库可信度评估:验证开源库的可靠性
交易验证:理解 Bitcoin 节点如何验证 Taproot 交易
攻击面分析:深入理解可能的安全漏洞点
结论
通过这次深入验证,我们:
✅ 成功实现了 BIP-341 tapleaf hash 算法
✅ 验证了 bitcoinutils 库的正确性
✅ 理解了 Taproot script path spending 的完整机制
✅ 掌握了链上数据的解析和验证方法
这次探索不仅解决了技术问题,更重要的是建立了对 Bitcoin 底层密码学机制的深入理解和独立验证能力。对于 Bitcoin 开发者来说,这种"从零实现并验证"的能力是极其宝贵的。
参考资料
本文记录了一次完整的 Bitcoin Taproot 技术验证过程,所有代码和数据都经过实际测试验证。
Last updated