Script

如何使用 Taproot 的 Miniscript 將 Miniscript 樹變成 Taproot 樹?

  • May 18, 2022

如何使用 Taproot’d Miniscript 將 Miniscript“樹”變成 Taproot 樹?

(需要明確的是,與 Taproot 樹不同,Miniscript 樹可能不會出現在使用者面前。將 Miniscript 分解成樹狀結構是在程式碼中完成的,並於2022 年 5 月 18 日在比特幣核心公關評論俱樂部中進行了討論。 )

如何使用 Taproot’d Miniscript 將 Miniscript“樹”變成 Taproot 樹?

你不會 - 它們是無法從一個翻譯到另一個的無與倫比的東西。

Miniscript 是一種表示比特幣腳本的方法,以幫助對其進行推理。主根樹是有助於建構主根輸出的承諾結構,這些輸出可以通過滿足可能的多個腳本之一來使用。

主根腳本配置和迷你腳本表達式都可以被認為是樹,但它們獨立存在,存在於不同的級別。充其量您可以說主根輸出是一棵樹,其葉子是腳本,而這些腳本又可以表示為 miniscript 表達式樹 - 但這些樹的性質非常不同。

也許一個更有用的問題是:

既然主根允許使用多個腳本的分離而不是單個腳本來花費輸出,那麼如何將支出策略轉換為腳本樹?

最簡單的情況類似於策略“使用密鑰 K1 簽名或使用密鑰 K2 簽名”。它可以實現為:

  • 單個腳本<K1> OP_CHECKSIG OP_SWAP <K2> OP_CHECKSIG OP_BOOLOR(miniscript or_b(pk(K1),s:pk(K2)))。

  • 兩個腳本的分離:

    • <K1> OP_CHECKSIG (pk(K1))
    • <K2> OP_CHECKSIG (pk(K2))

當我們談論更多涉及的政策時,情況會變得更加複雜:

  • “K1 必須簽名並且 K2 或 K3 必須簽名”可以使用以下方式實現:

    • 單個腳本<K1> OP_CHECKSIGVERIFY <K2> OP_CHECKSIG OP_SWAP <K3> OP_CHECKSIG OP_BOOLOR( and_v(v:pk(K1),or_b(pk(K2),s:pk(K3))))。

    • 兩個腳本的分離:

      • <K1> OP_CHECKSIGVERIFY <K2> OP_CHECKSIG (and_v(v:pk(K1),pk(K2)))
      • <K1> OP_CHECKSIGVERIFY <K3> OP_CHECKSIG (and_v(v:pk(K1),pk(K3)))
  • “必須滿足這三個條件中的兩個:(1)K1 必須簽名(2)K2 必須簽名(3)K3 和 K4 都必須簽名”可以使用以下方式實現:

    • 單個腳本<K3> OP_CHECKSIG OP_SWAP <K4> OP_CHECKSIG OP_BOOLAND OP_SWAP <K1> OP_CHECKSIG OP_ADD OP_SWAP <K2> OP_CHECKSIG OP_ADD 2 OP_EQUAL( thresh(2,and_b(pk(K3),s:pk(K4)),s:pk(K1),s:pk(K2)))

    • 3個腳本的析取:

      • <K1> OP_CHECKSIGVERIFY <K2> OP_CHECKSIG (and_v(v:pk(K1),pk(K2)))
      • <K1> OP_CHECKSIGVERIFY <K3> OP_CHECKSIGVERIFY <K4> OP_CHECKSIG (and_v(v:pk(K1),and_v(v:pk(K3),pk(K4))))
      • <K2> OP_CHECKSIGVERIFY <K3> OP_CHECKSIGVERIFY <K4> OP_CHECKSIG (and_v(v:pk(K2),and_v(v:pk(K3),pk(K4))))

這些選項中的哪一個是最佳的可能取決於具體情況:

  • 使用更多的腳本葉子通常更私密,因為未使用的葉子(以及它們對應的支出條件)不會在花費時間向區塊鏈透露。
  • 使用更多的腳本葉子可能會或可能不會更便宜。在簡單的析取情況下(其中策略是“A 或 B 或 C 或 …”),在單獨的腳本中拆分通常更便宜。當需要將策略轉化為使用單獨腳本的巨大組合爆炸時,單個腳本的花費可能會更便宜。
  • 在單個腳本的情況下,多個簽名方需要合作時的協調可能會更容易,因為他們需要提前決定他們將為哪個腳本簽名(由於 BIP341 sighash 規則送出給實際使用的腳本)。

Taproot 樹是(Tap)腳本的 Merkle(二進制)樹。每個節點(將葉子雜湊到根的過程中的中間狀態)最多有 2 個子節點,並且每個葉子腳本(在樹的底部)在再次雜湊之前通過其雜湊和它​​的連接再次雜湊兄弟的雜湊。

Miniscript 樹不做任何散列,因為它只是將單個(可能非常大)腳本重組為片段。Miniscript 樹的是整個表達式。每個子表達式都是樹中的一個節點。葉子是沒有子表達式的表達式,比如pk()or older()。樹上的一個節點可以有兩個以上的孩子。例如,Miniscript 樹的一個節點可能包含一個thresh()包含超過 2 個子表達式的 a(例如,2-of-3 門檻值將包含三個子表達式)。一個節點也只能有 1 個子節點(例如,如果它包含 Miniscript 包裝器之一a:d:l:)。

Taproot 樹將在Policy級別而不是 Miniscript 級別建構,因為 Taproot 樹的葉子上的每個 (Tap) 腳本都可以表示為單獨的 Miniscript(Miniscript 僅編碼整個 Script 的子集)。但是,如果我們考慮如何建構策略樹的主根樹,如果策略樹的“根”(最高級別)包含 a or(A,B,C),則很容易將其解構為具有葉 A、B 和 C 的主根樹。如果策略根包含一個整個策略and可能需要進入一個單獨的葉子,但也有可能的例外(如果它下面有析取,例如and(or(A,B),C)相當於or(and(A,C),and(B,C))``thresh``or()3 2-of-2s,如本部落格文章中所解釋的 2-of-3 門檻值簽名。

感謝個人回答我關於 IRC 的問題。任何錯誤都是我自己的。

引用自:https://bitcoin.stackexchange.com/questions/113768