@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,1437 @@
1
+ 'use strict';
2
+
3
+ var should = require('chai').should();
4
+ var expect = require('chai').expect;
5
+ var opcat = require('../..');
6
+
7
+ var Script = opcat.Script;
8
+ var Networks = opcat.Networks;
9
+ var Opcode = opcat.Opcode;
10
+ var PublicKey = opcat.PublicKey;
11
+ var Address = opcat.Address;
12
+
13
+ describe('Script', function () {
14
+ it('should make a new script', function () {
15
+ var script = new Script();
16
+ expect(script).to.be.instanceof(Script);
17
+ expect(script.chunks).to.deep.equal([]);
18
+ });
19
+
20
+ it('should make a new script when from is null', function () {
21
+ var script = new Script(null);
22
+ expect(script).to.be.instanceof(Script);
23
+ expect(script.chunks).to.deep.equal([]);
24
+ });
25
+
26
+ describe('#set', function () {
27
+ var script = new Script();
28
+
29
+ it('should be object', function () {
30
+ expect(function () {
31
+ script.set(null);
32
+ }).to.throw(/^Invalid Argument$/);
33
+ });
34
+
35
+ it('chunks should be array', function () {
36
+ expect(function () {
37
+ script.set({ chunks: 1 });
38
+ }).to.throw(/^Invalid Argument$/);
39
+ });
40
+
41
+ it('set chunks', function () {
42
+ script.set({
43
+ chunks: [
44
+ {
45
+ len: 0,
46
+ opcodenum: 0,
47
+ },
48
+ ],
49
+ });
50
+ expect(script.chunks).to.deep.equal([
51
+ {
52
+ len: 0,
53
+ opcodenum: 0,
54
+ },
55
+ ]);
56
+ });
57
+ });
58
+
59
+ describe('#fromBuffer', function () {
60
+ it('should parse this buffer containing an OP code', function () {
61
+ var buf = Buffer.alloc(1);
62
+ buf[0] = Opcode.OP_0;
63
+ var script = Script.fromBuffer(buf);
64
+ script.chunks.length.should.equal(1);
65
+ script.chunks[0].opcodenum.should.equal(buf[0]);
66
+ });
67
+
68
+ it('should parse this buffer containing another OP code', function () {
69
+ var buf = Buffer.alloc(1);
70
+ buf[0] = Opcode.OP_CHECKMULTISIG;
71
+ var script = Script.fromBuffer(buf);
72
+ script.chunks.length.should.equal(1);
73
+ script.chunks[0].opcodenum.should.equal(buf[0]);
74
+ });
75
+
76
+ it('should parse this buffer containing three bytes of data', function () {
77
+ var buf = Buffer.from([3, 1, 2, 3]);
78
+ var script = Script.fromBuffer(buf);
79
+ script.chunks.length.should.equal(1);
80
+ script.chunks[0].buf.toString('hex').should.equal('010203');
81
+ });
82
+
83
+ it('should parse this buffer containing OP_PUSHDATA1 and three bytes of data', function () {
84
+ var buf = Buffer.from([0, 0, 1, 2, 3]);
85
+ buf[0] = Opcode.OP_PUSHDATA1;
86
+ buf.writeUInt8(3, 1);
87
+ var script = Script.fromBuffer(buf);
88
+ script.chunks.length.should.equal(1);
89
+ script.chunks[0].buf.toString('hex').should.equal('010203');
90
+ });
91
+
92
+ it('should parse this buffer containing OP_PUSHDATA2 and three bytes of data', function () {
93
+ var buf = Buffer.from([0, 0, 0, 1, 2, 3]);
94
+ buf[0] = Opcode.OP_PUSHDATA2;
95
+ buf.writeUInt16LE(3, 1);
96
+ var script = Script.fromBuffer(buf);
97
+ script.chunks.length.should.equal(1);
98
+ script.chunks[0].buf.toString('hex').should.equal('010203');
99
+ });
100
+
101
+ it('should parse this buffer containing OP_PUSHDATA4 and three bytes of data', function () {
102
+ var buf = Buffer.from([0, 0, 0, 0, 0, 1, 2, 3]);
103
+ buf[0] = Opcode.OP_PUSHDATA4;
104
+ buf.writeUInt16LE(3, 1);
105
+ var script = Script.fromBuffer(buf);
106
+ script.chunks.length.should.equal(1);
107
+ script.chunks[0].buf.toString('hex').should.equal('010203');
108
+ });
109
+
110
+ it('should parse this buffer an OP code, data, and another OP code', function () {
111
+ var buf = Buffer.from([0, 0, 0, 0, 0, 0, 1, 2, 3, 0]);
112
+ buf[0] = Opcode.OP_0;
113
+ buf[1] = Opcode.OP_PUSHDATA4;
114
+ buf.writeUInt16LE(3, 2);
115
+ buf[buf.length - 1] = Opcode.OP_0;
116
+ var script = Script.fromBuffer(buf);
117
+ script.chunks.length.should.equal(3);
118
+ script.chunks[0].opcodenum.should.equal(buf[0]);
119
+ script.chunks[1].buf.toString('hex').should.equal('010203');
120
+ script.chunks[2].opcodenum.should.equal(buf[buf.length - 1]);
121
+ });
122
+ });
123
+
124
+ describe('#toBuffer', function () {
125
+ it('should output this buffer containing an OP code', function () {
126
+ var buf = Buffer.alloc(1);
127
+ buf[0] = Opcode.OP_0;
128
+ var script = Script.fromBuffer(buf);
129
+ script.chunks.length.should.equal(1);
130
+ script.chunks[0].opcodenum.should.equal(buf[0]);
131
+ script.toBuffer().toString('hex').should.equal(buf.toString('hex'));
132
+ });
133
+
134
+ it('should output this buffer containing another OP code', function () {
135
+ var buf = Buffer.alloc(1);
136
+ buf[0] = Opcode.OP_CHECKMULTISIG;
137
+ var script = Script.fromBuffer(buf);
138
+ script.chunks.length.should.equal(1);
139
+ script.chunks[0].opcodenum.should.equal(buf[0]);
140
+ script.toBuffer().toString('hex').should.equal(buf.toString('hex'));
141
+ });
142
+
143
+ it('should output this buffer containing three bytes of data', function () {
144
+ var buf = Buffer.from([3, 1, 2, 3]);
145
+ var script = Script.fromBuffer(buf);
146
+ script.chunks.length.should.equal(1);
147
+ script.chunks[0].buf.toString('hex').should.equal('010203');
148
+ script.toBuffer().toString('hex').should.equal(buf.toString('hex'));
149
+ });
150
+
151
+ it('should output this buffer containing OP_PUSHDATA1 and three bytes of data', function () {
152
+ var buf = Buffer.from([0, 0, 1, 2, 3]);
153
+ buf[0] = Opcode.OP_PUSHDATA1;
154
+ buf.writeUInt8(3, 1);
155
+ var script = Script.fromBuffer(buf);
156
+ script.chunks.length.should.equal(1);
157
+ script.chunks[0].buf.toString('hex').should.equal('010203');
158
+ script.toBuffer().toString('hex').should.equal(buf.toString('hex'));
159
+ });
160
+
161
+ it('should output this buffer containing OP_PUSHDATA2 and three bytes of data', function () {
162
+ var buf = Buffer.from([0, 0, 0, 1, 2, 3]);
163
+ buf[0] = Opcode.OP_PUSHDATA2;
164
+ buf.writeUInt16LE(3, 1);
165
+ var script = Script.fromBuffer(buf);
166
+ script.chunks.length.should.equal(1);
167
+ script.chunks[0].buf.toString('hex').should.equal('010203');
168
+ script.toBuffer().toString('hex').should.equal(buf.toString('hex'));
169
+ });
170
+
171
+ it('should output this buffer containing OP_PUSHDATA4 and three bytes of data', function () {
172
+ var buf = Buffer.from([0, 0, 0, 0, 0, 1, 2, 3]);
173
+ buf[0] = Opcode.OP_PUSHDATA4;
174
+ buf.writeUInt16LE(3, 1);
175
+ var script = Script.fromBuffer(buf);
176
+ script.chunks.length.should.equal(1);
177
+ script.chunks[0].buf.toString('hex').should.equal('010203');
178
+ script.toBuffer().toString('hex').should.equal(buf.toString('hex'));
179
+ });
180
+
181
+ it('should output this buffer an OP code, data, and another OP code', function () {
182
+ var buf = Buffer.from([0, 0, 0, 0, 0, 0, 1, 2, 3, 0]);
183
+ buf[0] = Opcode.OP_0;
184
+ buf[1] = Opcode.OP_PUSHDATA4;
185
+ buf.writeUInt16LE(3, 2);
186
+ buf[buf.length - 1] = Opcode.OP_0;
187
+ var script = Script.fromBuffer(buf);
188
+ script.chunks.length.should.equal(3);
189
+ script.chunks[0].opcodenum.should.equal(buf[0]);
190
+ script.chunks[1].buf.toString('hex').should.equal('010203');
191
+ script.chunks[2].opcodenum.should.equal(buf[buf.length - 1]);
192
+ script.toBuffer().toString('hex').should.equal(buf.toString('hex'));
193
+ });
194
+ });
195
+
196
+ describe('#fromASM', function () {
197
+ it('should parse this known script in ASM', function () {
198
+ var asm =
199
+ 'OP_DUP OP_HASH160 f4c03610e60ad15100929cc23da2f3a799af1725 OP_EQUALVERIFY OP_CHECKSIG';
200
+ var script = Script.fromASM(asm);
201
+ script.chunks[0].opcodenum.should.equal(Opcode.OP_DUP);
202
+ script.chunks[1].opcodenum.should.equal(Opcode.OP_HASH160);
203
+ script.chunks[2].opcodenum.should.equal(20);
204
+ script.chunks[2].buf.toString('hex').should.equal('f4c03610e60ad15100929cc23da2f3a799af1725');
205
+ script.chunks[3].opcodenum.should.equal(Opcode.OP_EQUALVERIFY);
206
+ script.chunks[4].opcodenum.should.equal(Opcode.OP_CHECKSIG);
207
+ });
208
+
209
+ it('should parse this known problematic script in ASM', function () {
210
+ var asm = 'OP_RETURN 026d02 0568656c6c6f';
211
+ var script = Script.fromASM(asm);
212
+ script.toASM().should.equal(asm);
213
+ });
214
+
215
+ it('should know this is invalid hex', function () {
216
+ var asm = 'OP_RETURN 026d02 0568656c6c6fzz';
217
+ let errors = 0;
218
+ try {
219
+ errors++;
220
+ var script = Script.fromASM(asm);
221
+ script.toASM().should.equal(asm);
222
+ } catch (err) {
223
+ err.message.should.equal('invalid hex string in script');
224
+ }
225
+ errors.should.equal(1);
226
+ });
227
+
228
+ it('should parse this long PUSHDATA1 script in ASM', function () {
229
+ var buf = Buffer.alloc(220, 0);
230
+ var asm = 'OP_RETURN ' + buf.toString('hex');
231
+ var script = Script.fromASM(asm);
232
+ script.chunks[1].opcodenum.should.equal(Opcode.OP_PUSHDATA1);
233
+ script.toASM().should.equal(asm);
234
+ });
235
+
236
+ it('should parse this long PUSHDATA2 script in ASM', function () {
237
+ var buf = Buffer.alloc(1024, 0);
238
+ var asm = 'OP_RETURN ' + buf.toString('hex');
239
+ var script = Script.fromASM(asm);
240
+ script.chunks[1].opcodenum.should.equal(Opcode.OP_PUSHDATA2);
241
+ script.toASM().should.equal(asm);
242
+ });
243
+
244
+ it('should parse this long PUSHDATA4 script in ASM', function () {
245
+ var buf = Buffer.alloc(Math.pow(2, 17), 0);
246
+ var asm = 'OP_RETURN ' + buf.toString('hex');
247
+ var script = Script.fromASM(asm);
248
+ script.chunks[1].opcodenum.should.equal(Opcode.OP_PUSHDATA4);
249
+ script.toASM().should.equal(asm);
250
+ });
251
+
252
+ it('should return this script correctly', function () {
253
+ var asm1 = 'OP_FALSE';
254
+ var asm2 = 'OP_0';
255
+ var asm3 = '0';
256
+ Script.fromASM(asm1).toASM().should.equal(asm3);
257
+ Script.fromASM(asm2).toASM().should.equal(asm3);
258
+ Script.fromASM(asm3).toASM().should.equal(asm3);
259
+ });
260
+
261
+ it('should return this script correctly', function () {
262
+ var asm1 = 'OP_1NEGATE';
263
+ var asm2 = '-1';
264
+ Script.fromASM(asm1).toASM().should.equal(asm2);
265
+ Script.fromASM(asm2).toASM().should.equal(asm2);
266
+ });
267
+ });
268
+
269
+ describe('#fromString', function () {
270
+ it('should parse these known scripts', function () {
271
+ Script.fromString('OP_0 OP_PUSHDATA4 3 0x010203 OP_0')
272
+ .toString()
273
+ .should.equal('OP_0 OP_PUSHDATA4 3 0x010203 OP_0');
274
+ Script.fromString('OP_0 OP_PUSHDATA2 3 0x010203 OP_0')
275
+ .toString()
276
+ .should.equal('OP_0 OP_PUSHDATA2 3 0x010203 OP_0');
277
+ Script.fromString('OP_0 OP_PUSHDATA1 3 0x010203 OP_0')
278
+ .toString()
279
+ .should.equal('OP_0 OP_PUSHDATA1 3 0x010203 OP_0');
280
+ Script.fromString('OP_0 3 0x010203 OP_0').toString().should.equal('OP_0 3 0x010203 OP_0');
281
+ });
282
+ });
283
+
284
+ describe('#toString', function () {
285
+ it('should work with an empty script', function () {
286
+ var script = new Script();
287
+ script.toString().should.equal('');
288
+ });
289
+
290
+ it('should output this buffer an OP code, data, and another OP code', function () {
291
+ var buf = Buffer.from([0, 0, 0, 0, 0, 0, 1, 2, 3, 0]);
292
+ buf[0] = Opcode.OP_0;
293
+ buf[1] = Opcode.OP_PUSHDATA4;
294
+ buf.writeUInt16LE(3, 2);
295
+ buf[buf.length - 1] = Opcode.OP_0;
296
+ var script = Script.fromBuffer(buf);
297
+ script.chunks.length.should.equal(3);
298
+ script.chunks[0].opcodenum.should.equal(buf[0]);
299
+ script.chunks[1].buf.toString('hex').should.equal('010203');
300
+ script.chunks[2].opcodenum.should.equal(buf[buf.length - 1]);
301
+ script.toString().toString('hex').should.equal('OP_0 OP_PUSHDATA4 3 0x010203 OP_0');
302
+ });
303
+
304
+ it('should output this known script as ASM', function () {
305
+ var script = Script.fromHex('76a914f4c03610e60ad15100929cc23da2f3a799af172588ac');
306
+ script
307
+ .toASM()
308
+ .should.equal(
309
+ 'OP_DUP OP_HASH160 f4c03610e60ad15100929cc23da2f3a799af1725 OP_EQUALVERIFY OP_CHECKSIG',
310
+ );
311
+ });
312
+
313
+ it('should output this known script with pushdata1 opcode as ASM', function () {
314
+ // network: livenet
315
+ // txid: dd6fabd2d879be7b8394ad170ff908e9a36b5d5d0b394508df0cca36d2931589
316
+ var script = Script.fromHex(
317
+ '00483045022100beb1d83771c04faaeb40bded4f031ed0e0730aaab77cf70102ecd05734a1762002206f168fb00f3b9d7c04b8c78e1fc11e81b9caa49885a904bf22780a7e14a8373101483045022100a319839e37828bf164ff45de34a3fe22d542ebc8297c5d87dbc56fc3068ff9d5022077081a877b6e7f104d8a2fe0985bf2eb7de2e08edbac9499fc3710a353f65461014c69522103a70ae7bde64333461fb88aaafe12ad6c67ca17c8213642469ae191e0aabc7251210344a62338c8ddf138771516d38187146242db50853aa588bcb10a5e49c86421a52102b52a1aed304c4d6cedcf82911f90ca6e1ffed0a5b8f7f19c68213d6fcbde677e53ae',
318
+ );
319
+ script
320
+ .toASM()
321
+ .should.equal(
322
+ '0 3045022100beb1d83771c04faaeb40bded4f031ed0e0730aaab77cf70102ecd05734a1762002206f168fb00f3b9d7c04b8c78e1fc11e81b9caa49885a904bf22780a7e14a8373101 3045022100a319839e37828bf164ff45de34a3fe22d542ebc8297c5d87dbc56fc3068ff9d5022077081a877b6e7f104d8a2fe0985bf2eb7de2e08edbac9499fc3710a353f6546101 522103a70ae7bde64333461fb88aaafe12ad6c67ca17c8213642469ae191e0aabc7251210344a62338c8ddf138771516d38187146242db50853aa588bcb10a5e49c86421a52102b52a1aed304c4d6cedcf82911f90ca6e1ffed0a5b8f7f19c68213d6fcbde677e53ae',
323
+ );
324
+ });
325
+
326
+ it('should OP_1NEGATE opcode as -1 with ASM', function () {
327
+ var script = Script.fromString('OP_1NEGATE');
328
+ script.toASM().should.equal('-1');
329
+ });
330
+ });
331
+
332
+ describe('toHex', function () {
333
+ it('should return an hexa string "03010203" as expected from [3, 1, 2, 3]', function () {
334
+ var buf = Buffer.from([3, 1, 2, 3]);
335
+ var script = Script.fromBuffer(buf);
336
+ script.toHex().should.equal('03010203');
337
+ });
338
+ });
339
+
340
+ describe('#isDataOut', function () {
341
+ it('should know this is a (blank) OP_RETURN script', function () {
342
+ Script('OP_RETURN').isDataOut().should.equal(true);
343
+ });
344
+
345
+ it('validates that this two part OP_RETURN is standard', function () {
346
+ Script.fromASM('OP_RETURN 026d02 0568656c6c6f').isDataOut().should.equal(true);
347
+ });
348
+
349
+ it('validates that this 40-byte OP_RETURN is standard', function () {
350
+ var buf = Buffer.alloc(40);
351
+ buf.fill(0);
352
+ Script('OP_RETURN 40 0x' + buf.toString('hex'))
353
+ .isDataOut()
354
+ .should.equal(true);
355
+ });
356
+
357
+ it('validates that this 80-byte OP_RETURN is standard', function () {
358
+ var buf = Buffer.alloc(80);
359
+ buf.fill(0);
360
+ Script('OP_RETURN OP_PUSHDATA1 80 0x' + buf.toString('hex'))
361
+ .isDataOut()
362
+ .should.equal(true);
363
+ });
364
+
365
+ it('validates that this 220-byte OP_RETURN is standard', function () {
366
+ var buf = Buffer.alloc(220);
367
+ buf.fill(0);
368
+ Script('OP_RETURN OP_PUSHDATA1 220 0x' + buf.toString('hex'))
369
+ .isDataOut()
370
+ .should.equal(true);
371
+ });
372
+
373
+ it('validates that this 40-byte long OP_CHECKMULTISIG is not standard op_return', function () {
374
+ var buf = Buffer.alloc(40);
375
+ buf.fill(0);
376
+ Script('OP_CHECKMULTISIG 40 0x' + buf.toString('hex'))
377
+ .isDataOut()
378
+ .should.equal(false);
379
+ });
380
+
381
+ it('validates that this 221-byte OP_RETURN is a valid standard OP_RETURN', function () {
382
+ var buf = Buffer.alloc(221);
383
+ buf.fill(0);
384
+ Script('OP_RETURN OP_PUSHDATA1 221 0x' + buf.toString('hex'))
385
+ .isDataOut()
386
+ .should.equal(true);
387
+ });
388
+
389
+ it('validates that this 99994-byte OP_RETURN is a valid standard OP_RETURN', function () {
390
+ var buf = Buffer.alloc(100000 - 6);
391
+ buf.fill(0);
392
+ Script(`OP_RETURN OP_PUSHDATA4 ${buf.length} 0x` + buf.toString('hex'))
393
+ .isDataOut()
394
+ .should.equal(true);
395
+ });
396
+
397
+ it('validates that this 99995-byte OP_RETURN is a valid standard OP_RETURN', function () {
398
+ var buf = Buffer.alloc(100000 - 5);
399
+ buf.fill(0);
400
+ Script(`OP_RETURN OP_PUSHDATA4 ${buf.length} 0x` + buf.toString('hex'))
401
+ .isDataOut()
402
+ .should.equal(true);
403
+ });
404
+ });
405
+
406
+ describe('#isSafeDataOut', function () {
407
+ it('should know this is a (blank) OP_RETURN script', function () {
408
+ Script('OP_FALSE OP_RETURN').isSafeDataOut().should.equal(true);
409
+ });
410
+
411
+ it('validates that this two part OP_RETURN is standard', function () {
412
+ Script.fromASM('OP_FALSE OP_RETURN 026d02 0568656c6c6f').isSafeDataOut().should.equal(true);
413
+ });
414
+
415
+ it('validates that this 40-byte OP_RETURN is standard', function () {
416
+ var buf = Buffer.alloc(40);
417
+ buf.fill(0);
418
+ Script('OP_FALSE OP_RETURN 40 0x' + buf.toString('hex'))
419
+ .isSafeDataOut()
420
+ .should.equal(true);
421
+ });
422
+
423
+ it('validates that this 80-byte OP_RETURN is standard', function () {
424
+ var buf = Buffer.alloc(80);
425
+ buf.fill(0);
426
+ Script('OP_FALSE OP_RETURN OP_PUSHDATA1 80 0x' + buf.toString('hex'))
427
+ .isSafeDataOut()
428
+ .should.equal(true);
429
+ });
430
+
431
+ it('validates that this 220-byte OP_RETURN is standard', function () {
432
+ var buf = Buffer.alloc(220);
433
+ buf.fill(0);
434
+ Script('OP_FALSE OP_RETURN OP_PUSHDATA1 220 0x' + buf.toString('hex'))
435
+ .isSafeDataOut()
436
+ .should.equal(true);
437
+ });
438
+
439
+ it('validates that this 40-byte long OP_CHECKMULTISIG is not standard op_return', function () {
440
+ var buf = Buffer.alloc(40);
441
+ buf.fill(0);
442
+ Script('OP_CHECKMULTISIG 40 0x' + buf.toString('hex'))
443
+ .isSafeDataOut()
444
+ .should.equal(false);
445
+ });
446
+
447
+ it('validates that this 221-byte OP_RETURN is a valid standard OP_RETURN', function () {
448
+ var buf = Buffer.alloc(221);
449
+ buf.fill(0);
450
+ Script('OP_FALSE OP_RETURN OP_PUSHDATA1 221 0x' + buf.toString('hex'))
451
+ .isSafeDataOut()
452
+ .should.equal(true);
453
+ });
454
+
455
+ it('validates that this 99994-byte OP_RETURN is a valid standard OP_RETURN', function () {
456
+ var buf = Buffer.alloc(100000 - 6);
457
+ buf.fill(0);
458
+ Script(`OP_FALSE OP_RETURN OP_PUSHDATA4 ${buf.length} 0x` + buf.toString('hex'))
459
+ .isSafeDataOut()
460
+ .should.equal(true);
461
+ });
462
+
463
+ it('validates that this 99995-byte OP_RETURN is a valid standard OP_RETURN', function () {
464
+ var buf = Buffer.alloc(100000 - 5);
465
+ buf.fill(0);
466
+ Script(`OP_FALSE OP_RETURN OP_PUSHDATA4 ${buf.length} 0x` + buf.toString('hex'))
467
+ .isSafeDataOut()
468
+ .should.equal(true);
469
+ });
470
+ });
471
+
472
+ describe('#isPublicKeyIn', function () {
473
+ it('correctly identify scriptSig as a public key in', function () {
474
+ // from txid: 5c85ed63469aa9971b5d01063dbb8bcdafd412b2f51a3d24abf2e310c028bbf8
475
+ // and input index: 5
476
+ var scriptBuffer = Buffer.from(
477
+ '483045022050eb59c79435c051f45003d9f82865c8e4df5699d7722e77113ef8cadbd92109022100d4ab233e070070eb8e0e62e3d2d2eb9474a5bf135c9eda32755acb0875a6c20601',
478
+ 'hex',
479
+ );
480
+ var script = opcat.Script.fromBuffer(scriptBuffer);
481
+ script.isPublicKeyIn().should.equal(true);
482
+ });
483
+ });
484
+
485
+ describe('#isPublicKeyHashIn', function () {
486
+ it('should identify this known pubkeyhashin (uncompressed pubkey version)', function () {
487
+ Script(
488
+ '73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 65 0x04e365859b3c78a8b7c202412b949ebca58e147dba297be29eee53cd3e1d300a6419bc780cc9aec0dc94ed194e91c8f6433f1b781ee00eac0ead2aae1e8e0712c6',
489
+ )
490
+ .isPublicKeyHashIn()
491
+ .should.equal(true);
492
+ });
493
+
494
+ it('should identify this known pubkeyhashin (hybrid pubkey version w/06)', function () {
495
+ Script(
496
+ '73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 65 0x06e365859b3c78a8b7c202412b949ebca58e147dba297be29eee53cd3e1d300a6419bc780cc9aec0dc94ed194e91c8f6433f1b781ee00eac0ead2aae1e8e0712c6',
497
+ )
498
+ .isPublicKeyHashIn()
499
+ .should.equal(true);
500
+ });
501
+
502
+ it('should identify this known pubkeyhashin (hybrid pubkey version w/07)', function () {
503
+ Script(
504
+ '73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 65 0x07e365859b3c78a8b7c202412b949ebca58e147dba297be29eee53cd3e1d300a6419bc780cc9aec0dc94ed194e91c8f6433f1b781ee00eac0ead2aae1e8e0712c6',
505
+ )
506
+ .isPublicKeyHashIn()
507
+ .should.equal(true);
508
+ });
509
+
510
+ it('should identify this known pubkeyhashin (compressed pubkey w/ 0x02)', function () {
511
+ Script(
512
+ '73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 33 0x02aec6b86621e7fef63747fbfd6a6e7d54c8e1052044ef2dd2c5e46656ef1194d4',
513
+ )
514
+ .isPublicKeyHashIn()
515
+ .should.equal(true);
516
+ });
517
+
518
+ it('should identify this known pubkeyhashin (compressed pubkey w/ 0x03)', function () {
519
+ Script(
520
+ '73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 33 0x03e724d93c4fda5f1236c525de7ffac6c5f1f72b0f5cdd1fc4b4f5642b6d055fcc',
521
+ )
522
+ .isPublicKeyHashIn()
523
+ .should.equal(true);
524
+ });
525
+
526
+ it('should identify this known non-pubkeyhashin (bad ops length)', function () {
527
+ Script(
528
+ '73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 65 0x04e365859b3c78a8b7c202412b949ebca58e147dba297be29eee53cd3e1d300a6419bc780cc9aec0dc94ed194e91c8f6433f1b781ee00eac0ead2aae1e8e0712c6 OP_CHECKSIG',
529
+ )
530
+ .isPublicKeyHashIn()
531
+ .should.equal(false);
532
+ });
533
+
534
+ it('should identify this known pubkey', function () {
535
+ Script(
536
+ '70 0x3043021f336721e4343f67c835cbfd465477db09073dc38a936f9c445d573c1c8a7fdf022064b0e3cb6892a9ecf870030e3066bc259e1f24841c9471d97f9be08b73f6530701 33 0x0370b2e1dcaa8f51cb0ead1221dd8cb31721502b3b5b7d4b374d263dfec63a4369',
537
+ )
538
+ .isPublicKeyHashIn()
539
+ .should.equal(true);
540
+ });
541
+
542
+ it('should identify this known non-pubkeyhashin (bad version)', function () {
543
+ Script(
544
+ '70 0x3043021f336721e4343f67c835cbfd465477db09073dc38a936f9c445d573c1c8a7fdf022064b0e3cb6892a9ecf870030e3066bc259e1f24841c9471d97f9be08b73f6530701 33 0x1270b2e1dcaa8f51cb0ead1221dd8cb31721502b3b5b7d4b374d263dfec63a4369',
545
+ )
546
+ .isPublicKeyHashIn()
547
+ .should.equal(false);
548
+ });
549
+
550
+ it('should identify this known non-pubkeyhashin (bad signature version)', function () {
551
+ Script(
552
+ '70 0x4043021f336721e4343f67c835cbfd465477db09073dc38a936f9c445d573c1c8a7fdf022064b0e3cb6892a9ecf870030e3066bc259e1f24841c9471d97f9be08b73f6530701 33 0x0370b2e1dcaa8f51cb0ead1221dd8cb31721502b3b5b7d4b374d263dfec63a4369',
553
+ )
554
+ .isPublicKeyHashIn()
555
+ .should.equal(false);
556
+ });
557
+
558
+ it('should identify this known non-pubkeyhashin (no public key)', function () {
559
+ Script(
560
+ '70 0x3043021f336721e4343f67c835cbfd465477db09073dc38a936f9c445d573c1c8a7fdf022064b0e3cb6892a9ecf870030e3066bc259e1f24841c9471d97f9be08b73f6530701 OP_CHECKSIG',
561
+ )
562
+ .isPublicKeyHashIn()
563
+ .should.equal(false);
564
+ });
565
+
566
+ it('should identify this known non-pubkeyhashin (no signature)', function () {
567
+ Script('OP_DROP OP_CHECKSIG').isPublicKeyHashIn().should.equal(false);
568
+ });
569
+ });
570
+
571
+ describe('#isPublicKeyHashOut', function () {
572
+ it('should identify this known pubkeyhashout as pubkeyhashout', function () {
573
+ Script(
574
+ 'OP_DUP OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG',
575
+ )
576
+ .isPublicKeyHashOut()
577
+ .should.equal(true);
578
+ });
579
+
580
+ it('should identify this known non-pubkeyhashout as not pubkeyhashout 1', function () {
581
+ Script('OP_DUP OP_HASH160 20 0x0000000000000000000000000000000000000000')
582
+ .isPublicKeyHashOut()
583
+ .should.equal(false);
584
+ });
585
+
586
+ it('should identify this known non-pubkeyhashout as not pubkeyhashout 2', function () {
587
+ Script('OP_DUP OP_HASH160 2 0x0000 OP_EQUALVERIFY OP_CHECKSIG')
588
+ .isPublicKeyHashOut()
589
+ .should.equal(false);
590
+ });
591
+ });
592
+
593
+ describe('#isMultisigOut', function () {
594
+ it('should identify known multisig out 1', function () {
595
+ Script(
596
+ 'OP_2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG',
597
+ )
598
+ .isMultisigOut()
599
+ .should.equal(true);
600
+ });
601
+ it('should identify known multisig out 2', function () {
602
+ Script(
603
+ 'OP_1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG',
604
+ )
605
+ .isMultisigOut()
606
+ .should.equal(true);
607
+ });
608
+ it('should identify known multisig out 3', function () {
609
+ Script(
610
+ 'OP_2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 OP_3 OP_CHECKMULTISIG',
611
+ )
612
+ .isMultisigOut()
613
+ .should.equal(true);
614
+ });
615
+
616
+ it('should identify non-multisig out 1', function () {
617
+ Script(
618
+ 'OP_2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG OP_EQUAL',
619
+ )
620
+ .isMultisigOut()
621
+ .should.equal(false);
622
+ });
623
+ it('should identify non-multisig out 2', function () {
624
+ Script('OP_2').isMultisigOut().should.equal(false);
625
+ });
626
+ });
627
+
628
+ describe('#isMultisigIn', function () {
629
+ it('should identify multisig in 1', function () {
630
+ Script(
631
+ 'OP_0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01',
632
+ )
633
+ .isMultisigIn()
634
+ .should.equal(true);
635
+ });
636
+ it('should identify multisig in 2', function () {
637
+ Script(
638
+ 'OP_0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01 0x48 0x30450220357011fd3b3ad2b8f2f2d01e05dc6108b51d2a245b4ef40c112d6004596f0475022100a8208c93a39e0c366b983f9a80bfaf89237fcd64ca543568badd2d18ee2e1d7501',
639
+ )
640
+ .isMultisigIn()
641
+ .should.equal(true);
642
+ });
643
+ it('should identify non-multisig in 1', function () {
644
+ Script(
645
+ '0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01',
646
+ )
647
+ .isMultisigIn()
648
+ .should.equal(false);
649
+ });
650
+ it('should identify non-multisig in 2', function () {
651
+ Script(
652
+ 'OP_0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01 OP_0',
653
+ )
654
+ .isMultisigIn()
655
+ .should.equal(false);
656
+ });
657
+ });
658
+
659
+ describe('#isPushOnly', function () {
660
+ it("should know these scripts are or aren't push only", function () {
661
+ Script('OP_NOP 1 0x01').isPushOnly().should.equal(false);
662
+ Script('OP_0').isPushOnly().should.equal(true);
663
+ Script('OP_0 OP_RETURN').isPushOnly().should.equal(false);
664
+ Script('OP_PUSHDATA1 5 0x1010101010').isPushOnly().should.equal(true);
665
+ Script('OP_PUSHDATA2 5 0x1010101010').isPushOnly().should.equal(true);
666
+ Script('OP_PUSHDATA4 5 0x1010101010').isPushOnly().should.equal(true);
667
+ // like bitcoind, we regard OP_RESERVED as being "push only"
668
+ Script('OP_RESERVED').isPushOnly().should.equal(true);
669
+ });
670
+ });
671
+
672
+ describe('#classifyInput', function () {
673
+ it("shouldn't classify public key hash out", function () {
674
+ Script(
675
+ 'OP_DUP OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG',
676
+ )
677
+ .classifyInput()
678
+ .should.equal(Script.types.UNKNOWN);
679
+ });
680
+ it('should classify public key hash in', function () {
681
+ Script(
682
+ '0x47 0x3044022077a8d81e656c4a1c1721e68ce35fa0b27f13c342998e75854858c12396a15ffa02206378a8c6959283c008c87a14a9c0ada5cf3934ac5ee29f1fef9cac6969783e9801 0x21 0x03993c230da7dabb956292851ae755f971c50532efc095a16bee07f83ab9d262df',
683
+ )
684
+ .classifyInput()
685
+ .should.equal(Script.types.PUBKEYHASH_IN);
686
+ });
687
+ it("shouldn't classify script hash out", function () {
688
+ Script('OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUAL')
689
+ .classifyInput()
690
+ .should.equal(Script.types.UNKNOWN);
691
+ });
692
+ it("shouldn't classify MULTISIG out", function () {
693
+ Script(
694
+ 'OP_2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG',
695
+ )
696
+ .classifyInput()
697
+ .should.equal(Script.types.UNKNOWN);
698
+ });
699
+ it('should classify MULTISIG in', function () {
700
+ Script(
701
+ 'OP_0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01',
702
+ )
703
+ .classifyInput()
704
+ .should.equal(Script.types.MULTISIG_IN);
705
+ });
706
+ it("shouldn't classify OP_RETURN data out", function () {
707
+ Script('OP_RETURN 1 0x01').classifyInput().should.equal(Script.types.UNKNOWN);
708
+ });
709
+ it("shouldn't classify public key out", function () {
710
+ Script(
711
+ '0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 OP_CHECKSIG',
712
+ )
713
+ .classifyInput()
714
+ .should.equal(Script.types.UNKNOWN);
715
+ });
716
+ it('should classify public key in', function () {
717
+ Script(
718
+ '0x47 0x3044022007415aa37ce7eaa6146001ac8bdefca0ddcba0e37c5dc08c4ac99392124ebac802207d382307fd53f65778b07b9c63b6e196edeadf0be719130c5db21ff1e700d67501',
719
+ )
720
+ .classifyInput()
721
+ .should.equal(Script.types.PUBKEY_IN);
722
+ });
723
+ it('should classify unknown', function () {
724
+ Script('OP_TRUE OP_FALSE').classifyInput().should.equal(Script.types.UNKNOWN);
725
+ });
726
+ });
727
+
728
+ describe('#classifyOutput', function () {
729
+ it('should classify public key hash out', function () {
730
+ Script(
731
+ 'OP_DUP OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG',
732
+ )
733
+ .classifyOutput()
734
+ .should.equal(Script.types.PUBKEYHASH_OUT);
735
+ });
736
+ it("shouldn't classify public key hash in", function () {
737
+ Script(
738
+ '0x47 0x3044022077a8d81e656c4a1c1721e68ce35fa0b27f13c342998e75854858c12396a15ffa02206378a8c6959283c008c87a14a9c0ada5cf3934ac5ee29f1fef9cac6969783e9801 0x21 0x03993c230da7dabb956292851ae755f971c50532efc095a16bee07f83ab9d262df',
739
+ )
740
+ .classifyOutput()
741
+ .should.equal(Script.types.UNKNOWN);
742
+ });
743
+ it("shouldn't classify script hash in", function () {
744
+ Script(
745
+ 'OP_0 73 0x30460221008ca148504190c10eea7f5f9c283c719a37be58c3ad617928011a1bb9570901d2022100ced371a23e86af6f55ff4ce705c57d2721a09c4d192ca39d82c4239825f75a9801 72 0x30450220357011fd3b3ad2b8f2f2d01e05dc6108b51d2a245b4ef40c112d6004596f0475022100a8208c93a39e0c366b983f9a80bfaf89237fcd64ca543568badd2d18ee2e1d7501 OP_PUSHDATA1 105 0x5221024c02dff2f0b8263a562a69ec875b2c95ffad860f428acf2f9e8c6492bd067d362103546324a1351a6b601c623b463e33b6103ca444707d5b278ece1692f1aa7724a42103b1ad3b328429450069cc3f9fa80d537ee66ba1120e93f3f185a5bf686fb51e0a53ae',
746
+ )
747
+ .classifyOutput()
748
+ .should.equal(Script.types.UNKNOWN);
749
+ });
750
+ it('should classify MULTISIG out', function () {
751
+ Script(
752
+ 'OP_2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG',
753
+ )
754
+ .classifyOutput()
755
+ .should.equal(Script.types.MULTISIG_OUT);
756
+ });
757
+ it("shouldn't classify MULTISIG in", function () {
758
+ Script(
759
+ 'OP_0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01',
760
+ )
761
+ .classifyOutput()
762
+ .should.equal(Script.types.UNKNOWN);
763
+ });
764
+ it('should classify OP_RETURN data out', function () {
765
+ Script('OP_RETURN 1 0x01').classifyOutput().should.equal(Script.types.DATA_OUT);
766
+ });
767
+ it('should classify public key out', function () {
768
+ Script(
769
+ '0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 OP_CHECKSIG',
770
+ )
771
+ .classifyOutput()
772
+ .should.equal(Script.types.PUBKEY_OUT);
773
+ });
774
+ it("shouldn't classify public key in", function () {
775
+ Script(
776
+ '0x47 0x3044022007415aa37ce7eaa6146001ac8bdefca0ddcba0e37c5dc08c4ac99392124ebac802207d382307fd53f65778b07b9c63b6e196edeadf0be719130c5db21ff1e700d67501',
777
+ )
778
+ .classifyOutput()
779
+ .should.equal(Script.types.UNKNOWN);
780
+ });
781
+ it('should classify unknown', function () {
782
+ Script('OP_TRUE OP_FALSE').classifyOutput().should.equal(Script.types.UNKNOWN);
783
+ });
784
+ it('should classify opreturn eventhough it also looks like a scriptHashIn', function () {
785
+ Script('6a1c3630fd3792f7e847ae5e27985dfb127542ef37ac2a5147c3b9cec7ba')
786
+ .classifyOutput()
787
+ .should.equal(Script.types.DATA_OUT);
788
+ });
789
+ });
790
+
791
+ describe('#classify', function () {
792
+ it('should classify public key hash out', function () {
793
+ Script(
794
+ 'OP_DUP OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG',
795
+ )
796
+ .classify()
797
+ .should.equal(Script.types.PUBKEYHASH_OUT);
798
+ });
799
+ it('should classify public key hash in', function () {
800
+ Script(
801
+ '0x47 0x3044022077a8d81e656c4a1c1721e68ce35fa0b27f13c342998e75854858c12396a15ffa02206378a8c6959283c008c87a14a9c0ada5cf3934ac5ee29f1fef9cac6969783e9801 0x21 0x03993c230da7dabb956292851ae755f971c50532efc095a16bee07f83ab9d262df',
802
+ )
803
+ .classify()
804
+ .should.equal(Script.types.PUBKEYHASH_IN);
805
+ });
806
+ it('should classify MULTISIG out', function () {
807
+ Script(
808
+ 'OP_2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG',
809
+ )
810
+ .classify()
811
+ .should.equal(Script.types.MULTISIG_OUT);
812
+ });
813
+ it('should classify MULTISIG in', function () {
814
+ Script(
815
+ 'OP_0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01',
816
+ )
817
+ .classify()
818
+ .should.equal(Script.types.MULTISIG_IN);
819
+ });
820
+ it('should classify OP_RETURN data out', function () {
821
+ Script('OP_RETURN 1 0x01').classify().should.equal(Script.types.DATA_OUT);
822
+ });
823
+ it('should classify public key out', function () {
824
+ Script(
825
+ '0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 OP_CHECKSIG',
826
+ )
827
+ .classify()
828
+ .should.equal(Script.types.PUBKEY_OUT);
829
+ });
830
+ it('should classify public key in', function () {
831
+ Script(
832
+ '0x47 0x3044022007415aa37ce7eaa6146001ac8bdefca0ddcba0e37c5dc08c4ac99392124ebac802207d382307fd53f65778b07b9c63b6e196edeadf0be719130c5db21ff1e700d67501',
833
+ )
834
+ .classify()
835
+ .should.equal(Script.types.PUBKEY_IN);
836
+ });
837
+ it('should classify unknown', function () {
838
+ Script('OP_TRUE OP_FALSE').classify().should.equal(Script.types.UNKNOWN);
839
+ });
840
+ it('should classify opreturn eventhough it also looks like a scriptHashIn', function () {
841
+ Script('6a1c3630fd3792f7e847ae5e27985dfb127542ef37ac2a5147c3b9cec7ba')
842
+ .classify()
843
+ .should.equal(Script.types.DATA_OUT);
844
+ });
845
+ it('should classify scriptHashIn eventhough it is opreturn when script is marked is input', function () {
846
+ Script('6a1c3630fd3792f7e847ae5e27985dfb127542ef37ac2a5147c3b9cec7ba')
847
+ .classify()
848
+ .should.equal(Script.types.DATA_OUT);
849
+ });
850
+ it('should classify unknown eventhough it is public key hash when marked as input', function () {
851
+ Script(
852
+ 'OP_DUP OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG',
853
+ )
854
+ .classify()
855
+ .should.equal(Script.types.PUBKEYHASH_OUT);
856
+ var s = Script(
857
+ 'OP_DUP OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG',
858
+ );
859
+ s._isInput = true; // this is normally set by when Script is initiated as part if Input or Output objects
860
+ s.classify().should.equal(Script.types.UNKNOWN);
861
+ });
862
+ it('should classify unknown eventhough it is public key hash in when marked as output', function () {
863
+ var s = Script(
864
+ '0x47 0x3044022077a8d81e656c4a1c1721e68ce35fa0b27f13c342998e75854858c12396a15ffa02206378a8c6959283c008c87a14a9c0ada5cf3934ac5ee29f1fef9cac6969783e9801 33 0x03993c230da7dabb956292851ae755f971c50532efc095a16bee07f83ab9d262df',
865
+ );
866
+ s.classify().should.equal(Script.types.PUBKEYHASH_IN);
867
+ s._isOutput = true; // this is normally set by when Script is initiated as part if Input or Output objects
868
+ s.classify().should.equal(Script.types.UNKNOWN);
869
+ });
870
+ });
871
+
872
+ describe('#add and #prepend', function () {
873
+ it('should add these ops', function () {
874
+ Script().add(1).add(10).add(186).toString().should.equal('1 0x0a 0xba');
875
+ Script().add(Buffer.from('03e8', 'hex')).toString().should.equal('2 0x03e8');
876
+ Script().add('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG');
877
+ Script().add('OP_1').add('OP_2').toString().should.equal('OP_1 OP_2');
878
+ Script().add(Opcode.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG');
879
+ Script().add(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG');
880
+ });
881
+
882
+ it('should prepend these ops', function () {
883
+ Script().prepend('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG');
884
+ Script().prepend('OP_1').prepend('OP_2').toString().should.equal('OP_2 OP_1');
885
+ });
886
+
887
+ it('should add and prepend correctly', function () {
888
+ Script()
889
+ .add('OP_1')
890
+ .prepend('OP_2')
891
+ .add('OP_3')
892
+ .prepend('OP_4')
893
+ .toString()
894
+ .should.equal('OP_4 OP_2 OP_1 OP_3');
895
+ });
896
+
897
+ it('should add these push data', function () {
898
+ var buf = Buffer.alloc(1);
899
+ buf.fill(0);
900
+ Script().add(buf).toString().should.equal('1 0x00');
901
+ buf = Buffer.alloc(255);
902
+ buf.fill(0);
903
+ Script()
904
+ .add(buf)
905
+ .toString()
906
+ .should.equal('OP_PUSHDATA1 255 0x' + buf.toString('hex'));
907
+ buf = Buffer.alloc(256);
908
+ buf.fill(0);
909
+ Script()
910
+ .add(buf)
911
+ .toString()
912
+ .should.equal('OP_PUSHDATA2 256 0x' + buf.toString('hex'));
913
+ buf = Buffer.alloc(Math.pow(2, 16));
914
+ buf.fill(0);
915
+ Script()
916
+ .add(buf)
917
+ .toString()
918
+ .should.equal('OP_PUSHDATA4 ' + Math.pow(2, 16) + ' 0x' + buf.toString('hex'));
919
+ });
920
+
921
+ it('should add both pushdata and non-pushdata chunks', function () {
922
+ Script().add('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG');
923
+ Script().add(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG');
924
+ var buf = Buffer.alloc(1);
925
+ buf.fill(0);
926
+ Script().add(buf).toString().should.equal('1 0x00');
927
+ });
928
+
929
+ it('should work for no data OP_RETURN', function () {
930
+ Script().add(Opcode.OP_RETURN).add(Buffer.from('')).toString().should.equal('OP_RETURN OP_0');
931
+ });
932
+ it('works with objects', function () {
933
+ Script()
934
+ .add({
935
+ opcodenum: 106,
936
+ })
937
+ .toString()
938
+ .should.equal('OP_RETURN');
939
+ });
940
+ it('works with another script', function () {
941
+ var someScript = Script(
942
+ 'OP_2 33 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 ' +
943
+ '33 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG',
944
+ );
945
+ var s = new Script().add(someScript);
946
+ s.toString().should.equal(someScript.toString());
947
+ });
948
+ it('fails with wrong type', function () {
949
+ var fails = function () {
950
+ return new Script().add(true);
951
+ };
952
+ fails.should.throw('Invalid script chunk');
953
+ });
954
+ });
955
+
956
+ describe('#isStandard', function () {
957
+ it('should classify correctly standard script', function () {
958
+ Script('OP_RETURN 1 0x00').isStandard().should.equal(true);
959
+ });
960
+ it('should classify correctly non standard script', function () {
961
+ Script('OP_TRUE OP_FALSE').isStandard().should.equal(false);
962
+ });
963
+ });
964
+
965
+ describe('#buildMultisigOut', function () {
966
+ var pubKeyHexes = [
967
+ '022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da',
968
+ '03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9',
969
+ '021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18',
970
+ '02bf97f572a02a8900246d72c2e8fa3d3798a6e59c4e17de2d131d9c60d0d9b574',
971
+ '036a98a36aa7665874b1ba9130bc6d318e52fd3bdb5969532d7fc09bf2476ff842',
972
+ '033aafcbead78c08b0e0aacc1b0cdb40702a7c709b660bebd286e973242127e15b',
973
+ ];
974
+ var sortkeys = pubKeyHexes.slice(0, 3).map(PublicKey);
975
+ it('should create sorted script by default', function () {
976
+ var s = Script.buildMultisigOut(sortkeys, 2);
977
+ s.toString().should.equal(
978
+ 'OP_2 33 0x021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 33 0x022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da 33 0x03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 OP_3 OP_CHECKMULTISIG',
979
+ );
980
+ s.isMultisigOut().should.equal(true);
981
+ });
982
+ it('should fail when number of required signatures is greater than number of pubkeys', function () {
983
+ expect(sortkeys.length).to.equal(3);
984
+ expect(function () {
985
+ return Script.buildMultisigOut(sortkeys, 4);
986
+ }).to.throw(
987
+ 'Number of required signatures must be less than or equal to the number of public keys',
988
+ );
989
+ });
990
+ it('should create unsorted script if specified', function () {
991
+ var s = Script.buildMultisigOut(sortkeys, 2);
992
+ var u = Script.buildMultisigOut(sortkeys, 2, {
993
+ noSorting: true,
994
+ });
995
+ s.toString().should.not.equal(u.toString());
996
+ u.toString().should.equal(
997
+ 'OP_2 33 0x022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da 33 0x03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 33 0x021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 OP_3 OP_CHECKMULTISIG',
998
+ );
999
+ s.isMultisigOut().should.equal(true);
1000
+ });
1001
+ var testMn = function (m, n) {
1002
+ var pubkeys = pubKeyHexes.slice(0, n).map(PublicKey);
1003
+ var s = Script.buildMultisigOut(pubkeys, m);
1004
+ s.isMultisigOut().should.equal(true);
1005
+ };
1006
+ for (var n = 1; n < 6; n++) {
1007
+ for (var m = 1; m <= n; m++) {
1008
+ it('should create ' + m + '-of-' + n, testMn.bind(null, m, n));
1009
+ }
1010
+ }
1011
+ });
1012
+ describe('#buildPublicKeyHashOut', function () {
1013
+ it('should create script from livenet address', function () {
1014
+ var address = Address.fromString('1NaTVwXDDUJaXDQajoa9MqHhz4uTxtgK14');
1015
+ var s = Script.buildPublicKeyHashOut(address);
1016
+ should.exist(s);
1017
+ s.toString().should.equal(
1018
+ 'OP_DUP OP_HASH160 20 0xecae7d092947b7ee4998e254aa48900d26d2ce1d OP_EQUALVERIFY OP_CHECKSIG',
1019
+ );
1020
+ s.isPublicKeyHashOut().should.equal(true);
1021
+ s.toAddress().toString().should.equal('1NaTVwXDDUJaXDQajoa9MqHhz4uTxtgK14');
1022
+ });
1023
+ it('should create script from testnet address', function () {
1024
+ var address = Address.fromString('mxRN6AQJaDi5R6KmvMaEmZGe3n5ScV9u33');
1025
+ var s = Script.buildPublicKeyHashOut(address);
1026
+ should.exist(s);
1027
+ s.toString().should.equal(
1028
+ 'OP_DUP OP_HASH160 20 0xb96b816f378babb1fe585b7be7a2cd16eb99b3e4 OP_EQUALVERIFY OP_CHECKSIG',
1029
+ );
1030
+ s.isPublicKeyHashOut().should.equal(true);
1031
+ s.toAddress().toString().should.equal('mxRN6AQJaDi5R6KmvMaEmZGe3n5ScV9u33');
1032
+ });
1033
+ it('should create script from public key', function () {
1034
+ var pubkey = new PublicKey(
1035
+ '022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da',
1036
+ );
1037
+ var s = Script.buildPublicKeyHashOut(pubkey);
1038
+ should.exist(s);
1039
+ s.toString().should.equal(
1040
+ 'OP_DUP OP_HASH160 20 0x9674af7395592ec5d91573aa8d6557de55f60147 OP_EQUALVERIFY OP_CHECKSIG',
1041
+ );
1042
+ s.isPublicKeyHashOut().should.equal(true);
1043
+ should.exist(s._network);
1044
+ s._network.should.equal(pubkey.network);
1045
+ });
1046
+ });
1047
+ describe('#buildPublicKeyOut', function () {
1048
+ it('should create script from public key', function () {
1049
+ var pubkey = new PublicKey(
1050
+ '022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da',
1051
+ );
1052
+ var s = Script.buildPublicKeyOut(pubkey);
1053
+ should.exist(s);
1054
+ s.toString().should.equal(
1055
+ '33 0x022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da OP_CHECKSIG',
1056
+ );
1057
+ s.isPublicKeyOut().should.equal(true);
1058
+ });
1059
+ });
1060
+ describe('#buildDataOut', function () {
1061
+ it('should create script from no data', function () {
1062
+ var s = Script.buildDataOut();
1063
+ should.exist(s);
1064
+ s.toString().should.equal('OP_RETURN');
1065
+ s.isDataOut().should.equal(true);
1066
+ });
1067
+ it('should create script from empty data', function () {
1068
+ var data = Buffer.from('');
1069
+ var s = Script.buildDataOut(data);
1070
+ should.exist(s);
1071
+ s.toString().should.equal('OP_RETURN OP_0');
1072
+ s.isDataOut().should.equal(true);
1073
+ });
1074
+ it('should create script from some data', function () {
1075
+ var data = Buffer.from('bacacafe0102030405', 'hex');
1076
+ var s = Script.buildDataOut(data);
1077
+ should.exist(s);
1078
+ s.toString().should.equal('OP_RETURN 9 0xbacacafe0102030405');
1079
+ s.isDataOut().should.equal(true);
1080
+ });
1081
+ it('should create script from array of some data', function () {
1082
+ var data = Buffer.from('bacacafe0102030405', 'hex');
1083
+ var s = Script.buildDataOut([data, data]);
1084
+ should.exist(s);
1085
+ s.toString().should.equal('OP_RETURN 9 0xbacacafe0102030405 9 0xbacacafe0102030405');
1086
+ s.isDataOut().should.equal(true);
1087
+ });
1088
+ it('should create script from array of some datas', function () {
1089
+ var data1 = Buffer.from('moneybutton.com');
1090
+ var data2 = Buffer.from('hello'.repeat(100));
1091
+ var s = Script.buildDataOut([data1, data2]);
1092
+ should.exist(s);
1093
+ s.toString().should.equal(
1094
+ 'OP_RETURN 15 0x6d6f6e6579627574746f6e2e636f6d OP_PUSHDATA2 500 0x68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f',
1095
+ );
1096
+ s.isDataOut().should.equal(true);
1097
+ });
1098
+ it('should create script from array of lots of data', function () {
1099
+ var data1 = Buffer.from('moneybutton.com');
1100
+ var data2 = Buffer.from('00'.repeat(90000), 'hex');
1101
+ var s = Script.buildDataOut([data1, data2]);
1102
+ should.exist(s);
1103
+ s.toString().should.equal(
1104
+ 'OP_RETURN 15 0x6d6f6e6579627574746f6e2e636f6d OP_PUSHDATA4 90000 0x' + '00'.repeat(90000),
1105
+ );
1106
+ s.isDataOut().should.equal(true);
1107
+ });
1108
+ it('should create script from string', function () {
1109
+ var data = 'hello world!!!';
1110
+ var s = Script.buildDataOut(data);
1111
+ should.exist(s);
1112
+ s.toString().should.equal('OP_RETURN 14 0x68656c6c6f20776f726c64212121');
1113
+ s.isDataOut().should.equal(true);
1114
+ });
1115
+ it('should create script from an array of strings', function () {
1116
+ var data = 'hello world!!!';
1117
+ var s = Script.buildDataOut([data, data]);
1118
+ should.exist(s);
1119
+ s.toString().should.equal(
1120
+ 'OP_RETURN 14 0x68656c6c6f20776f726c64212121 14 0x68656c6c6f20776f726c64212121',
1121
+ );
1122
+ s.isDataOut().should.equal(true);
1123
+ });
1124
+ it('should create script from a hex string', function () {
1125
+ var hexString = 'abcdef0123456789';
1126
+ var s = Script.buildDataOut(hexString, 'hex');
1127
+ should.exist(s);
1128
+ s.toString().should.equal('OP_RETURN 8 0xabcdef0123456789');
1129
+ s.isDataOut().should.equal(true);
1130
+ });
1131
+ it('should create script from an array of a hex string', function () {
1132
+ var hexString = 'abcdef0123456789';
1133
+ var s = Script.buildDataOut([hexString], 'hex');
1134
+ should.exist(s);
1135
+ s.toString().should.equal('OP_RETURN 8 0xabcdef0123456789');
1136
+ s.isDataOut().should.equal(true);
1137
+ });
1138
+ it('should create script from an array of hex strings', function () {
1139
+ var hexString = 'abcdef0123456789';
1140
+ var s = Script.buildDataOut([hexString, hexString], 'hex');
1141
+ should.exist(s);
1142
+ s.toString().should.equal('OP_RETURN 8 0xabcdef0123456789 8 0xabcdef0123456789');
1143
+ s.isDataOut().should.equal(true);
1144
+ });
1145
+ });
1146
+ describe('#buildSafeDataOut', function () {
1147
+ it('should create script from no data', function () {
1148
+ var s = Script.buildSafeDataOut();
1149
+ should.exist(s);
1150
+ s.toString().should.equal('OP_0 OP_RETURN');
1151
+ s.isSafeDataOut().should.equal(true);
1152
+ });
1153
+ it('should create script from empty data', function () {
1154
+ var data = Buffer.from('');
1155
+ var s = Script.buildSafeDataOut(data);
1156
+ should.exist(s);
1157
+ s.toString().should.equal('OP_0 OP_RETURN OP_0');
1158
+ s.isSafeDataOut().should.equal(true);
1159
+ });
1160
+ it('should create script from some data', function () {
1161
+ var data = Buffer.from('bacacafe0102030405', 'hex');
1162
+ var s = Script.buildSafeDataOut(data);
1163
+ should.exist(s);
1164
+ s.toString().should.equal('OP_0 OP_RETURN 9 0xbacacafe0102030405');
1165
+ s.isSafeDataOut().should.equal(true);
1166
+ });
1167
+ it('should create script from array of some data', function () {
1168
+ var data = Buffer.from('bacacafe0102030405', 'hex');
1169
+ var s = Script.buildSafeDataOut([data, data]);
1170
+ should.exist(s);
1171
+ s.toString().should.equal('OP_0 OP_RETURN 9 0xbacacafe0102030405 9 0xbacacafe0102030405');
1172
+ s.isSafeDataOut().should.equal(true);
1173
+ });
1174
+ it('should create script from array of some datas', function () {
1175
+ var data1 = Buffer.from('moneybutton.com');
1176
+ var data2 = Buffer.from('hello'.repeat(100));
1177
+ var s = Script.buildSafeDataOut([data1, data2]);
1178
+ should.exist(s);
1179
+ s.toString().should.equal(
1180
+ 'OP_0 OP_RETURN 15 0x6d6f6e6579627574746f6e2e636f6d OP_PUSHDATA2 500 0x68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f68656c6c6f',
1181
+ );
1182
+ s.isSafeDataOut().should.equal(true);
1183
+ });
1184
+ it('should create script from array of lots of data', function () {
1185
+ var data1 = Buffer.from('moneybutton.com');
1186
+ var data2 = Buffer.from('00'.repeat(90000), 'hex');
1187
+ var s = Script.buildSafeDataOut([data1, data2]);
1188
+ should.exist(s);
1189
+ s.toString().should.equal(
1190
+ 'OP_0 OP_RETURN 15 0x6d6f6e6579627574746f6e2e636f6d OP_PUSHDATA4 90000 0x' +
1191
+ '00'.repeat(90000),
1192
+ );
1193
+ s.isSafeDataOut().should.equal(true);
1194
+ });
1195
+ it('should create script from string', function () {
1196
+ var data = 'hello world!!!';
1197
+ var s = Script.buildSafeDataOut(data);
1198
+ should.exist(s);
1199
+ s.toString().should.equal('OP_0 OP_RETURN 14 0x68656c6c6f20776f726c64212121');
1200
+ s.isSafeDataOut().should.equal(true);
1201
+ });
1202
+ it('should create script from an array of strings', function () {
1203
+ var data = 'hello world!!!';
1204
+ var s = Script.buildSafeDataOut([data, data]);
1205
+ should.exist(s);
1206
+ s.toString().should.equal(
1207
+ 'OP_0 OP_RETURN 14 0x68656c6c6f20776f726c64212121 14 0x68656c6c6f20776f726c64212121',
1208
+ );
1209
+ s.isSafeDataOut().should.equal(true);
1210
+ });
1211
+ it('should create script from a hex string', function () {
1212
+ var hexString = 'abcdef0123456789';
1213
+ var s = Script.buildSafeDataOut(hexString, 'hex');
1214
+ should.exist(s);
1215
+ s.toString().should.equal('OP_0 OP_RETURN 8 0xabcdef0123456789');
1216
+ s.isSafeDataOut().should.equal(true);
1217
+ });
1218
+ it('should create script from an array of a hex string', function () {
1219
+ var hexString = 'abcdef0123456789';
1220
+ var s = Script.buildSafeDataOut([hexString], 'hex');
1221
+ should.exist(s);
1222
+ s.toString().should.equal('OP_0 OP_RETURN 8 0xabcdef0123456789');
1223
+ s.isSafeDataOut().should.equal(true);
1224
+ });
1225
+ it('should create script from an array of hex strings', function () {
1226
+ var hexString = 'abcdef0123456789';
1227
+ var s = Script.buildSafeDataOut([hexString, hexString], 'hex');
1228
+ should.exist(s);
1229
+ s.toString().should.equal('OP_0 OP_RETURN 8 0xabcdef0123456789 8 0xabcdef0123456789');
1230
+ s.isSafeDataOut().should.equal(true);
1231
+ });
1232
+ });
1233
+
1234
+ describe('#removeCodeseparators', function () {
1235
+ it('should remove any OP_CODESEPARATORs', function () {
1236
+ Script('OP_CODESEPARATOR OP_0 OP_CODESEPARATOR')
1237
+ .removeCodeseparators()
1238
+ .toString()
1239
+ .should.equal('OP_0');
1240
+ });
1241
+ });
1242
+
1243
+ describe('#findAndDelete', function () {
1244
+ it('should find and delete this buffer', function () {
1245
+ Script('OP_RETURN 2 0xf0f0')
1246
+ .findAndDelete(Script('2 0xf0f0'))
1247
+ .toString()
1248
+ .should.equal('OP_RETURN');
1249
+ });
1250
+ it('should do nothing', function () {
1251
+ Script('OP_RETURN 2 0xf0f0')
1252
+ .findAndDelete(Script('2 0xffff'))
1253
+ .toString()
1254
+ .should.equal('OP_RETURN 2 0xf0f0');
1255
+ });
1256
+ });
1257
+
1258
+ describe('#checkMinimalPush', function () {
1259
+ it('should check these minimal pushes', function () {
1260
+ Script().add(1).checkMinimalPush(0).should.equal(false);
1261
+ Script().add(0).checkMinimalPush(0).should.equal(true);
1262
+ Script().add(-1).checkMinimalPush(0).should.equal(true);
1263
+ Script()
1264
+ .add(Buffer.from([0]))
1265
+ .checkMinimalPush(0)
1266
+ .should.equal(true);
1267
+
1268
+ var buf = Buffer.alloc(75);
1269
+ buf.fill(1);
1270
+ Script().add(buf).checkMinimalPush(0).should.equal(true);
1271
+
1272
+ buf = Buffer.alloc(76);
1273
+ buf.fill(1);
1274
+ Script().add(buf).checkMinimalPush(0).should.equal(true);
1275
+
1276
+ buf = Buffer.alloc(256);
1277
+ buf.fill(1);
1278
+ Script().add(buf).checkMinimalPush(0).should.equal(true);
1279
+ });
1280
+ });
1281
+
1282
+ describe('getData returns associated data', function () {
1283
+ it('works with this testnet transaction', function () {
1284
+ // testnet block: 00000000a36400fc06440512354515964bc36ecb0020bd0b0fd48ae201965f54
1285
+ // txhash: e362e21ff1d2ef78379d401d89b42ce3e0ce3e245f74b1f4cb624a8baa5d53ad (output 0);
1286
+ var script = Script.fromBuffer(Buffer.from('6a', 'hex'));
1287
+ var dataout = script.isDataOut();
1288
+ dataout.should.equal(true);
1289
+ var data = script.getData();
1290
+ data.should.deep.equal(Buffer.alloc(0));
1291
+ });
1292
+ it('for a P2PKH address', function () {
1293
+ var address = Address.fromString('1NaTVwXDDUJaXDQajoa9MqHhz4uTxtgK14');
1294
+ var script = Script.buildPublicKeyHashOut(address);
1295
+ expect(script.getData().equals(address.hashBuffer)).to.equal(true);
1296
+ });
1297
+
1298
+ it('for a old-style opreturn output', function () {
1299
+ expect(
1300
+ Script('OP_RETURN 1 0xFF')
1301
+ .getData()
1302
+ .equals(Buffer.from([255])),
1303
+ ).to.equal(true);
1304
+ });
1305
+ it('for a safe opreturn output', function () {
1306
+ expect(
1307
+ Script('OP_FALSE OP_RETURN 1 0xFF')
1308
+ .getData()[0]
1309
+ .equals(Buffer.from([255])),
1310
+ ).to.equal(true);
1311
+ });
1312
+ it('fails if content is not recognized', function () {
1313
+ expect(function () {
1314
+ return Script('1 0xFF').getData();
1315
+ }).to.throw();
1316
+ });
1317
+ });
1318
+
1319
+ describe('toAddress', function () {
1320
+ var pubkey = new PublicKey(
1321
+ '027ffeb8c7795d529ee9cd96512d472cefe398a0597623438ac5d066a64af50072',
1322
+ );
1323
+ var liveAddress = pubkey.toAddress(Networks.livenet);
1324
+ var testAddress = pubkey.toAddress(Networks.testnet);
1325
+
1326
+ it('priorize the network argument', function () {
1327
+ var script = new Script(liveAddress);
1328
+ script.toAddress(Networks.testnet).toString().should.equal(testAddress.toString());
1329
+ script.toAddress(Networks.testnet).network.should.equal(Networks.testnet);
1330
+ });
1331
+ it('use the inherited network', function () {
1332
+ var script = new Script(liveAddress);
1333
+ script.toAddress().toString().should.equal(liveAddress.toString());
1334
+ script = new Script(testAddress);
1335
+ script.toAddress().toString().should.equal(testAddress.toString());
1336
+ });
1337
+ it('uses default network', function () {
1338
+ var script = new Script(
1339
+ 'OP_DUP OP_HASH160 20 ' +
1340
+ '0x06c06f6d931d7bfba2b5bd5ad0d19a8f257af3e3 OP_EQUALVERIFY OP_CHECKSIG',
1341
+ );
1342
+ script.toAddress().network.should.equal(Networks.defaultNetwork);
1343
+ });
1344
+ it('for a P2PKH address', function () {
1345
+ var stringAddress = '1NaTVwXDDUJaXDQajoa9MqHhz4uTxtgK14';
1346
+ var address = new Address(stringAddress);
1347
+ var script = new Script(address);
1348
+ script.toAddress().toString().should.equal(stringAddress);
1349
+ });
1350
+
1351
+ it('fails if content is not recognized', function () {
1352
+ Script().toAddress(Networks.livenet).should.equal(false);
1353
+ });
1354
+
1355
+ it('works for p2pkh output', function () {
1356
+ // taken from tx 7e519caca256423320b92e3e17be5701f87afecbdb3f53af598032bfd8d164f5
1357
+ var script = new Script(
1358
+ 'OP_DUP OP_HASH160 20 ' +
1359
+ '0xc8e11b0eb0d2ad5362d894f048908341fa61b6e1 OP_EQUALVERIFY OP_CHECKSIG',
1360
+ );
1361
+ script.toAddress().toString().should.equal('1KK9oz4bFH8c1t6LmighHaoSEGx3P3FEmc');
1362
+ });
1363
+ it('works for p2pkh input', function () {
1364
+ // taken from tx 7e519caca256423320b92e3e17be5701f87afecbdb3f53af598032bfd8d164f5
1365
+ var script = new Script(
1366
+ '72 0x3045022100eff96230ca0f55b1e8c7a63e014f48611ff1af40875ecd33dee9062d7a6f5e2002206320405b5f6992c756e03e66b21a05a812b60996464ac6af815c2638b930dd7a01 65 0x04150defa035a2c7d826d7d5fc8ab2154bd1bb832f1a5c8ecb338f436362ad232e428b57db44677c5a8bd42c5ed9e2d7e04e742c59bee1b40080cfd57dec64b23a',
1367
+ );
1368
+ script.toAddress().toString().should.equal('1KK9oz4bFH8c1t6LmighHaoSEGx3P3FEmc');
1369
+ // taken from tx 7f8f95752a59d715dae9e0008a42e7968d2736741591bbfc6685f6e1649c21ed
1370
+ var s2 = new Script(
1371
+ '0x47 0x3044022017053dad84aa06213749df50a03330cfd24d6b8e7ddbb6de66c03697b78a752a022053bc0faca8b4049fb3944a05fcf7c93b2861734d39a89b73108f605f70f5ed3401 33 0x0225386e988b84248dc9c30f784b06e02fdec57bbdbd443768eb5744a75ce44a4c',
1372
+ );
1373
+ s2.toAddress().toString().should.equal('17VArX6GRE6i6MVscBUZoXwi6NhnHa68B7');
1374
+ });
1375
+
1376
+ // no address scripts
1377
+ it('works for OP_RETURN script', function () {
1378
+ var script = new Script('OP_RETURN 20 0x99d29051af0c29adcb9040034752bba7dde33e35');
1379
+ script.toAddress().should.equal(false);
1380
+ });
1381
+ });
1382
+ describe('equals', function () {
1383
+ it('returns true for same script', function () {
1384
+ Script('OP_TRUE').equals(Script('OP_TRUE')).should.equal(true);
1385
+ });
1386
+ it('returns false for different chunks sizes', function () {
1387
+ Script('OP_TRUE').equals(Script('OP_TRUE OP_TRUE')).should.equal(false);
1388
+ });
1389
+ it('returns false for different opcodes', function () {
1390
+ Script('OP_TRUE OP_TRUE').equals(Script('OP_TRUE OP_FALSE')).should.equal(false);
1391
+ });
1392
+ it('returns false for different data', function () {
1393
+ Script().add(Buffer.from('a')).equals(Script('OP_TRUE')).should.equal(false);
1394
+ });
1395
+ it('returns false for different data', function () {
1396
+ Script()
1397
+ .add(Buffer.from('a'))
1398
+ .equals(Script().add(Buffer.from('b')))
1399
+ .should.equal(false);
1400
+ });
1401
+ });
1402
+
1403
+ describe('#getSignatureOperationsCount', function () {
1404
+ // comes from bitcoind src/test/sigopcount_tests
1405
+ // only test calls to function with boolean param, not signature ref param
1406
+ var pubKeyHexes = [
1407
+ '022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da',
1408
+ '03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9',
1409
+ '021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18',
1410
+ ];
1411
+ it('should return zero for empty scripts', function () {
1412
+ Script().getSignatureOperationsCount(false).should.equal(0);
1413
+ Script().getSignatureOperationsCount(true).should.equal(0);
1414
+ });
1415
+ it('should handle multi-sig multisig scripts from string', function () {
1416
+ var s1 = 'OP_1 01 0xFF OP_2 OP_CHECKMULTISIG';
1417
+ Script(s1).getSignatureOperationsCount(true).should.equal(2);
1418
+ s1 += ' OP_IF OP_CHECKSIG OP_ENDIF';
1419
+ Script(s1).getSignatureOperationsCount(true).should.equal(3);
1420
+ Script(s1).getSignatureOperationsCount(false).should.equal(21);
1421
+ });
1422
+ it('should handle multi-sig-out scripts from utility function', function () {
1423
+ var sortKeys = pubKeyHexes.slice(0, 3).map(PublicKey);
1424
+ var s2 = Script.buildMultisigOut(sortKeys, 1);
1425
+ Script(s2).getSignatureOperationsCount(true).should.equal(3);
1426
+ Script(s2).getSignatureOperationsCount(false).should.equal(20);
1427
+ });
1428
+ it('should default the one and only argument to true', function () {
1429
+ var s1 = 'OP_1 01 0xFF OP_2 OP_CHECKMULTISIG';
1430
+ var trueCount = Script(s1).getSignatureOperationsCount(true);
1431
+ var falseCount = Script(s1).getSignatureOperationsCount(false);
1432
+ var defaultCount = Script(s1).getSignatureOperationsCount();
1433
+ trueCount.should.not.equal(falseCount);
1434
+ trueCount.should.equal(defaultCount);
1435
+ });
1436
+ });
1437
+ });