UNPKG

8.17 kBMarkdownView Raw
1# Script
2
3All bitcoin transactions have scripts embedded into its inputs and outputs. The scripts use a very simple programming language, which is evaluated from left to right using a stack. The language is designed such that it guarantees all scripts will execute in a limited amount of time (it is not Turing-Complete).
4
5When a transaction is validated, the input scripts are concatenated with the output scripts and evaluated. To be valid, all transaction scripts must evaluate to true. A good analogy for how this works is that the output scripts are puzzles that specify in which conditions can those bitcoins be spent. The input scripts provide the correct data to make those output scripts evaluate to true.
6
7For more detailed information about the bitcoin scripting language, check the online reference [on bitcoin's wiki](https://en.bitcoin.it/wiki/Script).
8
9The `Script` object provides an interface to construct, parse, and identify bitcoin scripts. It also gives simple interfaces to create most common script types. This class is useful if you want to create custom input or output scripts. In other case, you should probably use `Transaction`.
10
11## Script creation
12
13Here's how to use `Script` to create the five most common script types:
14
15### Pay to Public Key Hash (p2pkh)
16
17This is the most commonly used transaction output script. It's used to pay to a bitcoin address (a bitcoin address is a public key hash encoded in base58check)
18
19```javascript
20// create a new p2pkh paying to a specific address
21var address = Address.fromString('1NaTVwXDDUJaXDQajoa9MqHhz4uTxtgK14');
22var script = Script.buildPublicKeyHashOut(address);
23assert(script.toString() === 'OP_DUP OP_HASH160 20 0xecae7d092947b7ee4998e254aa48900d26d2ce1d OP_EQUALVERIFY OP_CHECKSIG');
24```
25
26### Pay to Public Key (p2pk)
27
28Pay to public key scripts are a simplified form of the p2pkh, but aren't commonly used in new transactions anymore, because p2pkh scripts are more secure (the public key is not revealed until the output is spent).
29
30```javascript
31// create a new p2pk paying to a specific public key
32var pubkey = new PublicKey('022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da');
33var script = Script.buildPublicKeyOut(pubkey);
34assert(script.toString() === '33 0x022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da OP_CHECKSIG');
35```
36
37### Pay to Multisig (p2ms)
38
39Multisig outputs allow to share control of bitcoins between several keys. When creating the script, one specifies the public keys that control the funds, and how many of those keys are required to sign off spending transactions to be valid. An output with N public keys of which M are required is called an m-of-n output (For example, 2-of-3, 3-of-5, 4-of-4, etc.)
40
41Note that regular multisig outputs are rarely used nowadays. The best practice is to use a p2sh multisig output (See Script#toScriptHashOut()).
42
43```javascript
44// create a new 2-of-3 multisig output from 3 given public keys
45var pubkeys = [
46 new PublicKey('022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da'),
47 new PublicKey('03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9'),
48 new PublicKey('021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18'),
49];
50var threshold = 2;
51var script = Script.buildMultisigOut(pubkeys, threshold);
52assert(script.toString() === 'OP_2 33 0x022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da'
53 + ' 33 0x03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9'
54 + ' 33 0x021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 OP_3 OP_CHECKMULTISIG');
55```
56
57### Pay to Script Hash (p2sh)
58
59Pay to script hash outputs are scripts that contain the hash of another script, called `redeemScript`. To spend bitcoins sent in a p2sh output, the spending transaction must provide a script matching the script hash and data which makes the script evaluate to true. This allows to defer revealing the spending conditions to the moment of spending. It also makes it possible for the receiver to set the conditions to spend those bitcoins.
60
61Most multisig transactions today use p2sh outputs where the `redeemScript` is a multisig output.
62
63```javascript
64// create a p2sh multisig output
65var pubkeys = [
66 new PublicKey('022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da'),
67 new PublicKey('03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9'),
68 new PublicKey('021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18'),
69];
70var redeemScript = Script.buildMultisigOut(pubkeys, 2);
71var script = redeemScript.toScriptHashOut();
72assert(script.toString() === 'OP_HASH160 20 0x620a6eeaf538ec9eb89b6ae83f2ed8ef98566a03 OP_EQUAL');
73```
74
75### Data output
76
77Data outputs are used to push data into the blockchain. Up to 40 bytes can be pushed in a standard way, but more data can be used, if a miner decides to accept the transaction.
78
79```javascript
80var data = 'hello world!!!';
81var script = Script.buildDataOut(data);
82assert(script.toString() === 'OP_RETURN 14 0x68656c6c6f20776f726c64212121'
83```
84
85### Custom Scripts
86
87To create a custom `Script` instance, you must rely on the lower-level methods `add` and `prepend`. Both methods accept the same parameter types, and insert an opcode or data at the beginning (`prepend`) or end (`add`) of the `Script`.
88
89```javascript
90var script = Script()
91 .add('OP_IF') // add an opcode by name
92 .prepend(114) // add OP_2SWAP by code
93 .add(Opcode.OP_NOT) // add an opcode object
94 .add(new Buffer('bacacafe', 'hex')) // add a data buffer (will append the size of the push operation first)
95
96assert(script.toString() === 'OP_2SWAP OP_IF OP_NOT 4 0xbacacafe');
97```
98
99## Script Parsing and Identification
100
101`Script` has an easy interface to parse raw scripts from the network or bitcoind, and to extract useful information. An illustrative example (for more options check the API reference)
102
103```javascript
104var raw_script = new Buffer('5221022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da2103e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e921021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc1853ae', 'hex');
105var s = new Script(raw_script);
106console.log(s.toString());
107// 'OP_2 33 0x022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da 33 0x03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 33 0x021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 OP_3 OP_CHECKMULTISIG'
108
109s.isPublicKeyHashOut() // false
110s.isScriptHashOut() // false
111s.isMultisigOut() // true
112```
113
114## Script Interpreting and Validation
115
116To validate a transaction, the bitcoin network validates all of its inputs and outputs. To validate an input, the input's script is concatenated with the referenced output script, and the result is executed. If at the end of execution the stack contains a 'true' value, then the transaction is valid. You can do this in `bitcore` by using the `Interpreter` class. The entry point (and probably the only interface you'll need for most applications) is the method `Interpreter#verify()`.
117
118You can use it like this:
119
120```javascript
121var inputScript = Script('OP_1');
122var outputScript = Script('OP_15 OP_ADD OP_16 OP_EQUAL');
123
124var verified = Interpreter().verify(inputScript, outputScript);
125// verified will be true
126```
127
128Note that `verify` expects two scripts: one is the input script (scriptSig) and the other is the output script (scriptPubkey). This is because different conditions are checked for each.
129
130It also accepts some optional parameters, assuming defaults if not provided:
131
132```javascript
133// first we create a transaction
134var tx = new Transaction()
135 .from(utxo)
136 .to(toAddress, 100000)
137 .sign(privateKey);
138
139// we then extract the signature from the first input
140var inputIndex = 0;
141var signature = tx.getSignatures(privateKey)[inputIndex].signature;
142
143var scriptSig = Script.buildPublicKeyHashIn(publicKey, signature);
144var flags = Interpreter.SCRIPT_VERIFY_P2SH | Interpreter.SCRIPT_VERIFY_STRICTENC;
145var verified = Interpreter().verify(scriptSig, scriptPubkey, tx, inputIndex, flags);
146```