I was watching this Andreas Antonopoulos presentation 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.
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 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:
Presumably TRUE is equivalent to 1 and FALSE is equivalent to 0?
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).