Complex Scripts

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

Complex Script Example

In this section we combine many of the concepts from this chapter into a single example.

Our example uses the story of Mohammed, the company owner in Dubai who is operating an import/export business.

In this example, Mohammed wishes to construct a company capital account with flexible rules. The scheme he creates requires different levels of authorization depending on timelocks. The participants in the multisig scheme are Mohammed, his two partners Saeed and Zaira, and their company lawyer Abdul. The three partners make decisions based on a majority rule, so two of the three must agree. However, in the case of a problem with their keys, they want their lawyer to be able to recover the funds with one of the three partner signatures. Finally, if all partners are unavailable or incapacitated for a while, they want the lawyer to be able to manage the account directly.

Here's the redeem script that Mohammed designs to achieve this (line number prefix as XX):

Variable Multi-Signature with Timelock:

01  IF
02    IF
03      2
04    ELSE
05      <30 days> CHECKSEQUENCEVERIFY DROP
06      <Abdul the Lawyer's Pubkey> CHECKSIGVERIFY
07      1
08    ENDIF
09    <Mohammed's Pubkey> <Saeed's Pubkey> <Zaira's Pubkey> 3 CHECKMULTISIG
10  ELSE
11    <90 days> CHECKSEQUENCEVERIFY DROP
12    <Abdul the Lawyer's Pubkey> CHECKSIG
13  ENDIF

 

Mohammed's script implements three execution paths using nested IF...ELSE flow control clauses.

In the first execution path, this script operates as a simple 2-of-3 multisig with the three partners. This execution path consists of lines 3 and 9. Line 3 sets the quorum of the multisig to 2 (2-of-3). This execution path can be selected by putting TRUE TRUE at the end of the unlocking script:

 

Unlocking script for the first execution path (2-of-3 multisig)

0 <Mohammed's Sig> <Zaira's Sig> TRUE TRUE

 

Tip: The 0 at the beginning of this unlocking script is because of a bug in CHECKMULTISIG that pops an extra value from the stack. The extra value is disregarded by the CHECKMULTISIG, but it must be present or the script fails. Pushing 0 (customarily) is a workaround to the bug, as described in A bug in CHECKMULTISIG execution.

The second execution path can only be used after 30 days have elapsed from the creation of the UTXO. At that time, it requires the signature of Abdul the lawyer and one of the three partners (a 1-of-3 multisig). This is achieved by line 7, which sets the quorum for the multisig to 1. To select this execution path, the unlocking script would end in FALSE TRUE:

Unlocking script for the second execution path (Lawyer + 1-of-3):

0 <Abdul the Lawyer's Sig> <Saeed's Sig> FALSE TRUE

 

Tip: Why FALSE TRUE? Isn't that backward? Because the two values are pushed on to the stack, with FALSE pushed first, then TRUE pushed second. TRUE is therefore popped first by the first IF opcode.

Finally, the third execution path allows Abdul the lawyer to spend the funds alone, but only after 90 days. To select this execution path, the unlocking script has to end in FALSE:

Unlocking script for the third execution path (Lawyer only):

<Abdul the Lawyer's Sig> FALSE

 

Try running the script on paper to see how it behaves on the stack.

A few more things to consider when reading this example. See if you can find the answers: 

  • Why can't the lawyer redeem the third execution path at any time by selecting it with FALSE on the unlocking script?
  • How many execution paths can be used 5, 35, and 105 days, respectively, after the UTXO is mined?
  • Are the funds lost if the lawyer loses his key? Does your answer change if 91 days have elapsed?
  • How do the partners "reset" the clock every 29 or 89 days to prevent the lawyer from accessing the funds?
  • Why do some CHECKSIG opcodes in this script have the VERIFY suffix while others don't?