<p>Thanks to harding for answering this question on IRC and sanket1729 for edits.</p>
<blockquote>
<p>Presumably TRUE is equivalent to 1 and FALSE is equivalent to 0?</p>
</blockquote>
<p>TRUE is any non-zero value.  This is often used in scripts involving the former OP_NOPx opcodes that don't pop their values off the stack after verification, e.g. a script that can be spend by a miner after a certain height could use: <code>&lt;locktime&gt; OP_CLTV</code> ; if CLTV fails, the transaction is invalid; if it passes, then the non-zero  value left on the stack allows the script to pass.</p>
<blockquote>
<p>Any opcodes that evaluate to FALSE will result in immediate failure and termination of execution? So with non-CLEANSTACK you would never see a resulting stack of TRUE FALSE TRUE pass as FALSE would result in immediate failure and you wouldn't assess the final TRUE. However, you could see a stack of say TRUE 3 TRUE 5 and this would pass with non-CLEANSTACK. (It would fail with CLEANSTACK as CLEANSTACK must have a single element in the resulting stack).</p>
</blockquote>
<p>All that matters without CLEANSTACK is the top value on the stack at the end of execution.  Anything further down the stack doesn't matter.</p>
<p>CLEANSTACK is a standardness rule for P2SH but it is a consensus rule for Segwit v0 (<a href="https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program" rel="nofollow noreferrer">BIP141 specification</a>) and Tapscript, SegWit v1 (<a href="https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#specification" rel="nofollow noreferrer">BIP342 specification</a>, rule 4, ii)</p>
<p>The word &quot;failure&quot; is ambiguous here. There are different ways different opcodes can fail. For example, if OP_CHECKSIG fails it just pushes a 0 to the stack. But if OP_CHECKSIGVERIFY fails, the whole script fails. You can put TRUE FALSE FALSE on the stack using just OP_0 OP_0 OP_1.</p>
<p>Some of the VERIFY opcodes e.g. EQUALVERIFY, CHECKSIGVERIFY, CHECKMULTISIGVERIFY terminate immediately on failure but their non-VERIFY equivalents don't.</p>
<p>All that matters is the state of the stack at the end of script evaluation.  For example, you could do OP_CHECKSIG followed by OP_IF OP_PUSHNUM1 OP_ELSE OP_PUSHNUM2 OP_ENDIF, e.g. if the signature succeeds, take one branch; if it fails, take another branch (This isn't considered best practice though and shouldn't generally be done.)</p>
<p>CLEANSTACK is an attempt to prevent malleability by having people put a bunch of junk in your scriptSig or witness data. Because you can just push a bunch of data onto the stack that never gets used and doesn't prevent the script from evaluating correctly. (Pre-segwit, this affected txid malleability and was enforced as a standardness policy rule; with segwit, this is no longer possible as it is a consensus rule)</p>

CC BY-SA 4.0
2020-12-07T14:08:42.777Z
Miniscript ##miniscript
Michael Folkson
CC BY-SA 4.0
2020-12-07T18:36:03.707Z
I think the transaction will fail there is no matching OF_ENDIF for a `OP_IF`, but I am not 100% sure about it.
sanket1729
CC BY-SA 4.0
2020-12-07T18:45:02.420Z
just checked this and suggested an edit
sanket1729
CC BY-SA 4.0
2020-12-08T02:31:26.247Z
@sanket1729 Yes, if there are unbalanced `IF` and `ENDIF` then the script will fail. Similarly if you use `ELSE` outside of any `IF` statement. (Curiously, you can use multiple `ELSE` statements in a row, and the interpreter will just execute all the odd/even ones depending on the input to the `IF`.)
Andrew Poelstra
CC BY-SA 4.0
2020-12-07T13:42:41.880Z
2020-12-07T18:56:50.517Z
2020-12-07T18:56:50.517Z
Michael Folkson
<p>I was watching this Andreas Antonopoulos <a href="https://diyhpl.us/wiki/transcripts/sf-bitcoin-meetup/2017-04-03-andreas-antonopoulos-bitcoin-scripting/" rel="nofollow noreferrer">presentation</a> on Advanced Bitcoin Scripting.</p>
<p>It appears from Andreas' examples that for a redeem script to satisfy the conditions of the script it needs to leave TRUE (and nothing else) on the stack after it has been executed. This was also enquired about <a href="https://bitcoin.stackexchange.com/questions/32132/bitcoin-script-execution-must-end-with-just-true">here</a>.</p>
<p>Therefore there is a VERIFY suffix such that some opcodes (e.g. EQUAL, CHECKSIG, CHECKMULTISIG) have competing opcodes (e.g. EQUALVERIFY, CHECKSIGVERIFY, CHECKMULTISIGVERIFY). Instead of leaving TRUE on the stack these VERIFY opcodes will &quot;continue execution of the Script if the outcome of the conditional operator is TRUE&quot; but &quot;will not push that TRUE back to the stack, it will simply continue execution&quot;. These VERIFY opcodes can be used to ensure the execution of the redeem script leave TRUE (and nothing else) on the stack rather than say TRUE TRUE TRUE.</p>
<p>However, in this Bitcoin Core PR review club <a href="https://bitcoincore.reviews/19698" rel="nofollow noreferrer">session</a> Pieter Wuille stated (paraphrasing):</p>
<blockquote>
<p>For CLEANSTACK you have to have a stack with a single element in it which has to be nonzero. Without CLEANSTACK a non-empty stack with multiple elements is ok as long as the top element is nonzero</p>
</blockquote>
<p>I have two questions:</p>
<ol>
<li><p>Presumably TRUE is equivalent to 1 and FALSE is equivalent to 0?</p>
</li>
<li><p>Any opcodes that evaluate to FALSE will result in immediate failure and termination of execution? So with non-CLEANSTACK you would never see a resulting stack of TRUE FALSE TRUE pass as FALSE would result in immediate failure and you wouldn't assess the final TRUE. However, you could see a stack of say TRUE 3 TRUE 5 and this would pass with non-CLEANSTACK. (It would fail with CLEANSTACK as CLEANSTACK must have a single element in the resulting stack).</p>
</li>
</ol>

<script>
For a redeem script to satisfy the conditions of a script what must it leave on the stack post execution?
Michael Folkson
# For a redeem script to satisfy the conditions of a script what must it leave on the stack post execution?

(Asked by: username_0 on 2020-12-07)

I was watching this Andreas Antonopoulos [presentation](https://diyhpl.us/wiki/transcripts/sf-bitcoin-meetup/2017-04-03-andreas-antonopoulos-bitcoin-scripting/) on Advanced Bitcoin Scripting.

It appears from Andreas' examples that for a redeem script to satisfy the conditions of the script it needs to leave TRUE (and nothing else) on the stack after it has been executed. This was also enquired about [here](https://bitcoin.stackexchange.com/questions/32132/bitcoin-script-execution-must-end-with-just-true).

Therefore there is a VERIFY suffix such that some opcodes (e.g. EQUAL, CHECKSIG, CHECKMULTISIG) have competing opcodes (e.g. EQUALVERIFY, CHECKSIGVERIFY, CHECKMULTISIGVERIFY). Instead of leaving TRUE on the stack these VERIFY opcodes will "continue execution of the Script if the outcome of the conditional operator is TRUE" but "will not push that TRUE back to the stack, it will simply continue execution". These VERIFY opcodes can be used to ensure the execution of the redeem script leave TRUE (and nothing else) on the stack rather than say TRUE TRUE TRUE.

However, in this Bitcoin Core PR review club [session](https://bitcoincore.reviews/19698) Pieter Wuille stated (paraphrasing):

> For CLEANSTACK you have to have a stack with a single element in it which has to be nonzero. Without CLEANSTACK a non-empty stack with multiple elements is ok as long as the top element is nonzero

I have two questions:

1. Presumably TRUE is equivalent to 1 and FALSE is equivalent to 0?
2. Any opcodes that evaluate to FALSE will result in immediate failure and termination of execution? So with non-CLEANSTACK you would never see a resulting stack of TRUE FALSE TRUE pass as FALSE would result in immediate failure and you wouldn't assess the final TRUE. However, you could see a stack of say TRUE 3 TRUE 5 and this would pass with non-CLEANSTACK. (It would fail with CLEANSTACK as CLEANSTACK must have a single element in the resulting stack).

**Tags:** script


---

## 1 answers

### Answer by username_0 on 2020-12-07. Score: 5 | Accepted answer

Thanks to harding for answering this question on IRC and username_1 for edits.

> Presumably TRUE is equivalent to 1 and FALSE is equivalent to 0?

TRUE is any non-zero value. This is often used in scripts involving the former OP\_NOPx opcodes that don't pop their values off the stack after verification, e.g. a script that can be spend by a miner after a certain height could use: `<locktime> OP_CLTV` ; if CLTV fails, the transaction is invalid; if it passes, then the non-zero value left on the stack allows the script to pass.

> Any opcodes that evaluate to FALSE will result in immediate failure and termination of execution? So with non-CLEANSTACK you would never see a resulting stack of TRUE FALSE TRUE pass as FALSE would result in immediate failure and you wouldn't assess the final TRUE. However, you could see a stack of say TRUE 3 TRUE 5 and this would pass with non-CLEANSTACK. (It would fail with CLEANSTACK as CLEANSTACK must have a single element in the resulting stack).

All that matters without CLEANSTACK is the top value on the stack at the end of execution. Anything further down the stack doesn't matter.

CLEANSTACK is a standardness rule for P2SH but it is a consensus rule for Segwit v0 ([BIP141 specification](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program)) and Tapscript, SegWit v1 ([BIP342 specification](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#specification), rule 4, ii)

The word "failure" is ambiguous here. There are different ways different opcodes can fail. For example, if OP\_CHECKSIG fails it just pushes a 0 to the stack. But if OP\_CHECKSIGVERIFY fails, the whole script fails. You can put TRUE FALSE FALSE on the stack using just OP\_0 OP\_0 OP\_1.

Some of the VERIFY opcodes e.g. EQUALVERIFY, CHECKSIGVERIFY, CHECKMULTISIGVERIFY terminate immediately on failure but their non-VERIFY equivalents don't.

All that matters is the state of the stack at the end of script evaluation. For example, you could do OP\_CHECKSIG followed by OP\_IF OP\_PUSHNUM1 OP\_ELSE OP\_PUSHNUM2 OP\_ENDIF, e.g. if the signature succeeds, take one branch; if it fails, take another branch (This isn't considered best practice though and shouldn't generally be done.)

CLEANSTACK is an attempt to prevent malleability by having people put a bunch of junk in your scriptSig or witness data. Because you can just push a bunch of data onto the stack that never gets used and doesn't prevent the script from evaluating correctly. (Pre-segwit, this affected txid malleability and was enforced as a standardness policy rule; with segwit, this is no longer possible as it is a consensus rule)

> **Comments:**
> **username_0**: Miniscript ##miniscript  
> **username_1**: I think the transaction will fail there is no matching OF_ENDIF for a `OP_IF`, but I am not 100% sure about it.  
> **username_1**: just checked this and suggested an edit  
> **username_2**: @username_1 Yes, if there are unbalanced `IF` and `ENDIF` then the script will fail. Similarly if you use `ELSE` outside of any `IF` statement. (Curiously, you can use multiple `ELSE` statements in a row, and the interpreter will just execute all the odd/even ones depending on the input to the `IF`.)  

---

