Taproot 全面解析
比特幣最新的腳本升級:MAST、BIP-340/341/342。
Taproot 全面解析
Taproot 是比特幣 2021 年 11 月升級的重要特性,結合了多個比特幣改進提案(BIP),為比特幣帶來更強的隱私性和可擴展性。這次升級被視為比特幣自 2017 年 SegWit 以來最重要的協議升級,標誌著比特幣在智慧合約能力上的重大突破。
Taproot 升級內容
Taproot 升級實際上包含三個 BIP,它們共同運作形成一個完整的升級套件:
- BIP-340:Schnorr 簽名(Schnorr Signatures)
- BIP-341:Taproot(Pay-to-Taproot)
- BIP-342:Tapscript(對 Script 的擴展)
這三個 BIP 的設計目標是:
- 改善比特幣的交易隱私
- 降低複雜交易的費用
- 增強比特幣的腳本表达能力
- 為未來的協議升級奠定基礎
Schnorr 簽名(BIP-340)
什麼是 Schnorr 簽名?
Schnorr 簽名是一種數位簽名方案,由德國密碼學家 Claus Schnorr 於 1989 年發明。在比特幣中,Schnorr 簽名取代了自 2009 年比特幣創世以來使用的 ECDSA(橢圓曲線數位簽名演算法)。
Schnorr 簽名的核心數學原理基於離散對數問題。給定一個橢圓曲線上的點 G(生成點),私鑰 k 的公開金鑰為 K = kG。要對消息 m 簽名,簽名者:
- 選擇一個隨機 nonce r,計算 R = rG
- 計算 e = Hash(R || m)
- 計算 s = r + e*k (mod n),其中 n 是橢圓曲線的階
最終簽名為 (R, s)。驗證者只需檢查 sG = R + e*K 即可。
為什麼要用 Schnorr 簽名取代 ECDSA?
Schnorr 簽名相比 ECDSA 有以下幾個關鍵優勢:
- 密鑰聚合(Key Aggregation)
- 多個私鑰可以聚合成一個簽名
- 多簽名交易與單簽名看起來完全相同
- 這極大地提升了隱私性
- 線性簽名(Linear Signatures)
- 簽名過程是線性的
- 支援批次驗證(Batch Verification)
- 驗證速度比 ECDSA 快
- 安全性證明
- 有正式的安全性證明
- 比 ECDSA 更簡單,攻擊面更小
- 不存在ECDSA的延展性問題
密鑰聚合的實際運作
假設有 n 個參與者,每個參與者有自己的私鑰 ki 和公鑰 Ki = k_iG。傳統的多簽名需要 n 個簽名,但使用 Schnorr 簽名可以:
聚合公鑰:K = K_1 + K_2 + ... + K_n
聚合簽名:s = s_1 + s_2 + ... + s_n
這意味著一個 5-of-5 的多簽名交易,其見證資料大小與普通單簽名交易相同。
批次驗證
批次驗證允許一次驗證多個簽名,假設要驗證三個簽名 (R1, s1), (R2, s2), (R3, s3):
# 批次驗證的數學原理
# 驗證: s_i*G = R_i + e_i*K_i
# 可以合併為: (s_1+s_2+s_3)*G = (R_1+R_2+R_3) + (e_1*K_1+e_2*K_2+e_3*K_3)
這在區塊驗證時特別有用,可以顯著減少驗證時間。
簽名格式
<signature> <pubkey>
在 Taproot 升級中,Schnorr 簽名的長度為 64 位元組(而非 ECDSA 的 71 位元組),而公鑰為 32 位元組(壓縮格式)。
Rust 實作範例
use secp256k1::{Secp256k1, KeyPair, Message, Sign};
fn create_schnorr_signature(
keypair: &KeyPair,
message: &[u8]
) -> [u8; 64] {
let secp = Secp256k1::new();
let msg = Message::from_slice(message).unwrap();
keypair.sign_schnorr(msg)
}
fn verify_schnorr_signature(
public_key: &PublicKey,
message: &[u8],
signature: &[u8; 64]
) -> bool {
let secp = Secp256k1::new();
let msg = Message::from_slice(message).unwrap();
secp.verify_schnorr(&msg, signature, public_key).is_ok()
}
MAST 結構
什麼是 MAST?
MAST(Merkelized Abstract Syntax Tree)是一種結合 Merkle 樹和抽象語法樹(AST)的資料結構。它的核心思想是:
- 只揭示最終執行的腳本分支
- 未執行的腳本被完全隱藏
- 透過 Merkle 證明來驗證特定腳本的存在
MAST 的運作原理
假設有一個腳本包含三個可能的支出條件:
- 條件 A:延遲 30 天後可花費
- 條件 B:3-of-5 多簽名
- 條件 C:比特幣持有者單簽名
傳統的比特幣腳本會將所有條件都公佈在區塊鏈上。但使用 MAST:
Merkle Root
/ \
Hash(A) / \
Hash(B) Hash(C)
/ \ / \
Leaf A Leaf B Leaf C
當只有條件 C 被執行時,區塊鏈上只會顯示:
- Merkle Root
- 條件 C 的內容
- 通往條件 C 的 Merkle 證明路徑
Merkle 證明的大小
對於有 n 個分支的 MAST,Merkle 證明的大小為 log₂(n) 個雜湊值。例如:
| 分支數量 | Merkle 證明大小 |
|---|---|
| 2 | 32 bytes |
| 4 | 64 bytes |
| 8 | 96 bytes |
| 16 | 128 bytes |
| 256 | 256 bytes |
MAST 的優勢
- 隱私性
- 複雜的支付條件被隱藏
- 外部觀察者只能看到執行的分支
- 無法從區塊鏈推斷出完整的腳本邏輯
- 可擴展性
- 未執行的腳本不佔用區塊空間
- 可實現更複雜的邏輯而無需支付額外費用
- 鼓勵使用更安全的腳本設計
傳統 vs MAST 腳本結構
# 傳統 OP_IF 結構(所有條件都會被揭露)
OP_IF
<condition A>
OP_ELSE
<condition B>
OP_ENDIF
# MAST 結構
# 只揭露被執行的分支
<Taproot Root>
Taproot 輸出
P2TR(Pay to Taproot)
Taproot 地址格式使用 bech32m 編碼,以 bc1p 開頭。地址的生成過程:
- 生成內部公鑰(Internal Public Key)
- 構建腳本樹
- 計算 Taproot Merkle Root
- 組合為最終的支出公鑰
- 使用 bech32m 編碼
# Taproot 地址生成
internal_pubkey = bytes.fromhex("02...") # 32 bytes
script_tree = ScriptTree(...) # 可選的腳本樹
taptweak = sha256(taproot_root)
tweak = int.from_bytes(taptweak, 'big')
output_pubkey = internal_pubkey * tweak # 點加法
# bech32m 編碼
address = bech32m_encode("bc1p", output_pubkey)
腳本樹
Taproot 允許:
- 一個主要支出條件(key path)- 通常是單簽名
- 多個替代支出條件(script path)- 任意比特幣腳本
Merkle Root
/ \
Key Path Script Path
(threshold) / \
Script A Script B
兩種支出路徑
- Key Path 支出
- 使用聚合後的公鑰直接花費
- 最簡單、最便宜
- 隱私性最高
- Script Path 支出
- 需要揭示對應的腳本
- 提供 Merkle 證明
- 支援更複雜的邏輯
BIP-341 核心概念
BIP-341 定義了 Taproot 的完整語義:
witness: {
script: <script> (if needed)
ctrl: <control block>
signature:<sig> (key path) OR script witness (script path)
}
control block: {
version: 0xec
internal_pubkey: <33 bytes>
merkle_branch: <0-128 bytes>
}
Tapscript(BIP-342)
Tapscript 的改進
BIP-342 對比特幣腳本語言進行了多項改進:
- 移除 OP_CHECKMULTISIG 的問題
- 原本的 OP_CHECKMULTISIG 需要多個公鑰
- Tapscript 允許使用閾值簽名
- 新的 OP_CHECKSIGADD
- 結合了 OPCHECKSIG 和 OPADD
- 更適合批次驗證
- 更高的腳本大小限制
- 最大腳本大小從 10,000 位元組增加到 16,000 位元組
- 最大 MAST 深度從 16 增加到 128
- 改進的升級機制
- 未來的升級可以更平滑地引入
Tapscript 範例
# Tapscript 中的多簽名驗證
# 使用 OP_CHECKSIGADD 實現閾值簽名
<pubkey1> <pubkey2> <pubkey3> 3 OP_CHECKMULTISIG
# 等價的 Tapscript 實現
<pubkey1> OP_CHECKSIG
<pubkey2> OP_CHECKSIGADD
<pubkey3> OP_CHECKSIGADD
2 OP_EQUAL
Taproot 的優勢
1. 更佳隱私
- 所有交易看起來都類似
- 多簽名、智慧合約與普通交易無法區分
- 這對於機構投資者特別重要
具體來說:
- 傳統 2-of-2 多簽名交易:需要 2 個公鑰 + 2 個簽名
- Taproot 2-of-2 多簽名:只需要 1 個聚合公鑰 + 1 個簽名
- 節省約 50% 的見證空間
2. 更低費用
- 節省見證數據
- 複雜腳本的花費成本降低
- 對於需要多個備用條件的用戶特別有利
| 交易類型 | 傳統費用 | Taproot 費用 | 節省 |
|---|---|---|---|
| 2-of-2 多簽 | ~250 vbytes | ~170 vbytes | ~32% |
| 3-of-5 多簽 | ~400 vbytes | ~190 vbytes | ~52% |
| 帶時間鎖的腳本 | ~300 vbytes | ~180 vbytes | ~40% |
3. 更大靈活性
- 支援更複雜的腳本
- 閃電網路通道更高效
- 支援新的應用場景
4. 更強擴展性
- 為未來升級做準備
- 更好的腳本語言支援
- 更高的腳本大小限制
5. 安全性提升
- Schnorr 簽名沒有延展性問題
- 密鑰聚合減少了攻擊面
- 正式的安全性證明
Taproot Channels
Taproot 為閃電網路帶來重要改進:
1. 更快的關閉
- 單方面關閉更快
- 無需等待額外的確認
2. 更強隱私
- 通道與普通交易無法區分
- 外部觀察者無法識別閃電通道
3. MPTLC(MuSig-PTLC)
- Point Time Locked Contracts
- 更安全的支付路由
- 解決了 HTLC 的隱私問題
閃電通道類型比較
| 特性 | 傳統通道 | Taproot 通道 |
|---|---|---|
| 關閉時間 | 較慢 | 更快 |
| 隱私性 | 較差 | 更好 |
| 支付方式 | HTLC | PTLC |
| 費用效率 | 一般 | 更高 |
使用 Taproot
錢包支援
大多數主流錢包已支援 Taproot:
- Bitcoin Core:22.0+ 完全支援
- Ledger:Firmware 2.0+
- Trezor:Model T 和 Model One
- Sparrow Wallet:完整支援
- Electrum:4.1.0+
地址格式
Taproot 地址以 bc1p 開頭(bech32m 編碼)
例如:
bc1p0pls6r57h6jc9e8qw5u8rd9eym93lu9xu0g2g5d80k6jtecy0cmsfru6hm
在 Bitcoin Core 中使用 Taproot
# 生成 Taproot 地址
bitcoin-cli getnewaddress "my_taproot_wallet" "bech32m"
# 檢查地址類型
bitcoin-cli getaddressinfo "bc1p..."
# 創建 Taproot 交易
bitcoin-cli walletcreatefundedpsbt \
'[]' \
'{"bc1p...": 0.01}' \
'{"wallet_name": "my_taproot_wallet"}'
Python 實作:生成 Taproot 地址
import hashlib
import bech32
def taproot_address_from_pubkey(pubkey: bytes) -> str:
"""從公鑰生成 Taproot 地址"""
# 計算 Taproot tweak
tap_tweak = hashlib.sha256(pubkey).digest()
# 這個例子展示概念,實際需要 secp256k1 庫進行點加法
# tweaked_pubkey = pubkey + G * tap_tweak
# 轉換為 bech32m
return bech32.encode("bc", 1, pubkey) # 簡化版本
進階主題
閾值簽名
Taproot 的密鑰聚合支援 m-of-n 閾值簽名:
// 使用 musig2 實現閾值簽名
fn threshold_sign(
participants: &[KeyPair],
threshold: usize,
message: &[u8]
) -> PartialSignature {
// 每個參與者生成自己的 nonce
// 聚合所有 nonce 產生 R
// 每個參與者計算自己的部分簽名
// 聚合部分簽名產生最終簽名
}
腳本路徑的實際應用
- 遺產規劃
# 如果 365 天后仍未動用,轉入繼承人地址
<heir_pubkey> OP_CHECKSIG
OP_IF
OP_DROP
<time> OP_CHECKLOCKTIMEVERIFY
OP_ELSE
OP_DROP
<heir_pubkey> OP_CHECKSIG
OP_ENDIF
- 合作式關閉
- 閃電通道可以使用 key path 進行合作式關閉
- 單筆交易即可完成,隱私性極佳
與其他升級的比較
| 升級 | 年份 | 主要特性 |
|---|---|---|
| BIP-16 (P2SH) | 2012 | 腳本的雜湊表示 |
| BIP-141 (SegWit) | 2017 | 區塊容量提升 |
| BIP-340 (Schnorr) | 2021 | 簽名聚合 |
| BIP-341 (Taproot) | 2021 | MAST + 隱私 |
| BIP-342 (Tapscript) | 2021 | 腳本擴展 |
常見問題
Q:升級需要用戶做什麼?
A:一般用戶無需任何操作,錢包會自動使用新格式。升級是向後相容的,舊地址仍然可以正常使用。
Q:舊地址還能用嗎?
A:可以,舊地址完全相容。Taproot 升級不會影響現有的比特幣地址。
Q:Taproot 會讓比特幣更中心化嗎?
A:相反,Taproot 的設計鼓勵更多節點運行。由於所有交易看起來相同,無法從區塊鏈分析中識別特定類型的交易,這有助於保護普通用戶的隱私。
Q:Taproot 是否支援智慧合約?
A:Taproot 增強了比特幣的腳本能力,但受限於比特幣的設計哲學——它不是圖靈完整的。Taproot 主要用於更靈活的多簽名、閾值簽名和條件解鎖場景。
Q:使用 Taproot 有什麼風險?
A:主要風險在於錢包兼容性。使用 Taproot 地址前,請確保錢包已正確升級並支持 bech32m 格式。
2024-2025 年 Taproot 採用率分析
採用率現況
截至 2025 年 2 月,Taproot 的採用率持續穩步上升。根據區塊鏈數據分析:
Taproot 採用數據(2025 年 2 月)
═══════════════════════════════════════════════════════════════
採用指標 數據 趨勢
───────────────────────────────────────────────────────────────
Taproot 地址數量 ~4,500,000+ 快速增長
Taproot 輸出佔比 ~18-22% 持續上升
Taproot 交易佔比 ~15-20% 穩步增長
Schnorr 簽名使用 ~25%+ 主要錢包支援
MAST 腳本部署 實驗性 早期階段
───────────────────────────────────────────────────────────────
數據來源:區塊鏈分析師預估,實際數據因統計方法差異可能有所不同
主要錢包支援狀況
主流錢包 Taproot 支援時間軸
═══════════════════════════════════════════════════════════════
錢包名稱 支援版本 支援時間 採用程度
───────────────────────────────────────────────────────────────
Bitcoin Core 22.0+ (2021/11) 2021年11月 完全支援
Electrum 4.1.0+ (2022/3) 2022年3月 完全支援
Sparrow 1.6.0+ (2022/1) 2022年1月 完全支援
Ledger Firmware 2.0+ 2022年6月 完全支援
Trezor Model T/One 2022年8月 完全支援
BlueWallet 6.0.0+ (2023/2) 2023年2月 完全支援
Wasabi 2.0.0+ (2023/5) 2023年5月 完全支援
Exodus 23.5.0+ (2023/8) 2023年8月 完全支援
Coinbase App 4.65+ (2023/10) 2023年10月 完全支援
Kraken 全平台 (2023/12) 2023年12月 完全支援
───────────────────────────────────────────────────────────────
交易所採用狀況
主要交易所 Taproot 存款支援
═══════════════════════════════════════════════════════════════
交易所 存款支援 提款支援 備註
───────────────────────────────────────────────────────────────
Binance 完全支援 完全支援 預設啟用
Coinbase 完全支援 完全支援 自動轉換
Kraken 完全支援 完全支援 bech32m
Gemini 完全支援 完全支援 完整支援
Bitfinex 完全支援 完全支援 支援
OKX 完全支援 完全支援 完全支援
Bybit 完全支援 完全支援 完全支援
Huobi 完全支援 完全支援 完全支援
Gate.io 完全支援 完全支援 完全支援
───────────────────────────────────────────────────────────────
Taproot 採用驅動因素
採用增長的主要推動力
═══════════════════════════════════════════════════════════════
1. 費用效率優勢
- 複雜交易(多簽名、時間鎖)費用節省 30-50%
- 比特幣區塊空間需求增加,推動成本優化
- 機構投資者對費用敏感度提高
2. 隱私需求上升
- 機構採用增加,隱私意識提升
- 多簽名交易隱私化
- 比特幣生態系統整體隱私標準提高
3. 生態系統成熟
- 錢包支援率超過 90%
- 開發工具鏈完善
- 比特幣升級共識達成
4. 閃電網路整合
- Taproot Channels 技術成熟
- PTLC 支付支援
- 隱私增強的路由
採用率預測
未來採用趨勢預測(2025-2027)
═══════════════════════════════════════════════════════════════
年份 Taproot 輸出佔比 主要驅動因素
───────────────────────────────────────────────────────────────
2025 Q1 ~20-25% ETF 資金流入、錢包升級
2025 Q2 ~25-30% 費用效率認知提升
2025 Q3 ~30-35% 閃電網路普及
2025 Q4 ~35-40% 機構採用加速
2026 ~45-55% 生態系統全面升級
2027 ~60-70% 主流全面採用
───────────────────────────────────────────────────────────────
預測基礎:網路效應、歷史升級採用曲線、機構採用速度
對比特幣網路的影響
Taproot 對網路的具體影響(2024-2025 數據)
═══════════════════════════════════════════════════════════════
影響領域 變化 說明
───────────────────────────────────────────────────────────────
交易驗證速度 +15-25% Schnorr 批次驗證
多簽名交易比例 顯著增加 隱私性提升
區塊空間使用效率 +5-10% MAST 優化
閃電網路隱私性 質的飛躍 PTLC 支援
機構採用意願 顯著提升 隱私+效率
開發者創新 新用例出現 腳本靈活性
───────────────────────────────────────────────────────────────
P2TR 地址建立完整實作流程
單一簽名 P2TR 地址建立
建立一個基本的 P2TR(Pay-to-Taproot)地址涉及以下詳細步驟:
步驟一:生成私鑰和內部公鑰
首先需要生成一個 secp256k1 私鑰,然後計算對應的公鑰。在比特幣中,私鑰是一個256位的隨機數,通常表示為32字節的十六進制字符串。
# P2TR 地址建立 - 完整 Python 實現
import hashlib
import bech32
# secp256k1 曲線參數
P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
def point_mul(k, point):
"""橢圓曲線點乘法"""
# 簡化實現,實際使用時應使用經過審計的密碼學庫
return point # 佔位符
def point_add(p1, p2):
"""橢圓曲線點加法"""
return p1 # 佔位符
def generate_keypair():
"""生成私鑰和公鑰對"""
import os
while True:
private_key = int.from_bytes(os.urandom(32), 'big')
if 1 <= private_key < N:
break
public_key = point_mul(private_key, G)
return private_key, public_key
步驟二:計算 Taproot Tweak
Taproot 使用一個稱為「tweak」的值來修改最終的輸出公鑰。這個 tweak 是通過對內部公鑰進行哈希計算得到的。
def compute_tap_tweak(internal_pubkey):
"""
計算 Taproot tweak
公式: tweak = Hash(internal_pubkey || script_tree_root)
"""
# 對於純 key-path 花費,script_tree_root 為空(0x0000...)
# 最終 tweak = SHA256(SHA256(internal_pubkey))
# 序列化公鑰(33字節,壓縮格式)
if internal_pubkey[1] & 1:
prefix = b'\x03'
else:
prefix = b'\x02'
pubkey_data = prefix + internal_pubkey[0].to_bytes(32, 'big')
# 計算 tweak
tap_tweak = hashlib.sha256(hashlib.sha256(pubkey_data).digest()).digest()
return int.from_bytes(tap_tweak, 'big') % N
步驟三:應用 Tweak 並生成輸出公鑰
最終的 Taproot 輸出公鑰是內部公鑰加上 tweak 乘以生成點的結果。
def apply_tweak(internal_pubkey, tweak):
"""
應用 tweak 生成輸出公鑰
公式: output_pubkey = internal_pubkey + G * tweak
"""
tweaked_point = point_mul(tweak, G)
output_pubkey = point_add(internal_pubkey, tweaked_point)
return output_pubkey
步驟四:Bech32m 編碼
最後一步是將輸出公鑰編碼為人類可讀的地址格式。Taproot 使用 bech32m 編碼,以「bc1p」開頭。
def bech32_encode(hrp, version, data):
"""Bech32m 編碼實現"""
# 實際實現較為複雜,需要使用 bech32 庫
pass
def create_p2tr_address(internal_pubkey):
"""創建完整的 P2TR 地址"""
# 計算 tweak
tweak = compute_tap_tweak(internal_pubkey)
# 應用 tweak
output_pubkey = apply_tweak(internal_pubkey, tweak)
# 轉換為位元組(33字節,壓縮格式)
if output_pubkey[1] & 1:
version_byte = 0x03
else:
version_byte = 0x02
witness_program = bytes([version_byte]) + output_pubkey[0].to_bytes(32, 'big')
# Bech32m 編碼
# 格式: bc1p + bech32m 編碼的 witness program
address = bech32.bech32_encode("bc", 1, witness_program)
return address
使用 MuSig2 建立多簽名 P2TR 地址
MuSig2 允許多方共同建立一個 P2TR 地址,其中任何 m-of-n 的參與者可以授權花費。
步驟一:收集所有參與者的公鑰
在 MuSig2 中,首先需要收集所有 n 個參與者的公鑰。這通常在協議的「密鑰聚合」階段完成。
def compute_keyagg_coefficient(L, pubkey):
"""
計算密鑰聚合係數
a_i = Hash(L || P_i)
"""
data = L + pubkey
h = hashlib.sha256(data).digest()
return int.from_bytes(h, 'big') % N
def aggregate_public_keys(public_keys):
"""
聚合多個公鑰為單一密鑰
K = Σ(a_i * P_i)
"""
# 計算 L - 所有公鑰的哈希
L_data = b''.join(sorted(public_keys))
L = hashlib.sha256(L_data).digest()
# 聚合公鑰
agg_pubkey = (0, 0) # 無窮遠點
for pubkey in public_keys:
coeff = compute_keyagg_coefficient(L, pubkey)
coeff_point = point_mul(coeff, pubkey)
agg_pubkey = point_add(agg_pubkey, coeff_point)
return agg_pubkey, L
步驟二:建立帶有腳本樹的 P2TR
如果需要配置腳本路徑(script path),需要在密鑰聚合之後添加腳本樹的處理。
class TaprootScriptTree:
"""Taproot 腳本樹"""
def __init__(self, scripts=None):
self.scripts = scripts or []
self.leaves = []
self.root = None
def compute_leaf_hash(self, script):
"""計算腳本葉節點的哈希"""
# Taproot 使用 TapLeafHash
# 格式: 0xc0 || script
leaf_tag = b'TapLeaf'
h = hashlib.sha256(leaf_tag + leaf_tag + script).digest()
return h
def compute_branch_hash(self, left, right):
"""計算分支節點的哈希"""
# 內部節點的哈希
branch_tag = b'TapBranch'
h = hashlib.sha256(branch_tag + left + right).digest()
return h
def build_tree(self):
"""構建梅克爾樹"""
# 將每個腳本轉換為葉節點
self.leaves = [self.compute_leaf_hash(s) for s in self.scripts]
# 遞迴構建樹直到只剩根節點
current_level = self.leaves
while len(current_level) > 1:
if len(current_level) % 2 == 1:
current_level.append(current_level[-1])
next_level = []
for i in range(0, len(current_level), 2):
left = current_level[i]
right = current_level[i + 1]
branch = self.compute_branch_hash(left, right)
next_level.append(branch)
current_level = next_level
self.root = current_level[0] if current_level else b'\x00' * 32
return self.root
def get_root(self):
"""獲取腳本樹根"""
if self.root is None:
self.build_tree()
return self.root
步驟三:結合密鑰和腳本樹
最終的 Taproot 地址同時包含聚合公鑰和腳本樹根。
def create_taproot_address_with_scripts(internal_pubkey, scripts):
"""
創建帶有腳本樹的 P2TR 地址
"""
# 如果有腳本,計算腳本樹根
script_tree = TaprootScriptTree(scripts)
script_root = script_tree.get_root() if scripts else b'\x00' * 32
# 計算最終的 tweak(結合公鑰和腳本樹根)
# 公式: tweak = Hash(internal_pubkey || script_root)
pubkey_data = serialize_pubkey(internal_pubkey)
tweak_input = pubkey_data + script_root
tap_tweak = hashlib.sha256(hashlib.sha256(tweak_input).digest()).digest()
tweak = int.from_bytes(tap_tweak, 'big') % N
# 應用 tweak
tweaked_pubkey = apply_tweak(internal_pubkey, tweak)
# 編碼為地址
return create_p2tr_address(tweaked_pubkey)
實際使用 Bitcoin Core 建立 P2TR
在實際操作中,通常使用現成的工具而不是自己實現。以下是使用 Bitcoin Core 建立 P2TR 地址的方法:
# 生成 Taproot 地址
bitcoin-cli getnewaddress "my_taproot_wallet" "bech32m"
# 獲取地址信息(包括完整的公鑰)
bitcoin-cli getaddressinfo "bc1p..."
# 創建未簽名交易
bitcoin-cli walletcreatefundedpsbt \
'[]' \
'{"bc1p...destination...": 0.01}' \
'{"wallet_name": "my_taproot_wallet", "change_type": "bech32m"}'
# 簽名並廣播
bitcoin-cli signrawtransactionwithwallet "psbt_hex"
bitcoin-cli sendrawtransaction "signed_hex"
P2TR 地址的花費方式
Key Path 花費
Key Path 是最簡單的花費方式,只需要提供一個有效的 Schnorr 簽名即可。
解鎖腳本(Witness):
<signature>
腳本(ScriptPubKey):
OP_1 <32-byte public key>
這看起來與普通的單簽名交易完全相同,提供了最大的隱私性。
Script Path 花費
如果需要使用腳本路徑花費,需要提供完整的腳本和梅克爾證明。
解鎖腳本(Witness):
<script> <script args> <control block>
控制塊結構:
- version: 0xec
- internal pubkey: 32 bytes
- merkle proof: 0-128 bytes(取決於腳本樹深度)
技術參考
BIP 原文
資源庫
- libsecp256k1:比特幣核心密碼學庫
- rust-secp256k1:Rust 實現
- bip-schnorr:Python 實現
結論
Taproot 是比特幣多年來最重要的升級之一,為比特幣帶來更強的隱私性、可擴展性和靈活性。這次升級的核心價值在於:
- 隱私保護:所有交易外觀相同,無法區分多簽名和單簽名
- 費用效率:複雜腳本的花費成本大幅降低
- 擴展性:為比特幣的長期發展奠定基礎
- 安全性:更強的密碼學保證
這是比特幣持續演進的重要一步,將推動比特幣在機構採用、支付效率和用戶隱私方面達到新的水平。
本文包含
相關文章
- Taproot 隱私保護完整教學 — 深入解析 Taproot 如何增強比特幣隱私,包括 MAST、Schnorr 簽名聚合、P2TR 地址類型與實戰應用。
- Taproot 與閃電網路隱私機制深度分析 — 深入分析Taproot升級如何提升比特幣交易隱私,以及P2TR通道、PTLC、盲化路由等技術在閃電網路中的應用。
- MuSig2 多人簽名 — 理解 Schnorr 密鑰聚合與多簽名方案。
- Taproot 隱私優勢 — 分析 Taproot 升級如何提升比特幣交易隱私。
- Taproot Channels 閃電升級 — Taproot 如何提升閃電網路的隱私與效率。
延伸閱讀與來源
- BIP-340 Schnorr 簽名 Schnorr 簽名標準
- BIP-341 Taproot Taproot 升級規範
- BIP-342 Tapscript Taproot 腳本語言
這篇文章對您有幫助嗎?
請告訴我們如何改進:
評論
發表評論
注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。
目前尚無評論,成為第一個發表評論的人吧!