Script

比特幣腳本執行期間“特殊情況”的完整列表(p2sh、p2wsh 等)?

  • January 6, 2021

在執行比特幣腳本時,有一些“特殊情況”,解釋器會執行額外的驗證,而不僅僅是執行scriptSigthen scriptPubKey

例如,如果scriptPubKey具有以下特定格式:

OP_HASH160 <20 byte hash> OP_EQUAL

然後解釋器將另外應用BIP 0016“支付到腳本雜湊”(P2SH)規則。

在腳本執行期間可能遇到的“特殊情況”的完整列表是什麼,以及每種情況何時遇到?

截至 2021 年 1 月,網路上所有活動共識規則的“高級”腳本驗證大致如下:

頂級評價

  • 執行scriptSig, 並呼叫生成的堆棧stack。如果執行中止,則失敗。

  • 執行scriptPubKeywithstack作為輸入,並呼叫生成的 stack result。如果執行中止,則失敗。

  • 如果result為空,或其頂部元素的數值為 0,則失敗。

  • 如果scriptPubKey正好等於一個 OP_n(n 介於 0 和 16 之間,含),然後直接推送正好 2 到 40 個字節(含):

    • 如果scriptSig不為空,則失敗。
    • 使用 as 程序執行 segwit 驗證scriptPubKey,將 n 值作為版本,並witness作為輸入(見進一步)。如果此執行中止,則失敗。
  • 如果scriptPubKey恰好等於 OP_HASH160 + 20 字節推送 + OP_EQUAL,則執行 P2SH 驗證:

    • 如果scriptSig不只包含推送,則失敗。

    • 如果result為空,則失敗。

    • 將 的頂部元素解釋result為腳本,然後執行它,其餘部分result作為輸入。呼叫生成的堆棧p2sh_result。如果此執行中止,則失敗。

    • 如果p2sh_result為空,或其頂部元素的數值為 0,則失敗。

    • 如果頂部元素result恰好是 OP_n(n 介於 0 和 16 之間),然後直接推送 2 到 40 個字節(包括):

      • 如果scriptSig不完全是 的頂部元素的直接推送,則result失敗。
      • 使用 as 程序執行 segwit 驗證scriptPubKey,將 n 值作為版本,並witness作為輸入(見進一步)。如果此執行中止,則失敗。
  • 如果在此之前沒有發生故障,則腳本有效。

遵循驗證

version版本、程序program和輸入的 Segwit 驗證input

  • 如果版本為 0:

    • 如果程序不是 20 或 32 字節,則失敗。

    • 如果程序是 20 字節hash

      • hash使用初始堆棧執行腳本 OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG input。如果執行中止,則失敗。
      • 如果結果堆棧不完全是一個元素,或者該元素的數值為 0,則失敗。
    • 如果程序是 32 字節hash

      • 如果input為空,或者其頂部元素的 SHA256 雜湊不等於hash,則失敗。
      • 執行inputas 腳本的頂部元素,其他元素作為輸入。如果執行中止,則失敗。
      • 如果結果堆棧不完全是一個元素,或者該元素的數值為 0,則失敗。
  • 如果到此為止沒有發生故障,則返回成功。

此答案不包括 BIP341 和 BIP342 引入的更改,因為它們在網路上不活動。它也不包括各種標準/政策規則。

來源:https ://github.com/bitcoin/bitcoin/blob/v0.20.1/src/script/interpreter.cpp ,函式VerifyScript,,,。VerifyWitnessProgram``ExecuteWitnessScript

TL;DR:只有 BIP16 P2SH 模式(OP_HASH160 <20 字節> OP_EQUAL)和 BIP141 segwit 模式(OP_n <2 到 40 字節>)是觸發附加規則的實際特殊情況。但細節更複雜。

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