Taproot腳本樹概念解讀:MAST結構與解鎖條件的運作方式

Taproot腳本樹概念解讀:MAST結構與解鎖條件的運作方式
字号
【导读】從P2WSH痛點切入,解讀Taproot腳本樹(MAST)的葉子、分支與葉子版本規則,拆解內部公鑰、調整值與輸出公鑰Q的關係、控制塊結構與長度,並逐步說明密鑰路徑與腳本路徑兩種解鎖條件的驗證流程及成本取捨。

一個 Taproot 輸出的 scriptPubKey 固定是 34 位元組:1 位元組的 OP_1(代表見證版本 1)、1 位元組的推送長度 0x20,再加上 32 位元組的 x-only 公鑰。從區塊瀏覽器上看,它跟任何一個以密鑰路徑花費的 Taproot 輸出外觀一致——光看這 34 位元組,外界無法直接判定背後是否承諾了腳本樹、樹有多深或葉子有幾片。這個公鑰底下,可以同時承載多種多簽組合、帶有時間鎖的退款出口、硬體錢包的日常單簽通道,以及備用恢復密鑰。

花費資金時,交易發起方僅需掀開其中一片葉子。其餘條件在整個生命週期內都不會出現在鏈上,也不會佔用見證空間。這套機制的核心,正是 Taproot 腳本樹(即社群常稱的 MAST 結構)。理解其運作方式,需要從它解決的鏈上瓶頸、樹的組裝規則,以及兩種解鎖路徑的驗證邏輯逐一拆解。

舊結構的痛點:整份腳本都要上鏈

P2SH 與 P2WSH 都是把花費條件寫成一份完整腳本,並在花費時把整份腳本放進交易中。P2SH 把 redeem script 放入 scriptSig,P2WSH 則將 witness script 放進見證資料,兩者的共通限制是:只要想觸發其中一個條件,就必須將全部條件完整公開。

設想一個常見的企業錢包設計:三位主管各持一把密鑰,日常需要 2-of-3 簽名;如果連續 30 天沒有動用,財務總監可以單簽處理;若偵測到密鑰洩漏,冷備份密鑰配合 48 小時延遲可執行緊急轉移。寫成一份 P2WSH 腳本,內部會包含多個 OP_IF 分支、多組公鑰與時間鎖操作碼。花費當天即便只使用了兩位主管的簽名,鏈上依然會留下財務總監與冷備份的公鑰、延遲參數以及完整的邏輯分支結構。

這帶來了三重代價:在區塊空間方面,未執行的分支照樣佔用區塊容量與輸入資料,腳本越長手續費越高;在隱私方面,外界得以窺探組織的完整治理規則與權限架構;在可替換性方面,特徵明顯的複雜腳本會讓該筆網路上輸出在鏈上分析中格外醒目。

默克爾化腳本樹:把分支提升到結構層

MAST 的全稱為 Merkelized Abstract Syntax Tree,這是社群對此類默克爾化結構的通稱;BIP341 的規範術語則是 腳本樹(script tree)。在具體實現中,樹的葉子並非語法樹節點,而是一份份獨立且可直接執行的完整腳本。該機制把「一組候選花費條件」組織成了一棵默克爾樹。

葉子:一份完整腳本

每個葉子節點存儲獨立的腳本,例如「公鑰 A 與公鑰 B 的 2-of-2」或「公鑰 C 在 144 個區塊後可單簽」。葉子之間沒有 IF/ELSE 的巢狀關係,而是平行的花費選項。這與傳統腳本在單一腳本內使用 OP_IF 分支存在本質區別:OP_IF 的所有分支都寫在同一個腳本中,必然一起上鏈;腳本樹的分支各自獨立,未使用的葉子不會被公開。

中間節點:兩個子哈希的合併

兩個節點的哈希合併為父節點時,規則是先把兩個 32 位元組哈希按字典序排序(較小的在前),拼接後進行一次帶標籤的 SHA256 計算。字典序排序確保了同一對子節點只會產生唯一的父哈希,樹的根哈希與子節點的輸入順序無關,同時避免了雙向排列帶來的歧義。

葉子版本

每個葉子除腳本本身外,還包含 1 位元組的 leaf version。目前 Taproot 規範定義的標準版本為 0xc0,代表遵循 Tapscript 規則。此欄位為未來的軟分叉升級預留了擴展空間:當遇到非 0xc0 的未知葉子版本時,節點在驗證控制塊承諾匹配後不會執行腳本,而是直接視為有效花費,使得新規則可以在不中斷現有驗證邏輯的前提下向前相容。

內部公鑰、調整值與輸出公鑰的關係

Taproot 輸出的公鑰並非直接使用原始公鑰,而是經過了一次橢圓曲線標量調整(Tweak)。設內部公鑰為 P(32 位元組 x-only),腳本樹的默克爾根為 R,調整值 t 則是對 P 與 R 的拼接計算帶標籤哈希。最終的輸出公鑰計算為 Q = P + t·G,鎖定腳本中放置的是公鑰 Q 的 x 座標。

若該輸出僅打算使用密鑰路徑花費而未包含任何腳本樹,默克爾根 R 則為空,調整值僅對內部公鑰 P 自身進行哈希計算。這意味著即使沒有腳本條件,輸出的公鑰也不會直接等於內部公鑰,直接使用內部公鑰構造地址是不合規的。

Taproot腳本樹概念:內部公鑰、調整值與輸出公鑰的關係相关概念与关系示意
若該輸出僅打算使用密鑰路徑花費而未包含任何腳本樹,默克爾根 R 則為空,調整值僅對內部公鑰 P 自身進行哈希計算

此調整機制將兩種解鎖路徑無縫整合在同一個輸出中。腳本樹的默克爾根被承諾在輸出公鑰內,鏈上無需直接存儲根哈希。若走腳本路徑花費,見證資料必須提供足夠資訊以重新計算出 Q 並進行匹配;若走密鑰路徑花費,則需使用調整後的私鑰(即原始私鑰加上標量 t)進行 Schnorr 簽名。

三個帶標籤的哈希函數

Taproot 引入帶標籤的哈希(Tagged Hash)以隔離不同情境下的哈希計算。其構造方式是將特定的標籤字串進行 SHA256 運算兩次作為前綴,再拼接實際資料進行哈希計算,以防止跨協議情境下的哈希碰撞與誤用。

標籤名稱 輸入資料內容 用途說明
TapLeaf 葉子版本 + CompactSize(腳本長度) + 腳本內容 計算單一葉子節點的哈希值
TapBranch 經字典序排序後的兩個 32 位元組子節點哈希 將左右子節點合併為上一層父節點
TapTweak 內部公鑰 P(+ 默克爾根 R) 推導公鑰調整值 t

在計算 TapLeaf 時,資料格式嚴格定義為葉子版本、腳本長度的 CompactSize 編碼以及腳本字節串。軟體實現時必須嚴格按照 BIP341 規範進行標準序列化,若長度編碼或位元組結構不符,推導出的根哈希將與共識層不一致,導致交易驗證失敗。

兩種解鎖路徑

密鑰路徑:單一簽名完成驗證

密鑰路徑(Key Path)花費的見證資料通常只有一個元素:即針對調整後公鑰 Q 的 Schnorr 簽名。由於採用 SIGHASH_DEFAULT(值為 0x00),簽名字節數通常固定為 64 位元組,無需額外附加簽名類型位元組。驗證節點只需直接驗證公鑰與簽名,完全不需要解析腳本樹。

在標準交易中,一個 P2TR 密鑰路徑輸入在整筆交易中約佔 57.5 vB(根據 Murch 在 2-of-3 Taproot 方案中的測算),相較於傳統 P2PKH 輸入約 148 vB 具備顯著的體積優勢。更關鍵的是隱私保護:鏈上完全不透露是否存在內部公鑰或腳本樹,其數據特徵與常規單簽 Taproot 轉帳完全無法區分。

腳本路徑:腳本、參數與控制塊

當無法使用密鑰路徑花費時,交易發起方可選擇走腳本路徑(Script Path)。見證資料依序包含:執行腳本所需的參數(如簽名、預設數值等)、被觸發的單一腳本本身,以及一個 控制塊(Control Block)。若見證資料大於等於兩個元素且最後一個元素以 0x50 開頭,該元素會被識別為 annex 剝離,供未來協議擴展使用。

鏈上只會揭露被選中的那一條葉子腳本,其他未觸發的葉子內容完全保密,實現了局部條件披露與空間節省。

控制塊結構與長度

根據 BIP341 規範,控制塊由三部分組成:1 位元組的葉子版本與奇偶校驗位、32 位元組的內部公鑰 P,以及默克爾路徑上每層 32 位元組的兄弟哈希。因此控制塊的總長度公式為:

控制塊長度 = 33 + 32 × m(位元組)
(其中 m 代表從目標葉子到默克爾根的路徑長度/深度,規範上限 m ≤ 128,因此控制塊最大為 4129 位元組)

首字節的最高 7 位用於記錄葉子版本(如 0xc0),最低 1 位則記錄內部公鑰 P 在橢圓曲線上的 y 座標奇偶性。因此 Tapscript 的控制塊首字節常表現為 0xc0 或 0xc1。若腳本樹僅包含 1 片葉子(m = 0),默克爾路徑為空,控制塊長度即為基礎的 33 位元組。

Taproot腳本樹概念:控制塊結構與長度相关概念与关系示意
首字節的最高 7 位用於記錄葉子版本(如 0xc0),最低 1 位則記錄內部公鑰 P 在橢圓曲線上的 y 座標奇偶性

驗證流程逐步拆解

  1. 檢查見證資料是否包含 annex:若元素數量 ≥ 2 且最後一個元素以 0x50 開頭,將其分離。
  2. 將剩餘見證資料的最後一個元素作為控制塊,倒數第二個元素作為目標執行腳本。
  3. 從控制塊首字節提取葉子版本(遮蔽最低位)與 y 座標奇偶位;後續 32 位元組提取為內部公鑰 P,剩餘部分按每 32 位元組切分為默克爾路徑陣列。
  4. 使用葉子版本與腳本內容計算 TapLeaf 哈希,設為當前節點值。
  5. 沿著默克爾路徑逐層計算:將當前節點與路徑中的兄弟哈希按字典序排序後拼接,計算 TapBranch 哈希,直到路徑遍歷完成,得出默克爾根 R(若路徑為空,R 即等於葉子哈希)。
  6. 根據奇偶位恢復完整的內部公鑰點 P(若標記為奇數則對點進行取反運算)。
  7. 結合內部公鑰 P 與計算出的默克爾根 R 算出調整值 t,推導出公鑰 Q = P + t·G,並比對 Q 的 x 座標是否與交易輸出的 32 位元組公鑰完全一致。不一致則立即判定失敗。
  8. 公鑰驗證通過後,若葉子版本為 0xc0,則依據 Tapscript 規則執行腳本;若為未知的葉子版本,則在承諾比對成功後直接視為有效花費。
核心邏輯:控制塊同時承擔了內部公鑰、葉子版本、奇偶性與樹路徑的證明。驗證節點先在橢圓曲線與哈希層面完成「樹的歸屬證明」,再決定是否執行具體腳本邏輯。

Tapscript 帶來的規則變動

由 BIP 342 定義的 Tapscript 對傳統比特幣腳本規則進行了顯著優化:

  • Schnorr 簽名支援:簽名固定為 64 或 65 位元組(含可選的非預設 sighash 類型),消除了 ECDSA 編碼引發的交易延展性問題,並支援批量驗證。
  • 多簽機制升級:廢棄了存在歷史冗餘問題的 OP_CHECKMULTISIG,改用 OP_CHECKSIGADD。每個公鑰依序驗證簽名並累加計數器,最後與門檻值比對,堆疊邏輯清晰且節省空間。
  • 空簽名規範:未參與簽名的私鑰對應位置推入空位元組向量(Empty Vector),檢查計為 0 且不中斷腳本,避免了不必要的簽名佔位。
  • 簽名運算預算(Sigops Budget):取消了靜態操作碼數量上限,引入執行預算機制(初始預算為 50 + 腳本長度),每次非空簽名檢查消耗 50 點,耗盡則腳本終止。
  • 擴展操作碼 OP_SUCCESSx:腳本在執行到 OP_SUCCESSx 系列操作碼時直接判定成功,為未來的軟分叉功能引入提供了無縫擴展通道。
  • 簽名哈希覆蓋金額:BIP341 簽名承諾中納入了所有輸入的金額與鎖定腳本,硬體錢包無需盲簽,大幅提升了離線簽名的安全性。

樹的形狀如何影響成本與隱私

在腳本樹中,默克爾路徑長度 m 即為目標葉子的深度,控制塊每增加一層便增加 32 位元組:

  • 深度為 1(2 葉平衡樹):控制塊長度為 33 + 32×1 = 65 位元組。
  • 深度為 2(4 葉平衡樹):控制塊長度為 33 + 32×2 = 97 位元組。
  • 深度為 3(8 葉平衡樹):控制塊長度為 33 + 32×3 = 129 位元組。
  • 深度為 4(16 葉平衡樹):控制塊長度為 33 + 32×4 = 161 位元組(此時默克爾路徑部分為 128 位元組)。

這種線性增長特徵指明了樹形結構的優化方向:將高頻使用的花費條件置於淺層,將低頻或極端應急條件置於深層。非平衡樹的設計能讓常規花費享有更低的鏈上手續費。

在隱私層面,控制塊只會暴露被執行葉子的所在深度,外界無法得知整棵樹的葉子總數或其他未觸發分支的具體內容。若某個輸出構造時使用了深度為 4 的葉子,鏈上僅反映存在長度為 4 的哈希證明鏈,其餘兄弟節點的內容依舊處於哈希盲盒狀態。

密鑰路徑與腳本路徑的對比

比較維度 密鑰路徑(Key Path) 腳本路徑(Script Path)
見證資料結構 單一 64 位元組 Schnorr 簽名 執行參數 + 葉子腳本 + 控制塊(33 位元組起)
解鎖密鑰要求 經標量調整後的內部私鑰 該葉子腳本所滿足的特定簽名或前置條件
鏈上資訊暴露 完全無結構暴露,等同於普通單簽 僅暴露當前觸發的葉子內容與路徑深度
典型應用場景 合作結算、日常支付、通道常規關閉 爭議處理、時間鎖退款、緊急資產恢復

常見問題(FAQ)

Q1: 單葉子腳本樹在花費時一定比 P2WSH 更省手續費嗎?

不一定。P2TR 腳本路徑花費時必須包含至少 33 位元組的控制塊,而 P2WSH 則不需要控制塊。在極簡腳本(如單簽或簡單多簽)場景下,控制塊帶來的字節開銷可能抵消 Schnorr 簽名與 x-only 公鑰帶來的字節節省。具體成本取決於腳本複雜度、簽名數量及是否能優先使用密鑰路徑結算。

Q2: 腳本樹構造完成並生成地址後,後續可以動態修改或增加分支嗎?

不可以。默克爾根在地址生成時就已透過標量調整承諾進了輸出公鑰 Q 中。一旦資金存入該地址,條件即被密碼學鎖定。若需調整花費條件或輪換密鑰,必須發起一筆鏈上交易將資金轉移至包含新腳本樹結構的新輸出。

Q3: 外界是否能透過暴力枚舉常見模板猜出樹內未公開的腳本?

在一般情況下難以達成。要驗證猜測的默克爾根是否與鏈上輸出 Q 匹配,驗證方除了需要推測完整的候選腳本集合外,還必須獲知內部公鑰 P。在純密鑰路徑花費或未揭露控制塊的情況下,內部公鑰 P 並未在鏈上直接公開。若錢包在構造腳本時額外加入了防碰撞的多餘資料,將進一步消除枚舉推測的可能性。

Q4: 如果只想強制所有花費都執行腳本路徑,該如何設計?

可以構造一個無已知私鑰的「不可花費內部公鑰」(Unspendable Internal Key)。常見做法是將標準橢圓曲線基點 G 的序列化哈希作為 x 座標,推導出曲線上對應的點作為內部公鑰 P。由於無人知曉該點的離散對數(私鑰),該輸出將無法透過密鑰路徑動用,從而強制所有資金轉移必須公開提交腳本與控制塊進行鏈上驗證。

admin

作者负责资讯整理、核查与撰写。 · 已发布 93 篇文章

查看作者全部文章