Complex Scripts

Let's finish by learning about conditional clauses and flow control, and taking a look at some examples of complex scripts.

Conditional Clauses with VERIFY Opcodes

Another form of conditional in Bitcoin Script is any opcode that ends in VERIFY. The VERIFY suffix means that if the condition evaluated is not TRUE, execution of the script terminates immediately and the transaction is deemed invalid.

Unlike an IF clause, which offers alternative execution paths, the VERIFY suffix acts as a guard clause, continuing only if a precondition is met.

For example, the following script requires Bob's signature and a pre-image (secret) that produces a specific hash. Both conditions must be satisfied to unlock it:

A redeem script with an EQUALVERIFY guard clause.

HASH160 <expected hash> EQUALVERIFY <Bob's Pubkey> CHECKSIG


To redeem this, Bob must construct an unlocking script that presents a valid pre-image and a signature:

An unlocking script to satisfy the above redeem script

<Bob's Sig><hashpre-image>


Without presenting the pre-image, Bob can't get to the part of the script that checks for his signature.

This script can be written with an IF instead:

A redeem script with an IF guard clause

HASH160 <expected hash> EQUAL
IF
    <Bob's Pubkey> CHECKSIG
ENDIF


Bob's unlocking script is identical:

An unlocking script to satisfy the above redeem script

<Bob's Sig><hashpre-image>


The script with IF does the same thing as using an opcode with a VERIFY suffix; they both operate as guard clauses. However, the VERIFY construction is more efficient, using two fewer opcodes.

So, when do we use VERIFY and when do we use IF? If all we are trying to do is to attach a precondition (guard clause), then VERIFY is better. If, however, we want to have more than one execution path (flow control), then we need an IF...ELSE flow control clause.

Tip: An opcode such as EQUAL will push the result (TRUE/FALSE) onto the stack, leaving it there for evaluation by subsequent opcodes. In contrast, the opcode EQUALVERIFY suffix does not leave anything on the stack. Opcodes that end in VERIFY do not leave the result on the stack.