@leocuvee/turtlecoin-utils 0.0.14

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 (132) hide show
  1. package/.github/workflows/ci.yml +27 -0
  2. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  3. package/.idea/inspectionProfiles/Project_Default.xml +7 -0
  4. package/.idea/misc.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/turtlecoin-utils.iml +12 -0
  7. package/.idea/vcs.xml +6 -0
  8. package/.travis.yml +11 -0
  9. package/CONTRIBUTING.md +3 -0
  10. package/LICENSE +674 -0
  11. package/README.md +203 -0
  12. package/config.json +7 -0
  13. package/docs/.nojekyll +0 -0
  14. package/docs/CNAME +1 -0
  15. package/docs/assets/css/main.css +2321 -0
  16. package/docs/assets/images/icons.png +0 -0
  17. package/docs/assets/images/icons@2x.png +0 -0
  18. package/docs/assets/images/widgets.png +0 -0
  19. package/docs/assets/images/widgets@2x.png +0 -0
  20. package/docs/assets/js/main.js +1 -0
  21. package/docs/assets/js/search.js +3 -0
  22. package/docs/classes/address.html +964 -0
  23. package/docs/classes/addressprefix.html +431 -0
  24. package/docs/classes/block.html +965 -0
  25. package/docs/classes/blocktemplate.html +695 -0
  26. package/docs/classes/cryptonote.html +1137 -0
  27. package/docs/classes/ed25519.keypair.html +400 -0
  28. package/docs/classes/ed25519.keys.html +373 -0
  29. package/docs/classes/extranoncetag.extranoncedata.html +454 -0
  30. package/docs/classes/extranoncetag.extranoncepaymentid.html +453 -0
  31. package/docs/classes/extranoncetag.iextranonce.html +347 -0
  32. package/docs/classes/extratag.extramergedmining.html +494 -0
  33. package/docs/classes/extratag.extranonce.html +530 -0
  34. package/docs/classes/extratag.extrapadding.html +456 -0
  35. package/docs/classes/extratag.extrapublickey.html +460 -0
  36. package/docs/classes/extratag.iextratag.html +355 -0
  37. package/docs/classes/levinpacket.html +674 -0
  38. package/docs/classes/levinpayloads.handshake.html +731 -0
  39. package/docs/classes/levinpayloads.ilevinpayload.html +318 -0
  40. package/docs/classes/levinpayloads.liteblock.html +494 -0
  41. package/docs/classes/levinpayloads.missingtransactions.html +494 -0
  42. package/docs/classes/levinpayloads.newblock.html +540 -0
  43. package/docs/classes/levinpayloads.newtransactions.html +402 -0
  44. package/docs/classes/levinpayloads.peerentry.html +610 -0
  45. package/docs/classes/levinpayloads.ping.html +450 -0
  46. package/docs/classes/levinpayloads.rawblock.html +344 -0
  47. package/docs/classes/levinpayloads.requestchain.html +402 -0
  48. package/docs/classes/levinpayloads.requestgetobjects.html +448 -0
  49. package/docs/classes/levinpayloads.requesttxpool.html +402 -0
  50. package/docs/classes/levinpayloads.responsechain.html +494 -0
  51. package/docs/classes/levinpayloads.responsegetobjects.html +540 -0
  52. package/docs/classes/levinpayloads.timedsync.html +540 -0
  53. package/docs/classes/multisig.html +930 -0
  54. package/docs/classes/multisigmessage.html +694 -0
  55. package/docs/classes/parentblock.html +347 -0
  56. package/docs/classes/transaction.html +925 -0
  57. package/docs/classes/transactioninputs.coinbaseinput.html +390 -0
  58. package/docs/classes/transactioninputs.itransactioninput.html +321 -0
  59. package/docs/classes/transactioninputs.keyinput.html +459 -0
  60. package/docs/classes/transactionoutputs.itransactionoutput.html +317 -0
  61. package/docs/classes/transactionoutputs.keyoutput.html +422 -0
  62. package/docs/enums/extranoncetag.noncetagtype.html +246 -0
  63. package/docs/enums/extratag.extratagtype.html +280 -0
  64. package/docs/enums/levinprotocol.commandtype.html +391 -0
  65. package/docs/enums/transactioninputs.inputtype.html +246 -0
  66. package/docs/enums/transactionoutputs.outputtype.html +229 -0
  67. package/docs/globals.html +238 -0
  68. package/docs/index.html +271 -0
  69. package/docs/interfaces/interfaces.config.html +590 -0
  70. package/docs/interfaces/interfaces.daemonblocktemplateresponse.html +323 -0
  71. package/docs/interfaces/interfaces.generatedinput.html +304 -0
  72. package/docs/interfaces/interfaces.generatedoutput.html +285 -0
  73. package/docs/interfaces/interfaces.inputkeys.html +304 -0
  74. package/docs/interfaces/interfaces.ipreparedtransaction.html +268 -0
  75. package/docs/interfaces/interfaces.output.html +399 -0
  76. package/docs/interfaces/interfaces.preparedringsignature.html +377 -0
  77. package/docs/interfaces/interfaces.preparedtransaction.html +329 -0
  78. package/docs/interfaces/interfaces.randomoutput.html +285 -0
  79. package/docs/interfaces/interfaces.transactionrecipient.html +285 -0
  80. package/docs/interfaces/multisiginterfaces.partialkeyimage.html +277 -0
  81. package/docs/interfaces/multisiginterfaces.partialsigningkey.html +277 -0
  82. package/docs/modules/ed25519.html +195 -0
  83. package/docs/modules/extranoncetag.html +208 -0
  84. package/docs/modules/extratag.html +216 -0
  85. package/docs/modules/interfaces.html +231 -0
  86. package/docs/modules/levinpayloads.html +247 -0
  87. package/docs/modules/levinprotocol.html +191 -0
  88. package/docs/modules/multisiginterfaces.html +195 -0
  89. package/docs/modules/transactioninputs.html +208 -0
  90. package/docs/modules/transactionoutputs.html +204 -0
  91. package/index.d.ts +417 -0
  92. package/index.js +1508 -0
  93. package/lib/base58.js +220 -0
  94. package/lib/biginteger.js +1591 -0
  95. package/lib/blocktemplate.js +408 -0
  96. package/lib/crypto.js +19698 -0
  97. package/lib/mnemonic.js +1204 -0
  98. package/lib/nacl-fast-cn.js +608 -0
  99. package/lib/ringsigs.js +24262 -0
  100. package/lib/sha3.js +477 -0
  101. package/package.json +58 -0
  102. package/src/Address.ts +433 -0
  103. package/src/AddressPrefix.ts +117 -0
  104. package/src/Block.ts +556 -0
  105. package/src/BlockTemplate.ts +289 -0
  106. package/src/Common.ts +105 -0
  107. package/src/Config.ts +66 -0
  108. package/src/CryptoNote.ts +1072 -0
  109. package/src/LevinPacket.ts +366 -0
  110. package/src/Multisig.ts +600 -0
  111. package/src/MultisigMessage.ts +374 -0
  112. package/src/ParentBlock.ts +39 -0
  113. package/src/Transaction.ts +628 -0
  114. package/src/Types/ED25519.ts +187 -0
  115. package/src/Types/IExtraNonce.ts +225 -0
  116. package/src/Types/IExtraTag.ts +507 -0
  117. package/src/Types/ITransaction.ts +230 -0
  118. package/src/Types/ITransactionInput.ts +190 -0
  119. package/src/Types/ITransactionOutput.ts +108 -0
  120. package/src/Types/LevinPayloads.ts +1576 -0
  121. package/src/Types/MultisigInterfaces.ts +65 -0
  122. package/src/Types/PortableStorage.ts +289 -0
  123. package/src/Types.ts +36 -0
  124. package/src/index.ts +36 -0
  125. package/test/template.json +6 -0
  126. package/test/test.js +1457 -0
  127. package/tests/blocktemplate.json +6 -0
  128. package/tests/tests.js +215 -0
  129. package/tsconfig.json +15 -0
  130. package/tslint.json +36 -0
  131. package/typedoc.json +10 -0
  132. package/webpack.config.js +15 -0
package/src/Block.ts ADDED
@@ -0,0 +1,556 @@
1
+ // Copyright (c) 2018-2020, The TurtleCoin Developers
2
+ //
3
+ // Please see the included LICENSE file for more information.
4
+
5
+ import * as ConfigInterface from './Config';
6
+ import {Transaction} from './Transaction';
7
+ import {ParentBlock} from './ParentBlock';
8
+ import {TransactionInputs, TransactionOutputs, TurtleCoinCrypto} from './Types';
9
+ import {Reader, Writer} from 'bytestream-helper';
10
+ import Config = ConfigInterface.Interfaces.Config;
11
+
12
+ /** @ignore */
13
+ const Config = require('../config.json');
14
+
15
+ /** @ignore */
16
+ interface Cache {
17
+ blob: string;
18
+ hash: string;
19
+ longBlob: string;
20
+ longHash: string;
21
+ }
22
+
23
+ /**
24
+ * Represents a TurtleCoin Block
25
+ */
26
+ export class Block {
27
+
28
+ /**
29
+ * The size of the block in bytes
30
+ */
31
+ public get size(): number {
32
+ return this.toBuffer().length;
33
+ }
34
+
35
+ /**
36
+ * The height of the block
37
+ */
38
+ public get height(): number {
39
+ if (this.m_minerTransaction.inputs.length !== 0) {
40
+ return (this.m_minerTransaction.inputs[0] as TransactionInputs.CoinbaseInput).blockIndex;
41
+ } else {
42
+ return 0;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * The nonce of the block
48
+ */
49
+ public get nonce(): number {
50
+ const writer = new Writer();
51
+ writer.uint32_t(this.m_nonce, true);
52
+ const reader = new Reader(writer.buffer);
53
+ return reader.uint32_t().toJSNumber();
54
+ }
55
+
56
+ public set nonce(value: number) {
57
+ if (value > 0xFFFFFFFF) {
58
+ throw new Error('value exceeds uint32_t maximum');
59
+ }
60
+
61
+ const writer = new Writer();
62
+ writer.uint32_t(value);
63
+ const reader = new Reader(writer.buffer);
64
+ this.m_nonce = reader.uint32_t(true).toJSNumber();
65
+ }
66
+
67
+ /**
68
+ * The transactions hashes (non-coinbase) included in the block
69
+ */
70
+ public get transactions(): string[] {
71
+ return this.m_transactions;
72
+ }
73
+
74
+ /**
75
+ * The base transaction branch of the block
76
+ */
77
+ public get baseTransactionBranch(): string[] {
78
+ const transactions = [this.m_minerTransaction.hash].concat(this.transactions);
79
+
80
+ return TurtleCoinCrypto.tree_branch(transactions);
81
+ }
82
+
83
+ /**
84
+ * The transaction tree hash of the block
85
+ */
86
+ public get transactionTreeHash(): { hash: string, count: number } {
87
+ const transactions = [this.m_minerTransaction.hash].concat(this.transactions);
88
+
89
+ const treeHash = TurtleCoinCrypto.tree_hash(transactions);
90
+
91
+ return {hash: treeHash, count: transactions.length};
92
+ }
93
+
94
+ /**
95
+ * The merkle root of the block
96
+ */
97
+ public get merkleRoot(): string {
98
+ const writer = new Writer();
99
+
100
+ writer.varint(this.m_majorVersion);
101
+ writer.varint(this.m_minorVersion);
102
+
103
+ if (this.m_majorVersion < this.m_activateParentBlockVersion) {
104
+ writer.varint(this.m_timestamp.getTime() / 1000);
105
+ }
106
+
107
+ writer.hash(this.m_previousBlockHash);
108
+
109
+ if (this.m_majorVersion < this.m_activateParentBlockVersion) {
110
+ writer.uint32_t(this.m_nonce, true);
111
+ }
112
+
113
+ writer.hash(this.transactionTreeHash.hash);
114
+ writer.varint(this.transactionTreeHash.count);
115
+
116
+ return getBlockHash(writer.buffer);
117
+ }
118
+
119
+ /**
120
+ * The major block version
121
+ */
122
+ public get majorVersion(): number {
123
+ return this.m_majorVersion;
124
+ }
125
+
126
+ public set majorVersion(majorVersion: number) {
127
+ this.m_majorVersion = majorVersion;
128
+ }
129
+
130
+ /**
131
+ * The minor block version
132
+ */
133
+ public get minorVersion(): number {
134
+ return this.m_minorVersion;
135
+ }
136
+
137
+ public set minorVersion(minorVersion: number) {
138
+ this.m_minorVersion = minorVersion;
139
+ }
140
+
141
+ /**
142
+ * The block hash (id)
143
+ */
144
+ public get hash(): string {
145
+ const blob = this.toHashingBuffer();
146
+
147
+ if (this.m_cache.blob === blob.toString('hex') && this.m_cache.hash) {
148
+ return this.m_cache.hash;
149
+ }
150
+
151
+ this.m_cache.blob = blob.toString('hex');
152
+
153
+ this.m_cache.hash = getBlockHash(blob);
154
+
155
+ return this.m_cache.hash;
156
+ }
157
+
158
+ /**
159
+ * The block PoW hash
160
+ */
161
+ public get longHash(): string {
162
+ const blob = this.toHashingBuffer(true);
163
+
164
+ if (this.m_cache.longBlob === blob.toString('hex') && this.m_cache.longHash) {
165
+ return this.m_cache.longHash;
166
+ }
167
+
168
+ this.m_cache.longBlob = blob.toString('hex');
169
+
170
+ this.m_cache.longHash = getBlockPoWHash(blob, this.m_majorVersion);
171
+
172
+ return this.m_cache.longHash;
173
+ }
174
+
175
+ /**
176
+ * The timestamp of the block
177
+ */
178
+ public get timestamp(): Date {
179
+ return this.m_timestamp;
180
+ }
181
+
182
+ public set timestamp(timestamp: Date) {
183
+ this.m_timestamp = timestamp;
184
+ }
185
+
186
+ /**
187
+ * The previous block hash of the block
188
+ */
189
+ public get previousBlockHash(): string {
190
+ return this.m_previousBlockHash;
191
+ }
192
+
193
+ public set previousBlockHash(previousBlockHash: string) {
194
+ this.m_previousBlockHash = previousBlockHash;
195
+ }
196
+
197
+ /**
198
+ * The miner (coinbase) transaction of the block
199
+ */
200
+ public get minerTransaction(): Transaction {
201
+ return this.m_minerTransaction;
202
+ }
203
+
204
+ public set minerTransaction(minerTransaction: Transaction) {
205
+ this.m_minerTransaction = minerTransaction;
206
+ }
207
+
208
+ /**
209
+ * The parent block of the block
210
+ */
211
+ public get parentBlock(): ParentBlock {
212
+ return this.m_parentBlock;
213
+ }
214
+
215
+ public set parentBlock(parentBlock: ParentBlock) {
216
+ this.m_parentBlock = parentBlock;
217
+ }
218
+
219
+ /**
220
+ * Defines what major block version activates the use of parent blocks
221
+ */
222
+ public get activateParentBlockVersion(): number {
223
+ return this.m_activateParentBlockVersion;
224
+ }
225
+
226
+ public set activateParentBlockVersion(activateParentBlockVersion: number) {
227
+ this.m_activateParentBlockVersion = activateParentBlockVersion;
228
+ }
229
+
230
+ /**
231
+ * Creates a new instance of a block from the data supplied
232
+ * @param data the raw block data to decode
233
+ * @param [config] the configuration that may define the major block version to activate parent block usage
234
+ * @returns the new block object
235
+ */
236
+ public static from(data: Buffer | string, config?: Config): Block {
237
+ const activateParentBlockVersion =
238
+ (config && config.activateParentBlockVersion
239
+ && typeof config.activateParentBlockVersion !== 'undefined') ?
240
+ config.activateParentBlockVersion : 2;
241
+
242
+ const block = new Block();
243
+
244
+ const reader = new Reader(data);
245
+
246
+ block.m_majorVersion = reader.varint().toJSNumber();
247
+ block.m_minorVersion = reader.varint().toJSNumber();
248
+
249
+ if (block.m_majorVersion >= activateParentBlockVersion) {
250
+ block.m_previousBlockHash = reader.hash();
251
+ block.m_parentBlock.majorVersion = reader.varint().toJSNumber();
252
+ block.m_parentBlock.minorVersion = reader.varint().toJSNumber();
253
+ }
254
+
255
+ block.m_timestamp = new Date(reader.varint().toJSNumber() * 1000);
256
+
257
+ if (block.m_majorVersion >= activateParentBlockVersion) {
258
+ block.m_parentBlock.previousBlockHash = reader.hash();
259
+ } else {
260
+ block.m_previousBlockHash = reader.hash();
261
+ }
262
+
263
+ block.m_nonce = reader.uint32_t(true).toJSNumber();
264
+
265
+ if (block.m_majorVersion >= activateParentBlockVersion) {
266
+ block.m_parentBlock.transactionCount = reader.varint().toJSNumber();
267
+
268
+ const baseTransactionBranchDepth = TurtleCoinCrypto.tree_depth(block.m_parentBlock.transactionCount);
269
+
270
+ for (let i = 0; i < baseTransactionBranchDepth; i++) {
271
+ block.m_parentBlock.baseTransactionBranch.push(reader.hash());
272
+ }
273
+
274
+ block.m_parentBlock.minerTransaction.version = reader.varint().toJSNumber();
275
+ block.m_parentBlock.minerTransaction.unlockTime = reader.varint();
276
+
277
+ const p_inputs = reader.varint().toJSNumber();
278
+
279
+ for (let i = 0; i < p_inputs; i++) {
280
+ if (reader.uint8_t().toJSNumber() === TransactionInputs.InputType.COINBASE) {
281
+ block.m_parentBlock.minerTransaction.inputs.push(
282
+ new TransactionInputs.CoinbaseInput(reader.varint().toJSNumber()),
283
+ );
284
+ } else {
285
+ throw new Error('Non-coinbase input found in parent block miner transaction');
286
+ }
287
+ }
288
+
289
+ const p_outputs = reader.varint().toJSNumber();
290
+
291
+ for (let i = 0; i < p_outputs; i++) {
292
+ const amount = reader.varint();
293
+ const type = reader.uint8_t().toJSNumber();
294
+ if (type === TransactionOutputs.OutputType.KEY) {
295
+ block.m_parentBlock.minerTransaction.outputs.push(
296
+ new TransactionOutputs.KeyOutput(amount, reader.hash()),
297
+ );
298
+ } else {
299
+ throw new Error('Unknown output type detected');
300
+ }
301
+ }
302
+
303
+ const p_extraLength = reader.varint().toJSNumber();
304
+
305
+ const p_extra = reader.bytes(p_extraLength);
306
+
307
+ block.m_parentBlock.minerTransaction.parseExtra(p_extra);
308
+
309
+ if (block.m_parentBlock.minerTransaction.version >= 2) {
310
+ block.m_parentBlock.minerTransaction.ignoredField = reader.varint().toJSNumber();
311
+ }
312
+
313
+ const blockchainBranchDepth = (block.m_parentBlock.minerTransaction.mergedMining) ?
314
+ block.m_parentBlock.minerTransaction.mergedMining.depth : 0;
315
+
316
+ for (let i = 0; i < blockchainBranchDepth; i++) {
317
+ block.m_parentBlock.blockchainBranch.push(reader.hash());
318
+ }
319
+ }
320
+
321
+ block.m_minerTransaction.version = reader.varint().toJSNumber();
322
+ block.m_minerTransaction.unlockTime = reader.varint();
323
+
324
+ const inputs = reader.varint().toJSNumber();
325
+
326
+ for (let i = 0; i < inputs; i++) {
327
+ if (reader.uint8_t().toJSNumber() === TransactionInputs.InputType.COINBASE) {
328
+ block.m_minerTransaction.inputs.push(
329
+ new TransactionInputs.CoinbaseInput(reader.varint().toJSNumber()),
330
+ );
331
+ } else {
332
+ throw new Error('Non-coinbase input found in miner transaction');
333
+ }
334
+ }
335
+
336
+ const outputs = reader.varint().toJSNumber();
337
+
338
+ for (let i = 0; i < outputs; i++) {
339
+ const amount = reader.varint();
340
+ const type = reader.uint8_t().toJSNumber();
341
+ if (type === TransactionOutputs.OutputType.KEY) {
342
+ block.m_minerTransaction.outputs.push(
343
+ new TransactionOutputs.KeyOutput(amount, reader.hash()),
344
+ );
345
+ } else {
346
+ throw new Error('Unknown output type detected');
347
+ }
348
+ }
349
+
350
+ const extraLength = reader.varint().toJSNumber();
351
+
352
+ const extra = reader.bytes(extraLength);
353
+
354
+ block.m_minerTransaction.parseExtra(extra);
355
+
356
+ const txnCount = reader.varint().toJSNumber();
357
+
358
+ for (let i = 0; i < txnCount; i++) {
359
+ block.m_transactions.push(reader.hash());
360
+ }
361
+
362
+ if (reader.unreadBytes > 0) {
363
+ throw new RangeError('Unhandled data in block blob detected');
364
+ }
365
+
366
+ return block;
367
+ }
368
+
369
+ protected m_majorVersion: number = 0;
370
+ protected m_minorVersion: number = 0;
371
+ protected m_timestamp: Date = new Date();
372
+ protected m_previousBlockHash: string = ''.padStart(64, '0');
373
+ protected m_parentBlock: ParentBlock = new ParentBlock();
374
+ protected m_nonce: number = 0;
375
+ protected m_minerTransaction: Transaction = new Transaction();
376
+ protected m_transactions: string[] = [];
377
+ protected m_activateParentBlockVersion: number = Config.activateParentBlockVersion || 2;
378
+ protected m_cache: Cache = {
379
+ blob: '',
380
+ hash: '',
381
+ longBlob: '',
382
+ longHash: '',
383
+ };
384
+
385
+ /**
386
+ * Returns a Buffer representation of the block
387
+ * @returns the resulting Buffer
388
+ */
389
+ public toBuffer(): Buffer {
390
+ const writer = new Writer();
391
+
392
+ writer.varint(this.m_majorVersion);
393
+ writer.varint(this.m_minorVersion);
394
+
395
+ if (this.m_majorVersion >= this.m_activateParentBlockVersion) {
396
+ writer.hash(this.m_previousBlockHash);
397
+ writer.varint(this.m_parentBlock.majorVersion);
398
+ writer.varint(this.m_parentBlock.minorVersion);
399
+ }
400
+
401
+ writer.varint(this.m_timestamp.getTime() / 1000);
402
+
403
+ if (this.m_majorVersion >= this.m_activateParentBlockVersion) {
404
+ writer.hash(this.m_parentBlock.previousBlockHash);
405
+ } else {
406
+ writer.hash(this.m_previousBlockHash);
407
+ }
408
+
409
+ writer.uint32_t(this.m_nonce, true);
410
+
411
+ if (this.m_majorVersion >= this.m_activateParentBlockVersion) {
412
+ writer.varint(this.m_parentBlock.transactionCount);
413
+
414
+ if (Array.isArray(this.m_parentBlock.baseTransactionBranch)) {
415
+ this.m_parentBlock.baseTransactionBranch.forEach((branch) => {
416
+ writer.hash(branch);
417
+ });
418
+ } else {
419
+ writer.hash(this.m_parentBlock.baseTransactionBranch);
420
+ }
421
+
422
+ writer.write(this.m_parentBlock.minerTransaction.toBuffer(true));
423
+
424
+ if (this.m_parentBlock.minerTransaction.version >= 2) {
425
+ writer.varint(this.m_parentBlock.minerTransaction.ignoredField);
426
+ }
427
+
428
+ this.m_parentBlock.blockchainBranch.forEach((branch) => {
429
+ writer.hash(branch);
430
+ });
431
+ }
432
+
433
+ writer.write(this.m_minerTransaction.toBuffer(true));
434
+
435
+ writer.varint(this.m_transactions.length);
436
+
437
+ this.m_transactions.forEach((hash) => {
438
+ writer.hash(hash);
439
+ });
440
+
441
+ return writer.buffer;
442
+ }
443
+
444
+ /**
445
+ * Returns a hexadecimal (blob) representation of the block
446
+ * @returns the hexadecimal representation of the block
447
+ */
448
+ public toString(): string {
449
+ return this.toBuffer().toString('hex');
450
+ }
451
+
452
+ /**
453
+ * Returns a Buffer representation of the data for hashing (mining) the block
454
+ * @param [headerOnly] whether to return just the header or the full block
455
+ * @returns the hashing buffer
456
+ */
457
+ public toHashingBuffer(headerOnly: boolean = false): Buffer {
458
+ const writer = new Writer();
459
+
460
+ writer.varint(this.m_majorVersion);
461
+ writer.varint(this.m_minorVersion);
462
+
463
+ if (this.m_majorVersion >= this.m_activateParentBlockVersion) {
464
+ writer.hash(this.m_previousBlockHash);
465
+ } else {
466
+ writer.varint(this.m_timestamp.getTime() / 1000);
467
+ writer.hash(this.m_previousBlockHash);
468
+ writer.uint32_t(this.m_nonce, true);
469
+ }
470
+
471
+ writer.hash(this.transactionTreeHash.hash);
472
+
473
+ writer.varint(this.transactionTreeHash.count);
474
+
475
+ if (this.m_majorVersion >= this.m_activateParentBlockVersion) {
476
+ if (headerOnly) {
477
+ writer.clear();
478
+ }
479
+
480
+ writer.varint(this.m_parentBlock.majorVersion);
481
+ writer.varint(this.m_parentBlock.minorVersion);
482
+ writer.varint(this.m_timestamp.getTime() / 1000);
483
+ writer.hash(this.m_parentBlock.previousBlockHash);
484
+ writer.uint32_t(this.m_nonce, true);
485
+
486
+ const treeHash = TurtleCoinCrypto.tree_hash_from_branch(
487
+ this.m_parentBlock.baseTransactionBranch,
488
+ this.m_parentBlock.minerTransaction.hash,
489
+ 0,
490
+ );
491
+
492
+ writer.hash(treeHash);
493
+
494
+ writer.varint(this.m_parentBlock.transactionCount);
495
+
496
+ if (headerOnly) {
497
+ return writer.buffer;
498
+ }
499
+
500
+ this.m_parentBlock.baseTransactionBranch.forEach((branch) => {
501
+ writer.hash(branch);
502
+ });
503
+
504
+ writer.write(this.m_parentBlock.minerTransaction.toBuffer());
505
+
506
+ if (this.m_parentBlock.minerTransaction.version >= 2) {
507
+ writer.varint(this.m_parentBlock.minerTransaction.ignoredField);
508
+ }
509
+
510
+ this.m_parentBlock.blockchainBranch.forEach((branch) => {
511
+ writer.hash(branch);
512
+ });
513
+ }
514
+
515
+ return writer.buffer;
516
+ }
517
+
518
+ /**
519
+ * Returns a hexadecimal (blob) representation of the data for hashing (mining) the block
520
+ * @param [headerOnly] whether to return just the header or the full block
521
+ * @returns the hexadecimal (blob) representation of the hashing buffer
522
+ */
523
+ public toHashingString(headerOnly: boolean = false): string {
524
+ return this.toHashingBuffer(headerOnly).toString('hex');
525
+ }
526
+ }
527
+
528
+ /** @ignore */
529
+ function getBlockHash(data: Buffer): string {
530
+ const writer = new Writer();
531
+
532
+ writer.varint(data.length);
533
+ writer.write(data);
534
+
535
+ return TurtleCoinCrypto.cn_fast_hash(writer.blob);
536
+ }
537
+
538
+ /** @ignore */
539
+ function getBlockPoWHash(data: Buffer, majorVersion: number): string {
540
+ const blob = data.toString('hex');
541
+
542
+ switch (majorVersion) {
543
+ case 1:
544
+ case 2:
545
+ case 3:
546
+ return TurtleCoinCrypto.cn_slow_hash_v0(blob);
547
+ case 4:
548
+ return TurtleCoinCrypto.cn_lite_slow_hash_v1(blob);
549
+ case 5:
550
+ return TurtleCoinCrypto.cn_turtle_lite_slow_hash_v2(blob);
551
+ case 6:
552
+ return TurtleCoinCrypto.chukwa_slow_hash(blob);
553
+ default:
554
+ throw new Error('Unhandled major block version');
555
+ }
556
+ }