Complex Script Examples

Multisignature Script Examples

The following examples each demonstrate a different means through which multisignature or multi-conditional outputs can be generated which require the spending party to provide precise information to spend an output.

Example 1: Simple Multisignature using OP_CHECKMULTISIG

This is the most simple example of multisignature use available on Bitcoin. A worked example of this can be found here

Example 2: 2 of 3 Multisignature using PKH in outputs (P2MSH)

This example uses the same OP_CHECKMULTISIG opcode however the output is constructed such that it contains only public key hashes rather than public keys.

scriptPubKey: TOALTSTACK TOALTSTACK 2 SWAP DUP HASH160 <PKH1> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG 5 CHECKMULTISIG
scriptSig: 1 <SIG1> <SIG3> <PK1> <PK2> <PK3> 

This script offers users locking keys in a multisignature script a means to hide the public keys being used from the network until such time as the coin is being spent. Assuming that all parties are using best practice to prevent Address reuse this script protects the keyholders in a case of ECDSA being broken.

Note: The current version of the scripting engine also includes a bug that requires an additional value to be placed on the stack before the signatures. In this example, OP_1 has been used to push a 1 to the top of the stack, but in theory any piece of data can be used. This value is consumed by the checking process but is not evaluated.

Checking process:

Stack Script Description
Empty. 1 <SIG1> <SIG3> <PK1> <PK2> <PK3> TOALTSTACK TOALTSTACK 2 SWAP DUP HASH160 <PKH1> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG scriptSig and scriptPubKey are combined.
1 <SIG1> <SIG3> <PK1> <PK2> <PK3> TOALTSTACK TOALTSTACK 2 SWAP DUP HASH160 <PKH1> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG Constants from scriptSig are added to the stack.
1 <SIG1> <SIG3> <PK1> <PK2>
ALTSTACK: <PK3>
TOALTSTACK 2 SWAP DUP HASH160 <PKH1> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG PK3 is pushed to altstack
1 <SIG1> <SIG3> <PK1>
ALTSTACK: <PK3> <PK2>
2 SWAP DUP HASH160 <PKH1> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG PK2 is pushed to altstack
1 <SIG1> <SIG3> <PK1> 2
ALTSTACK: <PK3> <PK2>
SWAP DUP HASH160 <PKH1> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG 2 is pushed to stack (number of sigs required)
1 <SIG1> <SIG3> 2 <PK1>
ALTSTACK: <PK3> <PK2>
DUP HASH160 <PKH1> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG PK1 is brought to front of stack
1 <SIG1> <SIG3> 2 <PK1> <PK1>
ALTSTACK: <PK3> <PK2>
HASH160 <PKH1> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG PK1 is duplicated
1 <SIG1> <SIG3> 2 <PK1> <PKH1>
ALTSTACK: <PK3> <PK2>
<PKH1> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG duplicate PK1 is used to create PKH1
1 <SIG1> <SIG3> 2 <PK1> <PKH1> <PKH1>
ALTSTACK: <PK3> <PK2>
EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG PKH1 from ScriptPubKey is pushed to stack
1 <SIG1> <SIG3> 2 <PK1>
ALTSTACK: <PK3> <PK2>
FROMALTSTACK DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG EQUALVERIFY test
1 <SIG1> <SIG3> 2 <PK1> <PK2>
ALTSTACK: <PK3>
DUP HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG PK2 is moved from ALTSTACK to MAINSTACK
1 <SIG1> <SIG3> 2 <PK1> <PK2> <PK2>
ALTSTACK: <PK3>
HASH160 <PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG PK2 is duplicated
1 <SIG1> <SIG3> 2 <PK1> <PK2> <PKH2>
ALTSTACK: <PK3>
<PKH2> EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG duplicate PK2 is used to create PKH2
1 <SIG1> <SIG3> 2 <PK1> <PK2> <PKH2> <PKH2>
ALTSTACK: <PK3>
EQUALVERIFY FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG PKH2 from ScriptPubKey is pushed to stack
1 <SIG1> <SIG3> 2 <PK1> <PK2>
ALTSTACK: <PK3>
FROMALTSTACK DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG EQUALVERIFY test
1 <SIG1> <SIG3> 2 <PK1> <PK2> <PK3> DUP HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG PK3 is moved from ALTSTACK to MAINSTACK
1 <SIG1> <SIG3> 2 <PK1> <PK2> <PK3> <PK3> HASH160 <PKH3> EQUALVERIFY 3 CHECKMULTISIG PK3 is duplicated
1 <SIG1> <SIG3> 2 <PK1> <PK2> <PK3> <PKH3> <PKH3> EQUALVERIFY 3 CHECKMULTISIG duplicate PK3 is used to create PKH3
1 <SIG1> <SIG3> 2 <PK1> <PK2> <PK3> <PKH3> <PKH3> EQUALVERIFY 3 CHECKMULTISIG PKH3 from ScriptPubKey is pushed to stack
1 <SIG1> <SIG3> 2 <PK1> <PK2> <PK3> <PKH3> <PKH3> 3 CHECKMULTISIG EQUALVERIFY test
1 <SIG1> <SIG3> 2 <PK1> <PK2> <PK3> <PKH3> <PKH3> 3 CHECKMULTISIG 3 is pushed to stack (number of Pubkeys to check signatures against)
true Empty. Multisignature script evaluation is performed