對於滿足腳本條件的贖回腳本,它在執行後必須在堆棧中留下什麼?
我正在觀看關於高級比特幣腳本的Andreas Antonopoulos展示文稿。
從 Andreas 的範例中可以看出,要滿足腳本條件的贖回腳本,它需要在執行後在堆棧中保留 TRUE(而不是其他任何內容)。這也是在這裡詢問的。
因此有一個 VERIFY 後綴,使得一些操作碼(例如 EQUAL、CHECKSIG、CHECKMULTISIG)具有競爭操作碼(例如 EQUALVERIFY、CHECKSIGVERIFY、CHECKMULTISIGVERIFY)。這些 VERIFY 操作碼不會將 TRUE 留在堆棧中,而是“如果條件運算符的結果為 TRUE,則繼續執行腳本”,但“不會將該 TRUE 推回堆棧,它只會繼續執行”。這些 VERIFY 操作碼可用於確保兌換腳本的執行在堆棧上保留 TRUE(僅此而已),而不是說 TRUE TRUE TRUE。
然而,在這次比特幣核心公關評論俱樂部會議中, Pieter Wuille 說(釋義):
對於 CLEANSTACK,您必須有一個包含單個元素的堆棧,該元素必須為非零。如果沒有 CLEANSTACK,只要頂部元素非零,具有多個元素的非空堆棧就可以了
我有兩個問題:
- 大概 TRUE 相當於 1,FALSE 相當於 0?
- 任何評估為 FALSE 的操作碼將導致立即失敗並終止執行?因此,使用非 CLEANSTACK,您將永遠不會看到 TRUE FALSE TRUE 傳遞的結果堆棧,因為 FALSE 會導致立即失敗,並且您不會評估最終的 TRUE。但是,您可以看到一堆說 TRUE 3 TRUE 5 的堆棧,這將通過 non-CLEANSTACK 傳遞。(它會因 CLEANSTACK 而失敗,因為 CLEANSTACK 在結果堆棧中必須有一個元素)。
感謝 harding 在 IRC 和 sanket1729 上回答這個問題進行編輯。
大概 TRUE 相當於 1,FALSE 相當於 0?
TRUE 是任何非零值。這通常用於涉及以前的 OP_NOPx 操作碼的腳本中,這些操作碼在驗證後不會將其值從堆棧中彈出,例如,礦工可以在一定高度後使用的腳本可以使用
<locktime> OP_CLTV
:如果CLTV失敗,則交易無效;如果它通過,則留在堆棧上的非零值允許腳本通過。任何評估為 FALSE 的操作碼將導致立即失敗並終止執行?因此,使用非 CLEANSTACK,您將永遠不會看到 TRUE FALSE TRUE 傳遞的結果堆棧,因為 FALSE 會導致立即失敗,並且您不會評估最終的 TRUE。但是,您可以看到一堆說 TRUE 3 TRUE 5 的堆棧,這將通過 non-CLEANSTACK 傳遞。(它會因 CLEANSTACK 而失敗,因為 CLEANSTACK 在結果堆棧中必須有一個元素)。
沒有 CLEANSTACK 重要的是執行結束時堆棧上的頂部值。堆棧下方的任何內容都無關緊要。
CLEANSTACK 是 P2SH 的標準規則,但它是 Segwit v0(BIP141 規範)和 Tapscript、SegWit v1(BIP342 規範,規則 4,ii)的共識規則
“失敗”這個詞在這裡是模棱兩可的。不同的操作碼有不同的失敗方式。例如,如果 OP_CHECKSIG 失敗,它只會將 0 壓入堆棧。但是如果 OP_CHECKSIGVERIFY 失敗,整個腳本就會失敗。您可以僅使用 OP_0 OP_0 OP_1 將 TRUE FALSE FALSE 放入堆棧。
某些 VERIFY 操作碼,例如 EQUALVERIFY、CHECKSIGVERIFY、CHECKMULTISIGVERIFY 在失敗時立即終止,但它們的非 VERIFY 等價物不會。
重要的是腳本評估結束時堆棧的狀態。例如,你可以做 OP_CHECKSIG 後跟 OP_IF OP_PUSHNUM1 OP_ELSE OP_PUSHNUM2 OP_ENDIF,例如如果簽名成功,則取一個分支;如果失敗,請使用另一個分支(儘管這不是最佳實踐,通常不應該這樣做。)
CLEANSTACK 試圖通過讓人們在您的 scriptSig 或見證數據中放入一堆垃圾來防止延展性。因為您可以將一堆數據推送到堆棧上,這些數據永遠不會被使用,並且不會阻止腳本正確評估。(在隔離見證之前,這會影響 txid 的延展性並作為標準策略規則執行;使用隔離見證,這不再可能,因為它是共識規則)