@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,323 @@
1
+ 'use strict';
2
+
3
+ var _ = require('../util/_');
4
+ var BlockHeader = require('./blockheader');
5
+ var BufferReader = require('../encoding/bufferreader');
6
+ var BufferWriter = require('../encoding/bufferwriter');
7
+ var Hash = require('../crypto/hash');
8
+ var Transaction = require('../transaction');
9
+ var errors = require('../errors');
10
+ var $ = require('../util/preconditions');
11
+
12
+ /**
13
+ * Instantiate a MerkleBlock from a Buffer, JSON object, or Object with
14
+ * the properties of the Block
15
+ *
16
+ * @param {*} - A Buffer, JSON string, or Object representing a MerkleBlock
17
+ * @returns {MerkleBlock}
18
+ * @constructor
19
+ */
20
+ function MerkleBlock(arg) {
21
+ if (!(this instanceof MerkleBlock)) {
22
+ return new MerkleBlock(arg);
23
+ }
24
+
25
+ var info = {};
26
+ if (Buffer.isBuffer(arg)) {
27
+ info = MerkleBlock._fromBufferReader(BufferReader(arg));
28
+ } else if (_.isObject(arg)) {
29
+ var header;
30
+ if (arg.header instanceof BlockHeader) {
31
+ header = arg.header;
32
+ } else {
33
+ header = BlockHeader.fromObject(arg.header);
34
+ }
35
+ info = {
36
+ /**
37
+ * @name MerkleBlock#header
38
+ * @type {BlockHeader}
39
+ */
40
+ header: header,
41
+ /**
42
+ * @name MerkleBlock#numTransactions
43
+ * @type {Number}
44
+ */
45
+ numTransactions: arg.numTransactions,
46
+ /**
47
+ * @name MerkleBlock#hashes
48
+ * @type {String[]}
49
+ */
50
+ hashes: arg.hashes,
51
+ /**
52
+ * @name MerkleBlock#flags
53
+ * @type {Number[]}
54
+ */
55
+ flags: arg.flags,
56
+ };
57
+ } else {
58
+ throw new TypeError('Unrecognized argument for MerkleBlock');
59
+ }
60
+ _.extend(this, info);
61
+ this._flagBitsUsed = 0;
62
+ this._hashesUsed = 0;
63
+
64
+ return this;
65
+ }
66
+
67
+ /**
68
+ * @param {Buffer} - MerkleBlock data in a Buffer object
69
+ * @returns {MerkleBlock} - A MerkleBlock object
70
+ */
71
+ MerkleBlock.fromBuffer = function fromBuffer(buf) {
72
+ return MerkleBlock.fromBufferReader(BufferReader(buf));
73
+ };
74
+
75
+ /**
76
+ * @param {BufferReader} - MerkleBlock data in a BufferReader object
77
+ * @returns {MerkleBlock} - A MerkleBlock object
78
+ */
79
+ MerkleBlock.fromBufferReader = function fromBufferReader(br) {
80
+ return new MerkleBlock(MerkleBlock._fromBufferReader(br));
81
+ };
82
+
83
+ /**
84
+ * @returns {Buffer} - A buffer of the block
85
+ */
86
+ MerkleBlock.prototype.toBuffer = function toBuffer() {
87
+ return this.toBufferWriter().concat();
88
+ };
89
+
90
+ /**
91
+ * @param {BufferWriter} - An existing instance of BufferWriter
92
+ * @returns {BufferWriter} - An instance of BufferWriter representation of the MerkleBlock
93
+ */
94
+ MerkleBlock.prototype.toBufferWriter = function toBufferWriter(bw) {
95
+ if (!bw) {
96
+ bw = new BufferWriter();
97
+ }
98
+ bw.write(this.header.toBuffer());
99
+ bw.writeUInt32LE(this.numTransactions);
100
+ bw.writeVarintNum(this.hashes.length);
101
+ for (var i = 0; i < this.hashes.length; i++) {
102
+ bw.write(Buffer.from(this.hashes[i], 'hex'));
103
+ }
104
+ bw.writeVarintNum(this.flags.length);
105
+ for (i = 0; i < this.flags.length; i++) {
106
+ bw.writeUInt8(this.flags[i]);
107
+ }
108
+ return bw;
109
+ };
110
+
111
+ /**
112
+ * @returns {Object} - A plain object with the MerkleBlock properties
113
+ */
114
+ MerkleBlock.prototype.toObject = MerkleBlock.prototype.toJSON = function toObject() {
115
+ return {
116
+ header: this.header.toObject(),
117
+ numTransactions: this.numTransactions,
118
+ hashes: this.hashes,
119
+ flags: this.flags,
120
+ };
121
+ };
122
+
123
+ /**
124
+ * Verify that the MerkleBlock is valid
125
+ * @returns {Boolean} - True/False whether this MerkleBlock is Valid
126
+ */
127
+ MerkleBlock.prototype.validMerkleTree = function validMerkleTree() {
128
+ $.checkState(_.isArray(this.flags), 'MerkleBlock flags is not an array');
129
+ $.checkState(_.isArray(this.hashes), 'MerkleBlock hashes is not an array');
130
+
131
+ // Can't have more hashes than numTransactions
132
+ if (this.hashes.length > this.numTransactions) {
133
+ return false;
134
+ }
135
+
136
+ // Can't have more flag bits than num hashes
137
+ if (this.flags.length * 8 < this.hashes.length) {
138
+ return false;
139
+ }
140
+
141
+ var height = this._calcTreeHeight();
142
+ var opts = { hashesUsed: 0, flagBitsUsed: 0 };
143
+ var root = this._traverseMerkleTree(height, 0, opts);
144
+ if (opts.hashesUsed !== this.hashes.length) {
145
+ return false;
146
+ }
147
+ return root.equals(this.header.merkleRoot);
148
+ };
149
+
150
+ /**
151
+ * WARNING: This method is deprecated. Use filteredTxsHash instead.
152
+ *
153
+ * Return a list of all the txs hash that match the filter
154
+ * @returns {Array} - txs hash that match the filter
155
+ */
156
+ MerkleBlock.prototype.filterdTxsHash = function filterdTxsHash() {
157
+ throw new Error('filterdTxsHash has been deprecated. use filteredTxsHash.');
158
+ };
159
+
160
+ /**
161
+ * Return a list of all the txs hash that match the filter
162
+ * @returns {Array} - txs hash that match the filter
163
+ */
164
+ MerkleBlock.prototype.filteredTxsHash = function filteredTxsHash() {
165
+ $.checkState(_.isArray(this.flags), 'MerkleBlock flags is not an array');
166
+ $.checkState(_.isArray(this.hashes), 'MerkleBlock hashes is not an array');
167
+
168
+ // Can't have more hashes than numTransactions
169
+ if (this.hashes.length > this.numTransactions) {
170
+ throw new errors.MerkleBlock.InvalidMerkleTree();
171
+ }
172
+
173
+ // Can't have more flag bits than num hashes
174
+ if (this.flags.length * 8 < this.hashes.length) {
175
+ throw new errors.MerkleBlock.InvalidMerkleTree();
176
+ }
177
+
178
+ // If there is only one hash the filter do not match any txs in the block
179
+ if (this.hashes.length === 1) {
180
+ return [];
181
+ }
182
+
183
+ var height = this._calcTreeHeight();
184
+ var opts = { hashesUsed: 0, flagBitsUsed: 0 };
185
+ var txs = this._traverseMerkleTree(height, 0, opts, true);
186
+ if (opts.hashesUsed !== this.hashes.length) {
187
+ throw new errors.MerkleBlock.InvalidMerkleTree();
188
+ }
189
+ return txs;
190
+ };
191
+
192
+ /**
193
+ * Traverse a the tree in this MerkleBlock, validating it along the way
194
+ * Modeled after Bitcoin Core merkleblock.cpp TraverseAndExtract()
195
+ * @param {Number} - depth - Current height
196
+ * @param {Number} - pos - Current position in the tree
197
+ * @param {Object} - opts - Object with values that need to be mutated throughout the traversal
198
+ * @param {Boolean} - checkForTxs - if true return opts.txs else return the Merkle Hash
199
+ * @param {Number} - opts.flagBitsUsed - Number of flag bits used, should start at 0
200
+ * @param {Number} - opts.hashesUsed - Number of hashes used, should start at 0
201
+ * @param {Array} - opts.txs - Will finish populated by transactions found during traversal that match the filter
202
+ * @returns {Buffer|null} - Buffer containing the Merkle Hash for that height
203
+ * @returns {Array} - transactions found during traversal that match the filter
204
+ * @private
205
+ */
206
+ MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(
207
+ depth,
208
+ pos,
209
+ opts,
210
+ checkForTxs,
211
+ ) {
212
+ opts = opts || {};
213
+ opts.txs = opts.txs || [];
214
+ opts.flagBitsUsed = opts.flagBitsUsed || 0;
215
+ opts.hashesUsed = opts.hashesUsed || 0;
216
+ checkForTxs = checkForTxs || false;
217
+
218
+ if (opts.flagBitsUsed > this.flags.length * 8) {
219
+ return null;
220
+ }
221
+ var isParentOfMatch = (this.flags[opts.flagBitsUsed >> 3] >>> (opts.flagBitsUsed++ & 7)) & 1;
222
+ if (depth === 0 || !isParentOfMatch) {
223
+ if (opts.hashesUsed >= this.hashes.length) {
224
+ return null;
225
+ }
226
+ var hash = this.hashes[opts.hashesUsed++];
227
+ if (depth === 0 && isParentOfMatch) {
228
+ opts.txs.push(hash);
229
+ }
230
+ return Buffer.from(hash, 'hex');
231
+ } else {
232
+ var left = this._traverseMerkleTree(depth - 1, pos * 2, opts);
233
+ var right = left;
234
+ if (pos * 2 + 1 < this._calcTreeWidth(depth - 1)) {
235
+ right = this._traverseMerkleTree(depth - 1, pos * 2 + 1, opts);
236
+ }
237
+ if (checkForTxs) {
238
+ return opts.txs;
239
+ } else {
240
+ return Hash.sha256sha256(Buffer.concat([left, right]));
241
+ }
242
+ }
243
+ };
244
+
245
+ /** Calculates the width of a merkle tree at a given height.
246
+ * Modeled after Bitcoin Core merkleblock.h CalcTreeWidth()
247
+ * @param {Number} - Height at which we want the tree width
248
+ * @returns {Number} - Width of the tree at a given height
249
+ * @private
250
+ */
251
+ MerkleBlock.prototype._calcTreeWidth = function calcTreeWidth(height) {
252
+ return (this.numTransactions + (1 << height) - 1) >> height;
253
+ };
254
+
255
+ /** Calculates the height of the merkle tree in this MerkleBlock
256
+ * @param {Number} - Height at which we want the tree width
257
+ * @returns {Number} - Height of the merkle tree in this MerkleBlock
258
+ * @private
259
+ */
260
+ MerkleBlock.prototype._calcTreeHeight = function calcTreeHeight() {
261
+ var height = 0;
262
+ while (this._calcTreeWidth(height) > 1) {
263
+ height++;
264
+ }
265
+ return height;
266
+ };
267
+
268
+ /**
269
+ * @param {Transaction|String} - Transaction or Transaction ID Hash
270
+ * @returns {Boolean} - return true/false if this MerkleBlock has the TX or not
271
+ * @private
272
+ */
273
+ MerkleBlock.prototype.hasTransaction = function hasTransaction(tx) {
274
+ $.checkArgument(!_.isUndefined(tx), 'tx cannot be undefined');
275
+ $.checkArgument(
276
+ tx instanceof Transaction || typeof tx === 'string',
277
+ 'Invalid tx given, tx must be a "string" or "Transaction"',
278
+ );
279
+
280
+ var hash = tx;
281
+ if (tx instanceof Transaction) {
282
+ // We need to reverse the id hash for the lookup
283
+ hash = Buffer.from(tx.id, 'hex').reverse().toString('hex');
284
+ }
285
+
286
+ var txs = [];
287
+ var height = this._calcTreeHeight();
288
+ this._traverseMerkleTree(height, 0, { txs: txs });
289
+ return txs.indexOf(hash) !== -1;
290
+ };
291
+
292
+ /**
293
+ * @param {Buffer} - MerkleBlock data
294
+ * @returns {Object} - An Object representing merkleblock data
295
+ * @private
296
+ */
297
+ MerkleBlock._fromBufferReader = function _fromBufferReader(br) {
298
+ $.checkState(!br.finished(), 'No merkleblock data received');
299
+ var info = {};
300
+ info.header = BlockHeader.fromBufferReader(br);
301
+ info.numTransactions = br.readUInt32LE();
302
+ var numHashes = br.readVarintNum();
303
+ info.hashes = [];
304
+ for (var i = 0; i < numHashes; i++) {
305
+ info.hashes.push(br.read(32).toString('hex'));
306
+ }
307
+ var numFlags = br.readVarintNum();
308
+ info.flags = [];
309
+ for (i = 0; i < numFlags; i++) {
310
+ info.flags.push(br.readUInt8());
311
+ }
312
+ return info;
313
+ };
314
+
315
+ /**
316
+ * @param {Object} - A plain JavaScript object
317
+ * @returns {Block} - An instance of block
318
+ */
319
+ MerkleBlock.fromObject = function fromObject(obj) {
320
+ return new MerkleBlock(obj);
321
+ };
322
+
323
+ module.exports = MerkleBlock;