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 花费时,需要提供:

  1. 脚本内容(Script)

  2. Control Block(包含 Merkle proof)

  3. 满足脚本条件的输入

本文重点验证 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 计算结果与预期不匹配的问题,怀疑是算法实现或库的问题。

调试历程

  1. 系统性分析:逐步验证 BIP-341 算法的每个环节

  2. 对比测试:手工实现与 bitcoinutils 库的对比

  3. 脚本构造验证:确认脚本内容和序列化正确性

  4. Control Block 解析:理解 Merkle proof 结构

  5. 链上数据验证:与实际交易数据对比

关键发现

  • 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

实际应用价值

开发者收益

  1. 深入理解 Taproot:掌握 BIP-341 的核心机制

  2. 调试技能提升:系统性的密码学算法验证方法

  3. 库验证能力:独立验证第三方库的正确性

  4. 链上数据分析:从实际交易中提取和验证技术细节

安全审计价值

  1. 算法验证:确保关键算法实现的正确性

  2. 库可信度评估:验证开源库的可靠性

  3. 交易验证:理解 Bitcoin 节点如何验证 Taproot 交易

  4. 攻击面分析:深入理解可能的安全漏洞点

结论

通过这次深入验证,我们:

  1. ✅ 成功实现了 BIP-341 tapleaf hash 算法

  2. ✅ 验证了 bitcoinutils 库的正确性

  3. ✅ 理解了 Taproot script path spending 的完整机制

  4. ✅ 掌握了链上数据的解析和验证方法

这次探索不仅解决了技术问题,更重要的是建立了对 Bitcoin 底层密码学机制的深入理解和独立验证能力。对于 Bitcoin 开发者来说,这种"从零实现并验证"的能力是极其宝贵的。

参考资料


本文记录了一次完整的 Bitcoin Taproot 技术验证过程,所有代码和数据都经过实际测试验证。

Last updated