@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,277 @@
1
+ 'use strict';
2
+
3
+ var _ = require('../util/_');
4
+ var BlockHeader = require('./blockheader');
5
+ var BN = require('../crypto/bn');
6
+ var BufferReader = require('../encoding/bufferreader');
7
+ var BufferWriter = require('../encoding/bufferwriter');
8
+ var Hash = require('../crypto/hash');
9
+ var Transaction = require('../transaction');
10
+ var $ = require('../util/preconditions');
11
+
12
+ /**
13
+ * Instantiate a Block from a Buffer, JSON object, or Object with
14
+ * the properties of the Block
15
+ *
16
+ * @param {*} - A Buffer, JSON string, or Object
17
+ * @returns {Block}
18
+ * @constructor
19
+ */
20
+ function Block(arg) {
21
+ if (!(this instanceof Block)) {
22
+ return new Block(arg);
23
+ }
24
+ _.extend(this, Block._from(arg));
25
+ return this;
26
+ }
27
+
28
+ Block.MAX_BLOCK_SIZE = 128000000;
29
+
30
+ /**
31
+ * @param {*} - A Buffer, JSON string or Object
32
+ * @returns {Object} - An object representing block data
33
+ * @throws {TypeError} - If the argument was not recognized
34
+ * @private
35
+ */
36
+ Block._from = function _from(arg) {
37
+ var info = {};
38
+ if (Buffer.isBuffer(arg)) {
39
+ info = Block._fromBufferReader(BufferReader(arg));
40
+ } else if (_.isObject(arg)) {
41
+ info = Block._fromObject(arg);
42
+ } else {
43
+ throw new TypeError('Unrecognized argument for Block');
44
+ }
45
+ return info;
46
+ };
47
+
48
+ /**
49
+ * @param {Object} - A plain JavaScript object
50
+ * @returns {Object} - An object representing block data
51
+ * @private
52
+ */
53
+ Block._fromObject = function _fromObject(data) {
54
+ var transactions = [];
55
+ data.transactions.forEach(function (tx) {
56
+ if (tx instanceof Transaction) {
57
+ transactions.push(tx);
58
+ } else {
59
+ transactions.push(Transaction().fromObject(tx));
60
+ }
61
+ });
62
+ var info = {
63
+ header: BlockHeader.fromObject(data.header),
64
+ transactions: transactions,
65
+ };
66
+ return info;
67
+ };
68
+
69
+ /**
70
+ * @param {Object} - A plain JavaScript object
71
+ * @returns {Block} - An instance of block
72
+ */
73
+ Block.fromObject = function fromObject(obj) {
74
+ var info = Block._fromObject(obj);
75
+ return new Block(info);
76
+ };
77
+
78
+ /**
79
+ * @param {BufferReader} - Block data
80
+ * @returns {Object} - An object representing the block data
81
+ * @private
82
+ */
83
+ Block._fromBufferReader = function _fromBufferReader(br) {
84
+ var info = {};
85
+ $.checkState(!br.finished(), 'No block data received');
86
+ info.header = BlockHeader.fromBufferReader(br);
87
+ var transactions = br.readVarintNum();
88
+ info.transactions = [];
89
+ for (var i = 0; i < transactions; i++) {
90
+ info.transactions.push(Transaction().fromBufferReader(br));
91
+ }
92
+ return info;
93
+ };
94
+
95
+ /**
96
+ * @param {BufferReader} - A buffer reader of the block
97
+ * @returns {Block} - An instance of block
98
+ */
99
+ Block.fromBufferReader = function fromBufferReader(br) {
100
+ $.checkArgument(br, 'br is required');
101
+ var info = Block._fromBufferReader(br);
102
+ return new Block(info);
103
+ };
104
+
105
+ /**
106
+ * @param {Buffer} - A buffer of the block
107
+ * @returns {Block} - An instance of block
108
+ */
109
+ Block.fromBuffer = function fromBuffer(buf) {
110
+ return Block.fromBufferReader(new BufferReader(buf));
111
+ };
112
+
113
+ /**
114
+ * @param {string} - str - A hex encoded string of the block
115
+ * @returns {Block} - A hex encoded string of the block
116
+ */
117
+ Block.fromString = function fromString(str) {
118
+ var buf = Buffer.from(str, 'hex');
119
+ return Block.fromBuffer(buf);
120
+ };
121
+
122
+ /**
123
+ * @param {Binary} - Raw block binary data or buffer
124
+ * @returns {Block} - An instance of block
125
+ */
126
+ Block.fromRawBlock = function fromRawBlock(data) {
127
+ if (!Buffer.isBuffer(data)) {
128
+ data = Buffer.from(data, 'binary');
129
+ }
130
+ var br = BufferReader(data);
131
+ br.pos = Block.Values.START_OF_BLOCK;
132
+ var info = Block._fromBufferReader(br);
133
+ return new Block(info);
134
+ };
135
+
136
+ /**
137
+ * @returns {Object} - A plain object with the block properties
138
+ */
139
+ Block.prototype.toObject = Block.prototype.toJSON = function toObject() {
140
+ var transactions = [];
141
+ this.transactions.forEach(function (tx) {
142
+ transactions.push(tx.toObject());
143
+ });
144
+ return {
145
+ header: this.header.toObject(),
146
+ transactions: transactions,
147
+ };
148
+ };
149
+
150
+ /**
151
+ * @returns {Buffer} - A buffer of the block
152
+ */
153
+ Block.prototype.toBuffer = function toBuffer() {
154
+ return this.toBufferWriter().concat();
155
+ };
156
+
157
+ /**
158
+ * @returns {string} - A hex encoded string of the block
159
+ */
160
+ Block.prototype.toString = function toString() {
161
+ return this.toBuffer().toString('hex');
162
+ };
163
+
164
+ /**
165
+ * @param {BufferWriter} - An existing instance of BufferWriter
166
+ * @returns {BufferWriter} - An instance of BufferWriter representation of the Block
167
+ */
168
+ Block.prototype.toBufferWriter = function toBufferWriter(bw) {
169
+ if (!bw) {
170
+ bw = new BufferWriter();
171
+ }
172
+ bw.write(this.header.toBuffer());
173
+ bw.writeVarintNum(this.transactions.length);
174
+ for (var i = 0; i < this.transactions.length; i++) {
175
+ this.transactions[i].toBufferWriter(false, bw);
176
+ }
177
+ return bw;
178
+ };
179
+
180
+ /**
181
+ * Will iterate through each transaction and return an array of hashes
182
+ * @returns {Array} - An array with transaction hashes
183
+ */
184
+ Block.prototype.getTransactionHashes = function getTransactionHashes() {
185
+ var hashes = [];
186
+ if (this.transactions.length === 0) {
187
+ return [Block.Values.NULL_HASH];
188
+ }
189
+ for (var t = 0; t < this.transactions.length; t++) {
190
+ hashes.push(this.transactions[t]._getHash());
191
+ }
192
+ return hashes;
193
+ };
194
+
195
+ /**
196
+ * Will build a merkle tree of all the transactions, ultimately arriving at
197
+ * a single point, the merkle root.
198
+ * @link https://en.bitcoin.it/wiki/Protocol_specification#Merkle_Trees
199
+ * @returns {Array} - An array with each level of the tree after the other.
200
+ */
201
+ Block.prototype.getMerkleTree = function getMerkleTree() {
202
+ var tree = this.getTransactionHashes();
203
+
204
+ var j = 0;
205
+ for (var size = this.transactions.length; size > 1; size = Math.floor((size + 1) / 2)) {
206
+ for (var i = 0; i < size; i += 2) {
207
+ var i2 = Math.min(i + 1, size - 1);
208
+ var buf = Buffer.concat([tree[j + i], tree[j + i2]]);
209
+ tree.push(Hash.sha256sha256(buf));
210
+ }
211
+ j += size;
212
+ }
213
+
214
+ return tree;
215
+ };
216
+
217
+ /**
218
+ * Calculates the merkleRoot from the transactions.
219
+ * @returns {Buffer} - A buffer of the merkle root hash
220
+ */
221
+ Block.prototype.getMerkleRoot = function getMerkleRoot() {
222
+ var tree = this.getMerkleTree();
223
+ return tree[tree.length - 1];
224
+ };
225
+
226
+ /**
227
+ * Verifies that the transactions in the block match the header merkle root
228
+ * @returns {Boolean} - If the merkle roots match
229
+ */
230
+ Block.prototype.validMerkleRoot = function validMerkleRoot() {
231
+ var h = new BN(this.header.merkleRoot.toString('hex'), 'hex');
232
+ var c = new BN(this.getMerkleRoot().toString('hex'), 'hex');
233
+
234
+ if (h.cmp(c) !== 0) {
235
+ return false;
236
+ }
237
+
238
+ return true;
239
+ };
240
+
241
+ /**
242
+ * @returns {Buffer} - The little endian hash buffer of the header
243
+ */
244
+ Block.prototype._getHash = function () {
245
+ return this.header._getHash();
246
+ };
247
+
248
+ var idProperty = {
249
+ configurable: false,
250
+ enumerable: true,
251
+ /**
252
+ * @returns {string} - The big endian hash buffer of the header
253
+ */
254
+ get: function () {
255
+ if (!this._id) {
256
+ this._id = this.header.id;
257
+ }
258
+ return this._id;
259
+ },
260
+ set: _.noop,
261
+ };
262
+ Object.defineProperty(Block.prototype, 'id', idProperty);
263
+ Object.defineProperty(Block.prototype, 'hash', idProperty);
264
+
265
+ /**
266
+ * @returns {string} - A string formatted for the console
267
+ */
268
+ Block.prototype.inspect = function inspect() {
269
+ return '<Block ' + this.id + '>';
270
+ };
271
+
272
+ Block.Values = {
273
+ START_OF_BLOCK: 8, // Start of block in raw block data
274
+ NULL_HASH: Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex'),
275
+ };
276
+
277
+ module.exports = Block;
@@ -0,0 +1,295 @@
1
+ 'use strict';
2
+
3
+ var _ = require('../util/_');
4
+ var BN = require('../crypto/bn');
5
+ var BufferReader = require('../encoding/bufferreader');
6
+ var BufferWriter = require('../encoding/bufferwriter');
7
+ var Hash = require('../crypto/hash');
8
+ var $ = require('../util/preconditions');
9
+
10
+ var GENESIS_BITS = 0x1d00ffff;
11
+
12
+ /**
13
+ * Instantiate a BlockHeader from a Buffer, JSON object, or Object with
14
+ * the properties of the BlockHeader
15
+ *
16
+ * @param {*} - A Buffer, JSON string, or Object
17
+ * @returns {BlockHeader} - An instance of block header
18
+ * @constructor
19
+ */
20
+ var BlockHeader = function BlockHeader(arg) {
21
+ if (!(this instanceof BlockHeader)) {
22
+ return new BlockHeader(arg);
23
+ }
24
+ var info = BlockHeader._from(arg);
25
+ this.version = info.version;
26
+ this.prevHash = info.prevHash;
27
+ this.merkleRoot = info.merkleRoot;
28
+ this.time = info.time;
29
+ this.timestamp = info.time;
30
+ this.bits = info.bits;
31
+ this.nonce = info.nonce;
32
+
33
+ if (info.hash) {
34
+ $.checkState(
35
+ this.hash === info.hash,
36
+ 'Argument object hash property does not match block hash.',
37
+ );
38
+ }
39
+
40
+ return this;
41
+ };
42
+
43
+ /**
44
+ * @param {*} - A Buffer, JSON string or Object
45
+ * @returns {Object} - An object representing block header data
46
+ * @throws {TypeError} - If the argument was not recognized
47
+ * @private
48
+ */
49
+ BlockHeader._from = function _from(arg) {
50
+ var info = {};
51
+ if (Buffer.isBuffer(arg)) {
52
+ info = BlockHeader._fromBufferReader(BufferReader(arg));
53
+ } else if (_.isObject(arg)) {
54
+ info = BlockHeader._fromObject(arg);
55
+ } else {
56
+ throw new TypeError('Unrecognized argument for BlockHeader');
57
+ }
58
+ return info;
59
+ };
60
+
61
+ /**
62
+ * @param {Object} - A JSON string
63
+ * @returns {Object} - An object representing block header data
64
+ * @private
65
+ */
66
+ BlockHeader._fromObject = function _fromObject(data) {
67
+ $.checkArgument(data, 'data is required');
68
+ var prevHash = data.prevHash;
69
+ var merkleRoot = data.merkleRoot;
70
+ if (_.isString(data.prevHash)) {
71
+ prevHash = Buffer.from(data.prevHash, 'hex').reverse();
72
+ }
73
+ if (_.isString(data.merkleRoot)) {
74
+ merkleRoot = Buffer.from(data.merkleRoot, 'hex').reverse();
75
+ }
76
+ var info = {
77
+ hash: data.hash,
78
+ version: data.version,
79
+ prevHash: prevHash,
80
+ merkleRoot: merkleRoot,
81
+ time: data.time,
82
+ timestamp: data.time,
83
+ bits: data.bits,
84
+ nonce: data.nonce,
85
+ };
86
+ return info;
87
+ };
88
+
89
+ /**
90
+ * @param {Object} - A plain JavaScript object
91
+ * @returns {BlockHeader} - An instance of block header
92
+ */
93
+ BlockHeader.fromObject = function fromObject(obj) {
94
+ var info = BlockHeader._fromObject(obj);
95
+ return new BlockHeader(info);
96
+ };
97
+
98
+ /**
99
+ * @param {Binary} - Raw block binary data or buffer
100
+ * @returns {BlockHeader} - An instance of block header
101
+ */
102
+ BlockHeader.fromRawBlock = function fromRawBlock(data) {
103
+ if (!Buffer.isBuffer(data)) {
104
+ data = Buffer.from(data, 'binary');
105
+ }
106
+ var br = BufferReader(data);
107
+ br.pos = BlockHeader.Constants.START_OF_HEADER;
108
+ var info = BlockHeader._fromBufferReader(br);
109
+ return new BlockHeader(info);
110
+ };
111
+
112
+ /**
113
+ * @param {Buffer} - A buffer of the block header
114
+ * @returns {BlockHeader} - An instance of block header
115
+ */
116
+ BlockHeader.fromBuffer = function fromBuffer(buf) {
117
+ var info = BlockHeader._fromBufferReader(BufferReader(buf));
118
+ return new BlockHeader(info);
119
+ };
120
+
121
+ /**
122
+ * @param {string} - A hex encoded buffer of the block header
123
+ * @returns {BlockHeader} - An instance of block header
124
+ */
125
+ BlockHeader.fromString = function fromString(str) {
126
+ var buf = Buffer.from(str, 'hex');
127
+ return BlockHeader.fromBuffer(buf);
128
+ };
129
+
130
+ /**
131
+ * @param {BufferReader} - A BufferReader of the block header
132
+ * @returns {Object} - An object representing block header data
133
+ * @private
134
+ */
135
+ BlockHeader._fromBufferReader = function _fromBufferReader(br) {
136
+ var info = {};
137
+ info.version = br.readInt32LE();
138
+ info.prevHash = br.read(32);
139
+ info.merkleRoot = br.read(32);
140
+ info.time = br.readUInt32LE();
141
+ info.bits = br.readUInt32LE();
142
+ info.nonce = br.readUInt32LE();
143
+ return info;
144
+ };
145
+
146
+ /**
147
+ * @param {BufferReader} - A BufferReader of the block header
148
+ * @returns {BlockHeader} - An instance of block header
149
+ */
150
+ BlockHeader.fromBufferReader = function fromBufferReader(br) {
151
+ var info = BlockHeader._fromBufferReader(br);
152
+ return new BlockHeader(info);
153
+ };
154
+
155
+ /**
156
+ * @returns {Object} - A plain object of the BlockHeader
157
+ */
158
+ BlockHeader.prototype.toObject = BlockHeader.prototype.toJSON = function toObject() {
159
+ return {
160
+ hash: this.hash,
161
+ version: this.version,
162
+ prevHash: Buffer.from(this.prevHash).reverse().toString('hex'),
163
+ merkleRoot: Buffer.from(this.merkleRoot).reverse().toString('hex'),
164
+ time: this.time,
165
+ bits: this.bits,
166
+ nonce: this.nonce,
167
+ };
168
+ };
169
+
170
+ /**
171
+ * @returns {Buffer} - A Buffer of the BlockHeader
172
+ */
173
+ BlockHeader.prototype.toBuffer = function toBuffer() {
174
+ return this.toBufferWriter().concat();
175
+ };
176
+
177
+ /**
178
+ * @returns {string} - A hex encoded string of the BlockHeader
179
+ */
180
+ BlockHeader.prototype.toString = function toString() {
181
+ return this.toBuffer().toString('hex');
182
+ };
183
+
184
+ /**
185
+ * @param {BufferWriter} - An existing instance BufferWriter
186
+ * @returns {BufferWriter} - An instance of BufferWriter representation of the BlockHeader
187
+ */
188
+ BlockHeader.prototype.toBufferWriter = function toBufferWriter(bw) {
189
+ if (!bw) {
190
+ bw = new BufferWriter();
191
+ }
192
+ bw.writeInt32LE(this.version);
193
+ bw.write(this.prevHash);
194
+ bw.write(this.merkleRoot);
195
+ bw.writeUInt32LE(this.time);
196
+ bw.writeUInt32LE(this.bits);
197
+ bw.writeUInt32LE(this.nonce);
198
+ return bw;
199
+ };
200
+
201
+ /**
202
+ * Returns the target difficulty for this block
203
+ * @param {Number} bits
204
+ * @returns {BN} An instance of BN with the decoded difficulty bits
205
+ */
206
+ BlockHeader.prototype.getTargetDifficulty = function getTargetDifficulty(bits) {
207
+ bits = bits || this.bits;
208
+
209
+ var target = new BN(bits & 0xffffff);
210
+ var mov = 8 * ((bits >>> 24) - 3);
211
+ while (mov-- > 0) {
212
+ target = target.mul(new BN(2));
213
+ }
214
+ return target;
215
+ };
216
+
217
+ /**
218
+ * @link https://en.bitcoin.it/wiki/Difficulty
219
+ * @return {Number}
220
+ */
221
+ BlockHeader.prototype.getDifficulty = function getDifficulty() {
222
+ var difficulty1TargetBN = this.getTargetDifficulty(GENESIS_BITS).mul(new BN(Math.pow(10, 8)));
223
+ var currentTargetBN = this.getTargetDifficulty();
224
+
225
+ var difficultyString = difficulty1TargetBN.div(currentTargetBN).toString(10);
226
+ var decimalPos = difficultyString.length - 8;
227
+ difficultyString =
228
+ difficultyString.slice(0, decimalPos) + '.' + difficultyString.slice(decimalPos);
229
+
230
+ return parseFloat(difficultyString);
231
+ };
232
+
233
+ /**
234
+ * @returns {Buffer} - The little endian hash buffer of the header
235
+ */
236
+ BlockHeader.prototype._getHash = function hash() {
237
+ var buf = this.toBuffer();
238
+ return Hash.sha256sha256(buf);
239
+ };
240
+
241
+ var idProperty = {
242
+ configurable: false,
243
+ enumerable: true,
244
+ /**
245
+ * @returns {string} - The big endian hash buffer of the header
246
+ */
247
+ get: function () {
248
+ if (!this._id) {
249
+ this._id = BufferReader(this._getHash()).readReverse().toString('hex');
250
+ }
251
+ return this._id;
252
+ },
253
+ set: _.noop,
254
+ };
255
+ Object.defineProperty(BlockHeader.prototype, 'id', idProperty);
256
+ Object.defineProperty(BlockHeader.prototype, 'hash', idProperty);
257
+
258
+ /**
259
+ * @returns {Boolean} - If timestamp is not too far in the future
260
+ */
261
+ BlockHeader.prototype.validTimestamp = function validTimestamp() {
262
+ var currentTime = Math.round(new Date().getTime() / 1000);
263
+ if (this.time > currentTime + BlockHeader.Constants.MAX_TIME_OFFSET) {
264
+ return false;
265
+ }
266
+ return true;
267
+ };
268
+
269
+ /**
270
+ * @returns {Boolean} - If the proof-of-work hash satisfies the target difficulty
271
+ */
272
+ BlockHeader.prototype.validProofOfWork = function validProofOfWork() {
273
+ var pow = new BN(this.id, 'hex');
274
+ var target = this.getTargetDifficulty();
275
+
276
+ if (pow.cmp(target) > 0) {
277
+ return false;
278
+ }
279
+ return true;
280
+ };
281
+
282
+ /**
283
+ * @returns {string} - A string formatted for the console
284
+ */
285
+ BlockHeader.prototype.inspect = function inspect() {
286
+ return '<BlockHeader ' + this.id + '>';
287
+ };
288
+
289
+ BlockHeader.Constants = {
290
+ START_OF_HEADER: 8, // Start buffer position in raw block data
291
+ MAX_TIME_OFFSET: 2 * 60 * 60, // The max a timestamp can be in the future
292
+ LARGEST_HASH: new BN('10000000000000000000000000000000000000000000000000000000000000000', 'hex'),
293
+ };
294
+
295
+ module.exports = BlockHeader;
@@ -0,0 +1,4 @@
1
+ module.exports = require('./block');
2
+
3
+ module.exports.BlockHeader = require('./blockheader');
4
+ module.exports.MerkleBlock = require('./merkleblock');