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 2: 2 of 3 Multisignature using PKH in outputs (P2MSH)
This example uses the same OP_CHECKMULTISIG opcode as [[a simple multisignature transaction 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> | 3 CHECKMULTISIG | EQUALVERIFY test |
1 <SIG1> <SIG3> 2 <PK1> <PK2> <PK3> 3 | CHECKMULTISIG | 3 is pushed to stack (number of Pubkeys to check signatures against) |
true | Empty. | Multisignature script evaluation is performed |