@opcat-labs/opcat 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/.mocharc.yaml +3 -0
  2. package/index.d.ts +1541 -0
  3. package/index.js +74 -0
  4. package/lib/address.js +478 -0
  5. package/lib/block/block.js +277 -0
  6. package/lib/block/blockheader.js +295 -0
  7. package/lib/block/index.js +4 -0
  8. package/lib/block/merkleblock.js +323 -0
  9. package/lib/bn.js +3423 -0
  10. package/lib/crypto/bn.js +278 -0
  11. package/lib/crypto/ecdsa.js +339 -0
  12. package/lib/crypto/hash.browser.js +171 -0
  13. package/lib/crypto/hash.js +2 -0
  14. package/lib/crypto/hash.node.js +171 -0
  15. package/lib/crypto/point.js +221 -0
  16. package/lib/crypto/random.browser.js +28 -0
  17. package/lib/crypto/random.js +2 -0
  18. package/lib/crypto/random.node.js +11 -0
  19. package/lib/crypto/signature.js +325 -0
  20. package/lib/encoding/base58.js +111 -0
  21. package/lib/encoding/base58check.js +121 -0
  22. package/lib/encoding/bufferreader.js +212 -0
  23. package/lib/encoding/bufferwriter.js +140 -0
  24. package/lib/encoding/decode-asm.js +24 -0
  25. package/lib/encoding/decode-hex.js +32 -0
  26. package/lib/encoding/decode-script-chunks.js +43 -0
  27. package/lib/encoding/encode-hex.js +284 -0
  28. package/lib/encoding/is-hex.js +7 -0
  29. package/lib/encoding/varint.js +75 -0
  30. package/lib/errors/index.js +54 -0
  31. package/lib/errors/spec.js +314 -0
  32. package/lib/hash-cache.js +50 -0
  33. package/lib/hdprivatekey.js +678 -0
  34. package/lib/hdpublickey.js +525 -0
  35. package/lib/message/message.js +191 -0
  36. package/lib/mnemonic/mnemonic.js +303 -0
  37. package/lib/mnemonic/pbkdf2.browser.js +68 -0
  38. package/lib/mnemonic/pbkdf2.js +2 -0
  39. package/lib/mnemonic/pbkdf2.node.js +68 -0
  40. package/lib/mnemonic/words/chinese.js +2054 -0
  41. package/lib/mnemonic/words/english.js +2054 -0
  42. package/lib/mnemonic/words/french.js +2054 -0
  43. package/lib/mnemonic/words/index.js +8 -0
  44. package/lib/mnemonic/words/italian.js +2054 -0
  45. package/lib/mnemonic/words/japanese.js +2054 -0
  46. package/lib/mnemonic/words/spanish.js +2054 -0
  47. package/lib/networks.js +379 -0
  48. package/lib/opcode.js +255 -0
  49. package/lib/privatekey.js +374 -0
  50. package/lib/publickey.js +386 -0
  51. package/lib/script/index.js +5 -0
  52. package/lib/script/interpreter.js +1834 -0
  53. package/lib/script/script.js +1074 -0
  54. package/lib/script/stack.js +109 -0
  55. package/lib/script/write-i32-le.js +17 -0
  56. package/lib/script/write-push-data.js +35 -0
  57. package/lib/script/write-u16-le.js +12 -0
  58. package/lib/script/write-u32-le.js +16 -0
  59. package/lib/script/write-u64-le.js +24 -0
  60. package/lib/script/write-u8-le.js +8 -0
  61. package/lib/script/write-varint.js +46 -0
  62. package/lib/transaction/index.js +7 -0
  63. package/lib/transaction/input/index.js +5 -0
  64. package/lib/transaction/input/input.js +354 -0
  65. package/lib/transaction/input/multisig.js +242 -0
  66. package/lib/transaction/input/publickey.js +100 -0
  67. package/lib/transaction/input/publickeyhash.js +118 -0
  68. package/lib/transaction/output.js +231 -0
  69. package/lib/transaction/sighash.js +167 -0
  70. package/lib/transaction/signature.js +97 -0
  71. package/lib/transaction/transaction.js +1639 -0
  72. package/lib/transaction/unspentoutput.js +113 -0
  73. package/lib/util/_.js +47 -0
  74. package/lib/util/js.js +90 -0
  75. package/lib/util/preconditions.js +33 -0
  76. package/package.json +26 -0
  77. package/test/address.js +509 -0
  78. package/test/block/block.js +251 -0
  79. package/test/block/blockheader.js +275 -0
  80. package/test/block/merklebloack.js +211 -0
  81. package/test/crypto/bn.js +177 -0
  82. package/test/crypto/ecdsa.js +391 -0
  83. package/test/crypto/hash.browser.js +135 -0
  84. package/test/crypto/hash.js +136 -0
  85. package/test/crypto/point.js +224 -0
  86. package/test/crypto/random.js +32 -0
  87. package/test/crypto/signature.js +409 -0
  88. package/test/data/bip69.json +215 -0
  89. package/test/data/bitcoind/base58_keys_invalid.json +52 -0
  90. package/test/data/bitcoind/base58_keys_valid.json +335 -0
  91. package/test/data/bitcoind/blocks.json +22 -0
  92. package/test/data/bitcoind/script_tests.json +3822 -0
  93. package/test/data/bitcoind/sig_canonical.json +7 -0
  94. package/test/data/bitcoind/sig_noncanonical.json +36 -0
  95. package/test/data/bitcoind/tx_invalid.json +445 -0
  96. package/test/data/bitcoind/tx_valid.json +44 -0
  97. package/test/data/blk86756-testnet.dat +0 -0
  98. package/test/data/blk86756-testnet.js +14 -0
  99. package/test/data/blk86756-testnet.json +684 -0
  100. package/test/data/block.hex +1 -0
  101. package/test/data/ecdsa.json +230 -0
  102. package/test/data/merkleblocks.js +488 -0
  103. package/test/data/messages.json +22 -0
  104. package/test/data/sighash.json +12 -0
  105. package/test/data/tx_creation.json +95 -0
  106. package/test/encoding/base58.js +131 -0
  107. package/test/encoding/base58check.js +136 -0
  108. package/test/encoding/bufferreader.js +337 -0
  109. package/test/encoding/bufferwriter.js +172 -0
  110. package/test/encoding/varint.js +104 -0
  111. package/test/hashCache.js +67 -0
  112. package/test/hdkeys.js +445 -0
  113. package/test/hdprivatekey.js +332 -0
  114. package/test/hdpublickey.js +304 -0
  115. package/test/index.js +16 -0
  116. package/test/message/message.js +204 -0
  117. package/test/mnemonic/data/fixtures.json +300 -0
  118. package/test/mnemonic/mnemonic.js +259 -0
  119. package/test/mnemonic/mocha.opts +1 -0
  120. package/test/mnemonic/pbkdf2.test.js +59 -0
  121. package/test/networks.js +159 -0
  122. package/test/opcode.js +161 -0
  123. package/test/privatekey.js +439 -0
  124. package/test/publickey.js +554 -0
  125. package/test/script/interpreter.js +734 -0
  126. package/test/script/script.js +1437 -0
  127. package/test/transaction/deserialize.js +34 -0
  128. package/test/transaction/input/input.js +90 -0
  129. package/test/transaction/input/multisig.js +90 -0
  130. package/test/transaction/input/publickey.js +68 -0
  131. package/test/transaction/input/publickeyhash.js +51 -0
  132. package/test/transaction/output.js +185 -0
  133. package/test/transaction/sighash.js +65 -0
  134. package/test/transaction/signature.js +114 -0
  135. package/test/transaction/transaction.js +1109 -0
  136. package/test/transaction/unspentoutput.js +110 -0
  137. package/test/util/js.js +76 -0
  138. package/test/util/preconditions.js +79 -0
@@ -0,0 +1,379 @@
1
+ 'use strict';
2
+ var _ = require('./util/_');
3
+
4
+ var JSUtil = require('./util/js');
5
+ var networks = [];
6
+ var networkMaps = {};
7
+
8
+ /**
9
+ * A network is merely a map containing values that correspond to version
10
+ * numbers for each bitcoin network. Currently only supporting "livenet"
11
+ * (a.k.a. "mainnet"), "testnet", "regtest" and "stn".
12
+ * @constructor
13
+ */
14
+ function Network() {}
15
+
16
+ Network.prototype.toString = function toString() {
17
+ return this.name;
18
+ };
19
+
20
+ /**
21
+ * @function
22
+ * @member Networks#get
23
+ * Retrieves the network associated with a magic number or string.
24
+ * @param {string|number|Network} arg
25
+ * @param {string|Array} keys - if set, only check if the magic number associated with this name matches
26
+ * @return Network
27
+ */
28
+ function get(arg, keys) {
29
+ if (~networks.indexOf(arg)) {
30
+ return arg;
31
+ }
32
+ if (keys) {
33
+ if (!_.isArray(keys)) {
34
+ keys = [keys];
35
+ }
36
+ for (var i = 0; i < networks.length; i++) {
37
+ var network = networks[i];
38
+ var filteredNet = _.pick(network, keys);
39
+ var netValues = _.values(filteredNet);
40
+ if (~netValues.indexOf(arg)) {
41
+ return network;
42
+ }
43
+ }
44
+ return undefined;
45
+ }
46
+ return networkMaps[arg];
47
+ }
48
+
49
+ /***
50
+ * Derives an array from the given cashAddrPrefix to be used in the computation
51
+ * of the address' checksum.
52
+ *
53
+ * @param {string} cashAddrPrefix Network cashAddrPrefix. E.g.: 'bitcoincash'.
54
+ */
55
+ function cashAddrPrefixToArray(cashAddrPrefix) {
56
+ var result = [];
57
+ for (var i = 0; i < cashAddrPrefix.length; i++) {
58
+ result.push(cashAddrPrefix.charCodeAt(i) & 31);
59
+ }
60
+ return result;
61
+ }
62
+
63
+ /**
64
+ * @function
65
+ * @member Networks#add
66
+ * Will add a custom Network
67
+ * @param {Object} data
68
+ * @param {string} data.name - The name of the network
69
+ * @param {string} data.alias - The aliased name of the network
70
+ * @param {Number} data.pubkeyhash - The publickey hash cashAddrPrefix
71
+ * @param {Number} data.privatekey - The privatekey cashAddrPrefix
72
+ * @param {Number} data.scripthash - The scripthash cashAddrPrefix
73
+ * @param {Number} data.xpubkey - The extended public key magic
74
+ * @param {Number} data.xprivkey - The extended private key magic
75
+ * @param {Number} data.networkMagic - The network magic number
76
+ * @param {Number} data.port - The network port
77
+ * @param {Array} data.dnsSeeds - An array of dns seeds
78
+ * @return Network
79
+ */
80
+ function addNetwork(data) {
81
+ var network = new Network();
82
+
83
+ JSUtil.defineImmutable(network, {
84
+ name: data.name,
85
+ alias: data.alias,
86
+ pubkeyhash: data.pubkeyhash,
87
+ privatekey: data.privatekey,
88
+ scripthash: data.scripthash,
89
+ xpubkey: data.xpubkey,
90
+ xprivkey: data.xprivkey,
91
+ });
92
+
93
+ var indexBy = data.indexBy || Object.keys(data);
94
+
95
+ if (data.cashAddrPrefix) {
96
+ _.extend(network, {
97
+ cashAddrPrefix: data.cashAddrPrefix,
98
+ cashAddrPrefixArray: cashAddrPrefixToArray(data.cashAddrPrefix),
99
+ });
100
+ }
101
+
102
+ if (data.networkMagic) {
103
+ _.extend(network, {
104
+ networkMagic: JSUtil.integerAsBuffer(data.networkMagic),
105
+ });
106
+ }
107
+
108
+ if (data.port) {
109
+ _.extend(network, {
110
+ port: data.port,
111
+ });
112
+ }
113
+
114
+ if (data.dnsSeeds) {
115
+ _.extend(network, {
116
+ dnsSeeds: data.dnsSeeds,
117
+ });
118
+ }
119
+ networks.push(network);
120
+ indexNetworkBy(network, indexBy);
121
+ return network;
122
+ }
123
+
124
+ function indexNetworkBy(network, keys) {
125
+ for (var i = 0; i < keys.length; i++) {
126
+ var key = keys[i];
127
+ var networkValue = network[key];
128
+ if (!_.isUndefined(networkValue) && !_.isObject(networkValue)) {
129
+ networkMaps[networkValue] = network;
130
+ }
131
+ }
132
+ }
133
+
134
+ function unindexNetworkBy(network, values) {
135
+ for (var index = 0; index < values.length; index++) {
136
+ var value = values[index];
137
+ if (networkMaps[value] === network) {
138
+ delete networkMaps[value];
139
+ }
140
+ }
141
+ }
142
+
143
+ /**
144
+ * @function
145
+ * @member Networks#remove
146
+ * Will remove a custom network
147
+ * @param {Network} network
148
+ */
149
+ function removeNetwork(network) {
150
+ for (var i = 0; i < networks.length; i++) {
151
+ if (networks[i] === network) {
152
+ networks.splice(i, 1);
153
+ }
154
+ }
155
+ unindexNetworkBy(network, Object.keys(networkMaps));
156
+ }
157
+
158
+ var networkMagic = {
159
+ livenet: 0xe3e1f3e8,
160
+ testnet: 0xf4e5f3f4,
161
+ regtest: 0xdab5bffa,
162
+ stn: 0xfbcec4f9,
163
+ };
164
+
165
+ var dnsSeeds = ['seed.bitcoinsv.org', 'seed.bitcoinunlimited.info'];
166
+
167
+ var TESTNET = {
168
+ PORT: 18333,
169
+ NETWORK_MAGIC: networkMagic.testnet,
170
+ DNS_SEEDS: dnsSeeds,
171
+ PREFIX: 'testnet',
172
+ CASHADDRPREFIX: 'bchtest',
173
+ };
174
+
175
+ var REGTEST = {
176
+ PORT: 18444,
177
+ NETWORK_MAGIC: networkMagic.regtest,
178
+ DNS_SEEDS: [],
179
+ PREFIX: 'regtest',
180
+ CASHADDRPREFIX: 'bchreg',
181
+ };
182
+
183
+ var STN = {
184
+ PORT: 9333,
185
+ NETWORK_MAGIC: networkMagic.stn,
186
+ DNS_SEEDS: ['stn-seed.bitcoinsv.io'],
187
+ PREFIX: 'stn',
188
+ CASHADDRPREFIX: 'opcatstn',
189
+ };
190
+
191
+ var liveNetwork = {
192
+ name: 'livenet',
193
+ alias: 'mainnet',
194
+ prefix: 'bitcoin',
195
+ cashAddrPrefix: 'bitcoincash',
196
+ pubkeyhash: 0x00,
197
+ privatekey: 0x80,
198
+ scripthash: 0x05,
199
+ xpubkey: 0x0488b21e,
200
+ xprivkey: 0x0488ade4,
201
+ networkMagic: networkMagic.livenet,
202
+ port: 8333,
203
+ dnsSeeds: dnsSeeds,
204
+ };
205
+
206
+ // network magic, port, cashAddrPrefix, and dnsSeeds are overloaded by enableRegtest
207
+ var testNetwork = {
208
+ name: 'testnet',
209
+ prefix: TESTNET.PREFIX,
210
+ cashAddrPrefix: TESTNET.CASHADDRPREFIX,
211
+ pubkeyhash: 0x6f,
212
+ privatekey: 0xef,
213
+ scripthash: 0xc4,
214
+ xpubkey: 0x043587cf,
215
+ xprivkey: 0x04358394,
216
+ networkMagic: TESTNET.NETWORK_MAGIC,
217
+ };
218
+
219
+ var regtestNetwork = {
220
+ name: 'regtest',
221
+ prefix: REGTEST.PREFIX,
222
+ cashAddrPrefix: REGTEST.CASHADDRPREFIX,
223
+ pubkeyhash: 0x6f,
224
+ privatekey: 0xef,
225
+ scripthash: 0xc4,
226
+ xpubkey: 0x043587cf,
227
+ xprivkey: 0x04358394,
228
+ networkMagic: REGTEST.NETWORK_MAGIC,
229
+ port: REGTEST.PORT,
230
+ dnsSeeds: [],
231
+ indexBy: ['port', 'name', 'cashAddrPrefix', 'networkMagic'],
232
+ };
233
+ var stnNetwork = {
234
+ name: 'stn',
235
+ prefix: STN.PREFIX,
236
+ cashAddrPrefix: STN.CASHADDRPREFIX,
237
+ pubkeyhash: 0x6f,
238
+ privatekey: 0xef,
239
+ scripthash: 0xc4,
240
+ xpubkey: 0x043587cf,
241
+ xprivkey: 0x04358394,
242
+ networkMagic: STN.NETWORK_MAGIC,
243
+ indexBy: ['port', 'name', 'cashAddrPrefix', 'networkMagic'],
244
+ };
245
+ // Add configurable values for testnet/regtest
246
+
247
+ addNetwork(testNetwork);
248
+ addNetwork(stnNetwork);
249
+ addNetwork(regtestNetwork);
250
+ addNetwork(liveNetwork);
251
+
252
+ var livenet = get('livenet');
253
+ var regtest = get('regtest');
254
+ var testnet = get('testnet');
255
+ var stn = get('stn');
256
+
257
+ Object.defineProperty(testnet, 'port', {
258
+ enumerable: true,
259
+ configurable: false,
260
+ get: function () {
261
+ if (this.regtestEnabled) {
262
+ return REGTEST.PORT;
263
+ } else if (this.stnEnabled) {
264
+ return STN.PORT;
265
+ } else {
266
+ return TESTNET.PORT;
267
+ }
268
+ },
269
+ });
270
+
271
+ Object.defineProperty(testnet, 'networkMagic', {
272
+ enumerable: true,
273
+ configurable: false,
274
+ get: function () {
275
+ if (this.regtestEnabled) {
276
+ return JSUtil.integerAsBuffer(REGTEST.NETWORK_MAGIC);
277
+ } else if (this.stnEnabled) {
278
+ return JSUtil.integerAsBuffer(STN.NETWORK_MAGIC);
279
+ } else {
280
+ return JSUtil.integerAsBuffer(TESTNET.NETWORK_MAGIC);
281
+ }
282
+ },
283
+ });
284
+
285
+ Object.defineProperty(testnet, 'dnsSeeds', {
286
+ enumerable: true,
287
+ configurable: false,
288
+ get: function () {
289
+ if (this.regtestEnabled) {
290
+ return REGTEST.DNS_SEEDS;
291
+ } else if (this.stnEnabled) {
292
+ return STN.DNS_SEEDS;
293
+ } else {
294
+ return TESTNET.DNS_SEEDS;
295
+ }
296
+ },
297
+ });
298
+
299
+ Object.defineProperty(testnet, 'cashAddrPrefix', {
300
+ enumerable: true,
301
+ configurable: false,
302
+ get: function () {
303
+ if (this.regtestEnabled) {
304
+ return REGTEST.CASHADDRPREFIX;
305
+ } else if (this.stnEnabled) {
306
+ return STN.CASHADDRPREFIX;
307
+ } else {
308
+ return TESTNET.CASHADDRPREFIX;
309
+ }
310
+ },
311
+ });
312
+
313
+ Object.defineProperty(testnet, 'cashAddrPrefixArray', {
314
+ enumerable: true,
315
+ configurable: false,
316
+ get: function () {
317
+ if (this.regtestEnabled) {
318
+ return cashAddrPrefixToArray(REGTEST.CASHADDRPREFIX);
319
+ } else if (this.stnEnabled) {
320
+ return STN.cashAddrPrefixToArray(STN.CASHADDRPREFIX);
321
+ } else {
322
+ return cashAddrPrefixToArray(TESTNET.CASHADDRPREFIX);
323
+ }
324
+ },
325
+ });
326
+
327
+ /**
328
+ * @function
329
+ * @member Networks#enableRegtest
330
+ * Will enable regtest features for testnet
331
+ */
332
+ function enableRegtest() {
333
+ testnet.regtestEnabled = true;
334
+ }
335
+
336
+ /**
337
+ * @function
338
+ * @member Networks#disableRegtest
339
+ * Will disable regtest features for testnet
340
+ */
341
+ function disableRegtest() {
342
+ testnet.regtestEnabled = false;
343
+ }
344
+ /**
345
+ * @function
346
+ * @member Networks#enableStn
347
+ * Will enable stn features for testnet
348
+ */
349
+ function enableStn() {
350
+ testnet.stnEnabled = true;
351
+ }
352
+
353
+ /**
354
+ * @function
355
+ * @member Networks#disableStn
356
+ * Will disable stn features for testnet
357
+ */
358
+ function disableStn() {
359
+ testnet.stnEnabled = false;
360
+ }
361
+
362
+ /**
363
+ * @namespace Networks
364
+ */
365
+ module.exports = {
366
+ add: addNetwork,
367
+ remove: removeNetwork,
368
+ defaultNetwork: livenet,
369
+ livenet: livenet,
370
+ mainnet: livenet,
371
+ testnet: testnet,
372
+ regtest: regtest,
373
+ stn: stn,
374
+ get: get,
375
+ enableRegtest: enableRegtest,
376
+ disableRegtest: disableRegtest,
377
+ enableStn: enableStn,
378
+ disableStn: disableStn,
379
+ };
package/lib/opcode.js ADDED
@@ -0,0 +1,255 @@
1
+ 'use strict';
2
+
3
+ var _ = require('./util/_');
4
+ var $ = require('./util/preconditions');
5
+ var JSUtil = require('./util/js');
6
+
7
+ function Opcode(num) {
8
+ if (!(this instanceof Opcode)) {
9
+ return new Opcode(num);
10
+ }
11
+
12
+ var value;
13
+
14
+ if (_.isNumber(num)) {
15
+ value = num;
16
+ } else if (_.isString(num)) {
17
+ value = Opcode.map[num];
18
+ } else {
19
+ throw new TypeError('Unrecognized num type: "' + typeof num + '" for Opcode');
20
+ }
21
+
22
+ JSUtil.defineImmutable(this, {
23
+ num: value,
24
+ });
25
+
26
+ return this;
27
+ }
28
+
29
+ Opcode.fromBuffer = function (buf) {
30
+ $.checkArgument(Buffer.isBuffer(buf));
31
+ return new Opcode(Number('0x' + buf.toString('hex')));
32
+ };
33
+
34
+ Opcode.fromNumber = function (num) {
35
+ $.checkArgument(_.isNumber(num));
36
+ return new Opcode(num);
37
+ };
38
+
39
+ Opcode.fromString = function (str) {
40
+ $.checkArgument(_.isString(str));
41
+ var value = Opcode.map[str];
42
+ if (typeof value === 'undefined') {
43
+ throw new TypeError('Invalid opcodestr');
44
+ }
45
+ return new Opcode(value);
46
+ };
47
+
48
+ Opcode.prototype.toHex = function () {
49
+ return this.num.toString(16);
50
+ };
51
+
52
+ Opcode.prototype.toBuffer = function () {
53
+ return Buffer.from(this.toHex(), 'hex');
54
+ };
55
+
56
+ Opcode.prototype.toNumber = function () {
57
+ return this.num;
58
+ };
59
+
60
+ Opcode.prototype.toString = function () {
61
+ var str = Opcode.reverseMap[this.num];
62
+ if (typeof str === 'undefined') {
63
+ throw new Error('Opcode does not have a string representation');
64
+ }
65
+ return str;
66
+ };
67
+
68
+ Opcode.prototype.toSafeString = function () {
69
+ var str = Opcode.reverseMap[this.num];
70
+ if (typeof str === 'undefined') {
71
+ return this.toHex();
72
+ }
73
+ return str;
74
+ };
75
+
76
+ Opcode.smallInt = function (n) {
77
+ $.checkArgument(_.isNumber(n), 'Invalid Argument: n should be number');
78
+ $.checkArgument(n >= 0 && n <= 16, 'Invalid Argument: n must be between 0 and 16');
79
+ if (n === 0) {
80
+ return Opcode('OP_0');
81
+ }
82
+ return new Opcode(Opcode.map.OP_1 + n - 1);
83
+ };
84
+
85
+ Opcode.map = {
86
+ // push value
87
+ OP_FALSE: 0,
88
+ OP_0: 0,
89
+ OP_PUSHDATA1: 76,
90
+ OP_PUSHDATA2: 77,
91
+ OP_PUSHDATA4: 78,
92
+ OP_1NEGATE: 79,
93
+ OP_RESERVED: 80,
94
+ OP_TRUE: 81,
95
+ OP_1: 81,
96
+ OP_2: 82,
97
+ OP_3: 83,
98
+ OP_4: 84,
99
+ OP_5: 85,
100
+ OP_6: 86,
101
+ OP_7: 87,
102
+ OP_8: 88,
103
+ OP_9: 89,
104
+ OP_10: 90,
105
+ OP_11: 91,
106
+ OP_12: 92,
107
+ OP_13: 93,
108
+ OP_14: 94,
109
+ OP_15: 95,
110
+ OP_16: 96,
111
+
112
+ // control
113
+ OP_NOP: 97,
114
+ OP_VER: 98,
115
+ OP_IF: 99,
116
+ OP_NOTIF: 100,
117
+ OP_VERIF: 101,
118
+ OP_VERNOTIF: 102,
119
+ OP_ELSE: 103,
120
+ OP_ENDIF: 104,
121
+ OP_VERIFY: 105,
122
+ OP_RETURN: 106,
123
+
124
+ // stack ops
125
+ OP_TOALTSTACK: 107,
126
+ OP_FROMALTSTACK: 108,
127
+ OP_2DROP: 109,
128
+ OP_2DUP: 110,
129
+ OP_3DUP: 111,
130
+ OP_2OVER: 112,
131
+ OP_2ROT: 113,
132
+ OP_2SWAP: 114,
133
+ OP_IFDUP: 115,
134
+ OP_DEPTH: 116,
135
+ OP_DROP: 117,
136
+ OP_DUP: 118,
137
+ OP_NIP: 119,
138
+ OP_OVER: 120,
139
+ OP_PICK: 121,
140
+ OP_ROLL: 122,
141
+ OP_ROT: 123,
142
+ OP_SWAP: 124,
143
+ OP_TUCK: 125,
144
+
145
+ // splice ops
146
+ OP_CAT: 126,
147
+ OP_SPLIT: 127,
148
+ OP_NUM2BIN: 128,
149
+ OP_BIN2NUM: 129,
150
+ OP_SIZE: 130,
151
+
152
+ // bit logic
153
+ OP_INVERT: 131,
154
+ OP_AND: 132,
155
+ OP_OR: 133,
156
+ OP_XOR: 134,
157
+ OP_EQUAL: 135,
158
+ OP_EQUALVERIFY: 136,
159
+ OP_RESERVED1: 137,
160
+ OP_RESERVED2: 138,
161
+
162
+ // numeric
163
+ OP_1ADD: 139,
164
+ OP_1SUB: 140,
165
+ OP_2MUL: 141,
166
+ OP_2DIV: 142,
167
+ OP_NEGATE: 143,
168
+ OP_ABS: 144,
169
+ OP_NOT: 145,
170
+ OP_0NOTEQUAL: 146,
171
+
172
+ OP_ADD: 147,
173
+ OP_SUB: 148,
174
+ OP_MUL: 149,
175
+ OP_DIV: 150,
176
+ OP_MOD: 151,
177
+ OP_LSHIFT: 152,
178
+ OP_RSHIFT: 153,
179
+
180
+ OP_BOOLAND: 154,
181
+ OP_BOOLOR: 155,
182
+ OP_NUMEQUAL: 156,
183
+ OP_NUMEQUALVERIFY: 157,
184
+ OP_NUMNOTEQUAL: 158,
185
+ OP_LESSTHAN: 159,
186
+ OP_GREATERTHAN: 160,
187
+ OP_LESSTHANOREQUAL: 161,
188
+ OP_GREATERTHANOREQUAL: 162,
189
+ OP_MIN: 163,
190
+ OP_MAX: 164,
191
+
192
+ OP_WITHIN: 165,
193
+
194
+ // crypto
195
+ OP_RIPEMD160: 166,
196
+ OP_SHA1: 167,
197
+ OP_SHA256: 168,
198
+ OP_HASH160: 169,
199
+ OP_HASH256: 170,
200
+ OP_CODESEPARATOR: 171,
201
+ OP_CHECKSIG: 172,
202
+ OP_CHECKSIGVERIFY: 173,
203
+ OP_CHECKMULTISIG: 174,
204
+ OP_CHECKMULTISIGVERIFY: 175,
205
+
206
+ OP_CHECKLOCKTIMEVERIFY: 177,
207
+ OP_CHECKSEQUENCEVERIFY: 178,
208
+
209
+ // expansion
210
+ OP_NOP1: 176,
211
+ OP_NOP2: 177,
212
+ OP_NOP3: 178,
213
+ OP_NOP4: 179,
214
+ OP_NOP5: 180,
215
+ OP_NOP6: 181,
216
+ OP_NOP7: 182,
217
+ OP_NOP8: 183,
218
+ OP_NOP9: 184,
219
+ OP_NOP10: 185,
220
+
221
+ // template matching params
222
+ OP_PUBKEYHASH: 253,
223
+ OP_PUBKEY: 254,
224
+ OP_INVALIDOPCODE: 255,
225
+ };
226
+
227
+ Opcode.reverseMap = [];
228
+
229
+ for (var k in Opcode.map) {
230
+ Opcode.reverseMap[Opcode.map[k]] = k;
231
+ }
232
+
233
+ // Easier access to opcodes
234
+ _.extend(Opcode, Opcode.map);
235
+
236
+ /**
237
+ * @returns true if opcode is one of OP_0, OP_1, ..., OP_16
238
+ */
239
+ Opcode.isSmallIntOp = function (opcode) {
240
+ if (opcode instanceof Opcode) {
241
+ opcode = opcode.toNumber();
242
+ }
243
+ return opcode === Opcode.map.OP_0 || (opcode >= Opcode.map.OP_1 && opcode <= Opcode.map.OP_16);
244
+ };
245
+
246
+ /**
247
+ * Will return a string formatted for the console
248
+ *
249
+ * @returns {string} Script opcode
250
+ */
251
+ Opcode.prototype.inspect = function () {
252
+ return '<Opcode: ' + this.toString() + ', hex: ' + this.toHex() + ', decimal: ' + this.num + '>';
253
+ };
254
+
255
+ module.exports = Opcode;