OP_IF 和 OP_ELSE 的內部工作
具體是如何
OP_ELSE
工作的?有else if
腳本嗎?根據<https://en.bitcoin.it/wiki/Script#Flow_control>,an 之後的語句
OP_ELSE
在三種情況下執行。它說:如果前面的 OP_IF 或 OP_NOTIF 或 OP_ELSE 沒有被執行,那麼這些語句是。
我想了解第三種情況是如何工作的,即
OP_ELSE
沒有遵循前面的情況。考慮這個腳本和True
堆棧頂部的 a:OP_IF <foo> OP_ELSE <bar> OP_ELSE <baz> OP_ENDIF
如果我們按照對這封信的引用的解釋,那麼這意味著
<foo>
並且<baz>
被執行。然而,這非常違反直覺。如果是這種情況,那麼第二個OP_ELSE
是多餘的,因為<baz>
可以簡單地追求<foo>
相同的效果並且使用更少的操作碼。我還缺少其他解釋嗎?
我在嘗試編寫具有 3 個不同分支的腳本時偶然發現了這個細節,例如
OP_IF top stack item is 0 <foo> OP_ELSEIF top stack item is 1 <bar> OP_ELSE <baz> OP_ENDIF
我知道上述不是有效的腳本,但可以在不訴諸以下的情況下實現這種效果嗎?
OP_IF <foo> OP_ELSE OP_IF <bar> OP_ELSE <baz> OP_ENDIF OP_ENDIF
請注意,這不僅因為它具有更多操作碼,而且因為在見證中需要兩個堆棧項才能執行
<bar>
or ,因此成本更高<baz>
。
比特幣腳本中條件的內部工作
比特幣腳本中的條件在概念上是使用一堆布爾值實現的,每個布爾值指示在針對條件的每個深度(嵌套的 IF / ELSE)迭代腳本時是否執行目前操作碼。
為了掌握功能,讓我們首先考慮操作碼的單布爾條件執行。
true
解釋器將通過在開始時將布爾值設置為(執行操作)來遍歷腳本。當遇到 an 時,IF
它會將布爾值設置為 之前的推送數據的值IF
,轉換為布爾值(CastToBool
在參考實現中)。如果是
true
這樣,它將繼續執行以下操作碼,有效地執行“if {}
分支”。如果是
false
,它將暫停執行,直到 …. 它遇到一個ELSE
! 遇到 anELSE
將切換全域布爾暫停執行。如果是以前false
,它將成為true
並有效地執行“else {}
分支”。相反如果是true
,它將成為false
並暫停執行“else {}
分支”。使用一點 ASCII 藝術(
fExec
是全域布爾值,告訴是否實際執行 OP):Value of fExec: true true true true true true false false ??? Script : |start| OP_BLABLA OP_DOSOMETHING <1> OP_IF OP_DOSOMESTUFF OP_ELSE OP_DOANOTHERSTUFF OP_ENDIF
Value of fExec: true true true true false false true true ??? Script : |start| OP_BLABLA OP_DOSOMETHING <0> OP_IF OP_DOSOMESTUFF OP_ELSE OP_DOANOTHERSTUFF OP_ENDIF
請注意我在遇到時如何標記
fExec
as的值。這是因為實際的實現稍微複雜一些:為了支持嵌套條件,這不是一個布爾值,而是一個用於確定執行的布爾值向量。那是:???``OP_ENDIF
OP_IF
將一個新的布爾值推送到向量OP_ELSE
將切換向量的最後一個布爾值OP_ENDIF
將彈出向量的最後一個元素走得更遠
多個
ELSE
為一個IF
請注意,
ELSE
作為單個切換的實現意味著沒有什麼可以阻止連續切換兩次。也就是說,您可以ELSE
在ENDIF
. 兩個後續ELSE
s 將有效地切換最後一個布爾值兩次,因此執行以下操作碼,就像“if {}
分支”一樣。因此,在您的問題範例中:
OP_IF <foo> OP_ELSE <bar> OP_ELSE <baz> OP_ENDIF
確實如此
<foo>
,<baz>
這將被執行。
fExec
從布爾向量計算時的二次行為Pieter Wuille 於 2020 年修改了條件邏輯的實現,以修復Segio Demian Lerner 發現的二次行為。
因此,實際實現實際上不再為布爾值使用堆棧,而是將“頂部布爾值”儲存在模仿先前實現的專用資料結構中。
稍微相關的 Tapscript 規則
作為提議的 Taproot 軟分叉(Tapscript) 的一部分,提議的對腳本規則的新增內容提升了
201
OP 程式碼的限制。這是通過消除上述二次行為而成為可能的。