如何使用 CHECKSIGFROMSTACKVERIFY 模擬 SIGHASH_NOINPUT?
我在 bitcoin-dev上讀到 CHECKSIGFROMSTACKVERIFY(BCash 中的 CHECKDATASIG)可用於模擬新的 sighash 標誌。具體來說,這將如何運作?作為範例,請提供基於Eltoo 論文圖 4 的範例更新事務,或aj 的簡化閃電(不適用於瞭望塔)。
Eltoo 依賴於原語
SIGHASH_ANYPREVOUT
或SIGHASH_NOINPUT
(以下稱為 APO)BPI118,從 APO 建構 Eltoo 將用修改後的腳本替換Eltoo 論文CHECKSIG
的圖 4 。該答案的大部分內容基於此連結中 Russell O’Connor 的部落格文章(該連結也涉及其他盟約結構)。為了完整起見,讓我們看一下事務自省的基礎知識,然後再討論如何構造
APO
. 答案是隔離見證簽名雜湊和 ECDSA 簽名算法。不幸的是,將其擴展到主根需要額外的操作碼/其他更改,我將在答案末尾解釋。
OP_CHECKSIGFROMSTACK
:(此後CSFS
)這個操作碼還沒有正式的提議,但很可能它會按如下方式工作:pop 1) a pubkeypk
, 2) a messagem
, and a 3) digital signaturesig
。該操作將驗證 sig 作為 ECSDA.Verify(pk, sha256(m), sig) 並將結果推送到堆棧頂部。- OP_CAT:從堆棧中彈出兩個項目
top
並next_top
壓入next_top || top
堆棧,其中||
表示字節字元串連接。我將假設一個SIGHASH_ALL
用於以下構造,但該構造可用於 sighash 類型。
OP_CAT
首先,我們將使用and來查看基本的事務自省OP_CSFS
:考慮以下腳本:1. OP_OVER OP_SHA256 <pubKey> 2. 2 OP_PICK 1 OP_CAT OP_OVER 3. OP_CHECKSIGVERIFY 4. OP_CHECKSIGFROMSTACKVERIFY
與見證堆棧
<sig> <sig_msg>
哪裡
<fixed_pk>
是公開的,每個人都知道其密鑰。比如說,G
密鑰為的生成器1
。<sig_msg>
表示正在簽名的轉換摘要。在步驟 1 結束時,堆棧為
<pubKey> <sha256(<sig_msg>)> <signature> <<sig_msg>>
在第 2 步結束時,堆棧內容為
<pubKey> <sig;SIGHASH_ALL> <pubKey> <sha256(sig_msg)> <sig> <sig_msg>
請注意,它
1
被翻譯為SIGHASH_ALL
並 catted 為sig
. 這會創建一個正常的比特幣簽名,我們可以使用正常OP_CHECKSIG
的 . 步驟 3 之後,堆棧內容為<pubKey> <sha256(sig_msg)> <sig> <sig_msg>
這會要求
OP_CHECKSIGFROMSTACKVERIFY
只留<sig_msg>
在堆棧上。第 4 步的 OP_CHECKSIGFROMSTACKVERIFY 使用相同的 pubKey 和簽名。此操作執行另一個 SHA-256(segwit sighash 算法需要雙 sha256)並對雙散列 <sig_msg> 進行數字簽名驗證。請注意,因為我們使用的<pubKey>
和<sig>
之前的OP_CHECKSIGVERIFY
操作完全相同,所以只有在 <sig_msg> 與步驟 3 的 OP_CHECKSIGVERIFY 操作期間檢查的消息相同時,目前OP_CHECKSIGFROMSTACKVERIFY
才能成功。至此,我們可以確定<sig_msg>
棧頂上的 和簽名的交易消息是一樣的。*請注意,*由於私鑰是已知的,任何人都可以創建此簽名,但此腳本只有在如上所述正確指定
<fixed_pk>
時才會成功。<sig_msg>
到 ANYPREVOUT:
Anyprevout 本質上是從正常簽名雜湊消息中替換一些東西,並用 0 替換那些東西。詳細地說,我們現在可以
sig_msg
按照BIP143中的定義使用OP_SUBSTR
. 也可以使用OP_CAT
最初提供拆分的消息,然後將其集中在一起。現在我們在堆棧上有了符合 BIP143 的簽名雜湊消息,我們對其進行操作以使某些欄位為 0。特別是,我們將項目 2-4 設為 0。
2. hashPrevouts (32-byte hash) 3. hashSequence (32-byte hash) 4. outpoint (32-byte hash + 4-byte little endian)
我們採取 a
OP_DUP OP_SUSTR 0 <4>
得到第 1 項,版本。到堆棧上。同樣,將項目 5-10 連接到堆棧上。最後,我們通過 <items 5.10>將它們組合在一起
<ver> <[0; (32+ 32 + (32 +4))]>`以獲得一個新的 sighash,我們將其用於 Eltoo 更新密鑰。讓
introspect_script
=OP_OVER OP_SHA256 <pubKey> 2 OP_PICK 1 OP_CAT OP_OVER OP_CHECKSIGVERIFY OP_CHECKSIGFROMSTACKVERIFY
正如我們上面所討論的。並讓
manipulate_txdata_script
腳本從 BIP143 sighash 消息中修改堆棧內容以獲取將相應項目設置為的新消息0s
。然後我們的最終替代品OP_CHECKSIGANYPREVOUT
將是以下腳本。final_script(eltoo_pk) = <introspect_script> <manipulate_txdata_script> <eltoo_pk> OP_CSFS
滿足這一點需要在初始見證堆棧中添加以下內容。
<sig_from_fixed_key> <sig_msg> <sig_from_eltoo_update_priv_key>
最後,eltoo 腳本現在看起來像:
OP_IF 10 OP_CSV 2 A(s,i) B(s,i) 2 OP_CHECKMULTISIGVERIFY OP_ELSE <Si + 1> OP_CHECKLOCKTIMEVERIFY final_script(Au) final_script(Bu) OP_ENDIF
注意兩個多重簽名中的兩個是如何分成兩部分的。
Taproot簽名雜湊:
由於標記的雜湊,相同的技術不適用於 Taproot 簽名雜湊算法(請參閱BIP341)和 Schnorr 簽名(請參閱BIP340)。在高層次上,由於標籤,這些消息的大小超過 520 字節,這是目前比特幣網路支持的最大值。可以通過添加 1) 流式
SHA256
操作碼、2) 通過提高每個堆棧元素限製或 3) 通過新操作碼添加對標記雜湊的支持來克服此限制。