@btc-vision/bitcoin 7.0.0-beta.0 → 7.0.0-beta.1

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 (116) hide show
  1. package/README.md +112 -13
  2. package/benchmark-compare/BENCHMARK.md +74 -59
  3. package/benchmark-compare/compare.bench.ts +249 -96
  4. package/benchmark-compare/harness.ts +23 -25
  5. package/benchmark-compare/package.json +1 -0
  6. package/browser/address.d.ts +4 -4
  7. package/browser/address.d.ts.map +1 -1
  8. package/browser/chunks/{psbt-parallel-B-dfm5GZ.js → psbt-parallel-jZ6QcCnM.js} +3128 -2731
  9. package/browser/index.d.ts +1 -1
  10. package/browser/index.d.ts.map +1 -1
  11. package/browser/index.js +603 -585
  12. package/browser/io/base58check.d.ts +1 -25
  13. package/browser/io/base58check.d.ts.map +1 -1
  14. package/browser/io/base64.d.ts.map +1 -1
  15. package/browser/networks.d.ts +1 -0
  16. package/browser/networks.d.ts.map +1 -1
  17. package/browser/payments/bip341.d.ts +17 -0
  18. package/browser/payments/bip341.d.ts.map +1 -1
  19. package/browser/payments/index.d.ts +3 -2
  20. package/browser/payments/index.d.ts.map +1 -1
  21. package/browser/payments/p2mr.d.ts +169 -0
  22. package/browser/payments/p2mr.d.ts.map +1 -0
  23. package/browser/payments/types.d.ts +11 -1
  24. package/browser/payments/types.d.ts.map +1 -1
  25. package/browser/psbt/bip371.d.ts +30 -0
  26. package/browser/psbt/bip371.d.ts.map +1 -1
  27. package/browser/psbt/psbtutils.d.ts +1 -0
  28. package/browser/psbt/psbtutils.d.ts.map +1 -1
  29. package/browser/psbt.d.ts.map +1 -1
  30. package/browser/workers/index.js +9 -9
  31. package/build/address.d.ts +4 -4
  32. package/build/address.d.ts.map +1 -1
  33. package/build/address.js +11 -1
  34. package/build/address.js.map +1 -1
  35. package/build/index.d.ts +1 -1
  36. package/build/index.d.ts.map +1 -1
  37. package/build/index.js.map +1 -1
  38. package/build/io/base58check.d.ts +1 -25
  39. package/build/io/base58check.d.ts.map +1 -1
  40. package/build/io/base58check.js +1 -31
  41. package/build/io/base58check.js.map +1 -1
  42. package/build/io/base64.d.ts.map +1 -1
  43. package/build/io/base64.js +3 -0
  44. package/build/io/base64.js.map +1 -1
  45. package/build/networks.d.ts +1 -0
  46. package/build/networks.d.ts.map +1 -1
  47. package/build/networks.js +12 -0
  48. package/build/networks.js.map +1 -1
  49. package/build/payments/bip341.d.ts +17 -0
  50. package/build/payments/bip341.d.ts.map +1 -1
  51. package/build/payments/bip341.js +32 -1
  52. package/build/payments/bip341.js.map +1 -1
  53. package/build/payments/index.d.ts +3 -2
  54. package/build/payments/index.d.ts.map +1 -1
  55. package/build/payments/index.js +2 -1
  56. package/build/payments/index.js.map +1 -1
  57. package/build/payments/p2mr.d.ts +178 -0
  58. package/build/payments/p2mr.d.ts.map +1 -0
  59. package/build/payments/p2mr.js +555 -0
  60. package/build/payments/p2mr.js.map +1 -0
  61. package/build/payments/types.d.ts +11 -1
  62. package/build/payments/types.d.ts.map +1 -1
  63. package/build/payments/types.js +1 -0
  64. package/build/payments/types.js.map +1 -1
  65. package/build/psbt/bip371.d.ts +30 -0
  66. package/build/psbt/bip371.d.ts.map +1 -1
  67. package/build/psbt/bip371.js +80 -15
  68. package/build/psbt/bip371.js.map +1 -1
  69. package/build/psbt/psbtutils.d.ts +1 -0
  70. package/build/psbt/psbtutils.d.ts.map +1 -1
  71. package/build/psbt/psbtutils.js +2 -0
  72. package/build/psbt/psbtutils.js.map +1 -1
  73. package/build/psbt.d.ts.map +1 -1
  74. package/build/psbt.js +3 -2
  75. package/build/psbt.js.map +1 -1
  76. package/build/pubkey.js +1 -1
  77. package/build/pubkey.js.map +1 -1
  78. package/build/tsconfig.build.tsbuildinfo +1 -1
  79. package/documentation/README.md +122 -0
  80. package/documentation/address.md +820 -0
  81. package/documentation/block.md +679 -0
  82. package/documentation/crypto.md +461 -0
  83. package/documentation/ecc.md +584 -0
  84. package/documentation/errors.md +656 -0
  85. package/documentation/io.md +942 -0
  86. package/documentation/networks.md +625 -0
  87. package/documentation/p2mr.md +380 -0
  88. package/documentation/payments.md +1485 -0
  89. package/documentation/psbt.md +1400 -0
  90. package/documentation/script.md +730 -0
  91. package/documentation/taproot.md +670 -0
  92. package/documentation/transaction.md +943 -0
  93. package/documentation/types.md +587 -0
  94. package/documentation/workers.md +1007 -0
  95. package/eslint.config.js +3 -0
  96. package/package.json +17 -14
  97. package/src/address.ts +22 -10
  98. package/src/index.ts +1 -0
  99. package/src/io/base58check.ts +1 -35
  100. package/src/io/base64.ts +5 -0
  101. package/src/networks.ts +13 -0
  102. package/src/payments/bip341.ts +36 -1
  103. package/src/payments/index.ts +4 -0
  104. package/src/payments/p2mr.ts +660 -0
  105. package/src/payments/types.ts +12 -0
  106. package/src/psbt/bip371.ts +84 -13
  107. package/src/psbt/psbtutils.ts +2 -0
  108. package/src/psbt.ts +4 -2
  109. package/src/pubkey.ts +1 -1
  110. package/test/bitcoin.core.spec.ts +1 -1
  111. package/test/fixtures/p2mr.json +270 -0
  112. package/test/integration/taproot.spec.ts +7 -3
  113. package/test/opnetTestnet.spec.ts +302 -0
  114. package/test/payments.spec.ts +3 -1
  115. package/test/psbt.spec.ts +297 -2
  116. package/test/tsconfig.json +2 -2
@@ -0,0 +1,679 @@
1
+ # Block
2
+
3
+ The `Block` class represents a Bitcoin block, including its 80-byte header and optional array of transactions. It provides methods for parsing raw block data, computing block hashes and IDs, validating proof-of-work, verifying merkle roots, and handling SegWit witness commitments (BIP 141).
4
+
5
+ ## Overview
6
+
7
+ | Property | Value |
8
+ |----------|-------|
9
+ | Header size | 80 bytes |
10
+ | Hash algorithm | Double SHA-256 (`hash256`) |
11
+ | Block ID format | Reversed hash as hex (matches block explorers) |
12
+ | Witness commitment | BIP 141 (`OP_RETURN` with prefix `0x6a24aa21a9ed`) |
13
+ | Weight formula | `base_size * 3 + total_size` |
14
+
15
+ ---
16
+
17
+ ## Installation
18
+
19
+ ```typescript
20
+ import { Block } from '@btc-vision/bitcoin';
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Block Header Structure
26
+
27
+ Every Bitcoin block begins with an 80-byte header containing six fields, serialized in the following order:
28
+
29
+ | Field | Type | Size | Description |
30
+ |-------|------|------|-------------|
31
+ | `version` | `int32le` | 4 bytes | Block version number (signed, little-endian) |
32
+ | `prevHash` | `Bytes32` | 32 bytes | Hash of the previous block header |
33
+ | `merkleRoot` | `Bytes32` | 32 bytes | Merkle root of the block's transactions |
34
+ | `timestamp` | `uint32le` | 4 bytes | Block timestamp as Unix epoch seconds |
35
+ | `bits` | `uint32le` | 4 bytes | Compact target threshold for proof-of-work |
36
+ | `nonce` | `uint32le` | 4 bytes | Nonce value iterated during mining |
37
+
38
+ After the header, a full block contains a varint transaction count followed by the serialized transactions.
39
+
40
+ ```
41
+ [version:4][prevHash:32][merkleRoot:32][timestamp:4][bits:4][nonce:4][txCount:varint][tx0][tx1]...[txN]
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Class: Block
47
+
48
+ ```typescript
49
+ class Block {
50
+ // Header fields
51
+ version: number;
52
+ prevHash?: Bytes32;
53
+ merkleRoot?: Bytes32;
54
+ timestamp: number;
55
+ bits: number;
56
+ nonce: number;
57
+
58
+ // Body
59
+ transactions?: Transaction[];
60
+
61
+ // Witness (BIP 141)
62
+ witnessCommit?: Bytes32;
63
+
64
+ // Static methods
65
+ static fromBuffer(buffer: Uint8Array): Block;
66
+ static fromHex(hex: string): Block;
67
+ static calculateTarget(bits: number): Bytes32;
68
+ static calculateMerkleRoot(transactions: Transaction[], forWitness?: boolean): Bytes32;
69
+
70
+ // Instance methods
71
+ getHash(): Bytes32;
72
+ getId(): string;
73
+ getUTCDate(): Date;
74
+ getWitnessCommit(): Bytes32 | null;
75
+ hasWitnessCommit(): boolean;
76
+ hasWitness(): boolean;
77
+ weight(): number;
78
+ byteLength(headersOnly?: boolean, allowWitness?: boolean): number;
79
+ checkTxRoots(): boolean;
80
+ checkProofOfWork(): boolean;
81
+ toBuffer(headersOnly?: boolean): Uint8Array;
82
+ toHex(headersOnly?: boolean): string;
83
+ }
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Instance Properties
89
+
90
+ | Property | Type | Default | Description |
91
+ |----------|------|---------|-------------|
92
+ | `version` | `number` | `1` | Block version number, interpreted as a signed 32-bit integer (little-endian). Version 2+ signals BIP 34 (height in coinbase). |
93
+ | `prevHash` | `Bytes32 \| undefined` | `undefined` | 32-byte hash of the previous block header. The genesis block uses all zeros. |
94
+ | `merkleRoot` | `Bytes32 \| undefined` | `undefined` | 32-byte merkle root computed from the double-SHA256 hashes of all transactions in the block. |
95
+ | `timestamp` | `number` | `0` | Block timestamp in Unix epoch seconds. Must be greater than the median of the last 11 blocks. |
96
+ | `bits` | `number` | `0` | Compact encoding of the target threshold. The block hash must be less than or equal to the expanded target for the proof-of-work to be valid. |
97
+ | `nonce` | `number` | `0` | 32-bit nonce value. Miners iterate this field to search for a valid proof-of-work. |
98
+ | `transactions` | `Transaction[] \| undefined` | `undefined` | Array of transactions in the block. `undefined` when only the 80-byte header was parsed. The first transaction is always the coinbase. |
99
+ | `witnessCommit` | `Bytes32 \| undefined` | `undefined` | 32-byte witness commitment extracted from the coinbase transaction's `OP_RETURN` output. Present only for SegWit blocks (BIP 141). |
100
+
101
+ ---
102
+
103
+ ## Static Methods
104
+
105
+ ### Block.fromBuffer(buffer)
106
+
107
+ Parses a `Block` from a raw `Uint8Array`. If the buffer is exactly 80 bytes, only the header fields are populated and `transactions` remains `undefined`. If the buffer is longer, the transaction data following the header is deserialized, and the witness commitment is extracted if present.
108
+
109
+ ```typescript
110
+ static fromBuffer(buffer: Uint8Array): Block;
111
+ ```
112
+
113
+ | Parameter | Type | Description |
114
+ |-----------|------|-------------|
115
+ | `buffer` | `Uint8Array` | Raw block data (minimum 80 bytes) |
116
+
117
+ **Returns:** A fully populated `Block` instance.
118
+
119
+ **Throws:** `Error` if the buffer is smaller than 80 bytes.
120
+
121
+ ```typescript
122
+ import { Block, fromHex } from '@btc-vision/bitcoin';
123
+
124
+ // Parse a header-only block (80 bytes = 160 hex chars)
125
+ const headerHex =
126
+ '020000003385c4b2a3499669987f5d04fa4127b59dbf2ee625694fa0bf08000000000000' +
127
+ 'cf52f0ed6571367818a801a169e64030d8cab1a9f17e27170a6924127e19dbb8' +
128
+ 'eba43e54ffff001d12052ce0';
129
+ const block = Block.fromBuffer(fromHex(headerHex));
130
+
131
+ console.log(block.version); // 2
132
+ console.log(block.timestamp); // 1413391595
133
+ console.log(block.transactions); // undefined (header only)
134
+ ```
135
+
136
+ ---
137
+
138
+ ### Block.fromHex(hex)
139
+
140
+ Convenience wrapper around `fromBuffer` that accepts a hex string instead of a `Uint8Array`.
141
+
142
+ ```typescript
143
+ static fromHex(hex: string): Block;
144
+ ```
145
+
146
+ | Parameter | Type | Description |
147
+ |-----------|------|-------------|
148
+ | `hex` | `string` | Hexadecimal representation of the block |
149
+
150
+ **Returns:** A fully populated `Block` instance.
151
+
152
+ ```typescript
153
+ import { Block } from '@btc-vision/bitcoin';
154
+
155
+ const block = Block.fromHex('020000003385c4b2a349...');
156
+ console.log(block.version); // 2
157
+ ```
158
+
159
+ ---
160
+
161
+ ### Block.calculateTarget(bits)
162
+
163
+ Expands the compact `bits` field from the block header into the full 32-byte target threshold. The compact format encodes the target as a 3-byte mantissa with a 1-byte exponent.
164
+
165
+ ```typescript
166
+ static calculateTarget(bits: number): Bytes32;
167
+ ```
168
+
169
+ | Parameter | Type | Description |
170
+ |-----------|------|-------------|
171
+ | `bits` | `number` | Compact bits value from the block header |
172
+
173
+ **Returns:** 32-byte target threshold as `Bytes32`.
174
+
175
+ The encoding works as follows:
176
+ - The top byte `(bits >> 24)` is the exponent.
177
+ - The lower 3 bytes `(bits & 0x007fffff)` are the mantissa.
178
+ - The target is `mantissa * 2^(8 * (exponent - 3))`.
179
+
180
+ ```typescript
181
+ import { Block } from '@btc-vision/bitcoin';
182
+ import { toHex } from '@btc-vision/bitcoin';
183
+
184
+ // Bitcoin mainnet difficulty 1 target
185
+ const target = Block.calculateTarget(0x1d00ffff);
186
+ console.log(toHex(target));
187
+ // '00000000ffff0000000000000000000000000000000000000000000000000000'
188
+ ```
189
+
190
+ ---
191
+
192
+ ### Block.calculateMerkleRoot(transactions, forWitness?)
193
+
194
+ Computes the merkle root from an array of transactions. When `forWitness` is `true`, computes the witness merkle root used in BIP 141 witness commitments by hashing with witness data and combining with the coinbase witness nonce.
195
+
196
+ ```typescript
197
+ static calculateMerkleRoot(transactions: Transaction[], forWitness?: boolean): Bytes32;
198
+ ```
199
+
200
+ | Parameter | Type | Description |
201
+ |-----------|------|-------------|
202
+ | `transactions` | `Transaction[]` | Array of transactions |
203
+ | `forWitness` | `boolean \| undefined` | If `true`, calculate the witness merkle root |
204
+
205
+ **Returns:** 32-byte merkle root as `Bytes32`.
206
+
207
+ **Throws:**
208
+ - `TypeError` if `transactions` is empty or not an array.
209
+ - `TypeError` if `forWitness` is `true` but the coinbase has no witness data.
210
+
211
+ ```typescript
212
+ import { Block } from '@btc-vision/bitcoin';
213
+ import { toHex } from '@btc-vision/bitcoin';
214
+
215
+ const block = Block.fromHex(fullBlockHex);
216
+ const merkleRoot = Block.calculateMerkleRoot(block.transactions!);
217
+ console.log(toHex(merkleRoot)); // matches block.merkleRoot
218
+ ```
219
+
220
+ ---
221
+
222
+ ## Instance Methods
223
+
224
+ ### block.getHash()
225
+
226
+ Computes the double-SHA256 hash of the 80-byte block header. This is the raw 32-byte hash in internal byte order (little-endian).
227
+
228
+ ```typescript
229
+ getHash(): Bytes32;
230
+ ```
231
+
232
+ **Returns:** 32-byte block hash as `Bytes32`.
233
+
234
+ ```typescript
235
+ import { Block } from '@btc-vision/bitcoin';
236
+ import { toHex } from '@btc-vision/bitcoin';
237
+
238
+ const block = Block.fromHex(blockHex);
239
+ const hash = block.getHash();
240
+ console.log(toHex(hash));
241
+ // '55388f8f9b326bd0b8e50fbe44c1903d4be14febcfad4dffa50c846c00000000'
242
+ ```
243
+
244
+ ---
245
+
246
+ ### block.getId()
247
+
248
+ Returns the block hash as a hex string in reversed byte order, matching the format used by block explorers and Bitcoin RPC.
249
+
250
+ ```typescript
251
+ getId(): string;
252
+ ```
253
+
254
+ **Returns:** Block ID as a hex string.
255
+
256
+ The difference between `getHash()` and `getId()` is byte order. Bitcoin displays block hashes with the bytes reversed from the internal representation.
257
+
258
+ ```typescript
259
+ import { Block } from '@btc-vision/bitcoin';
260
+
261
+ const block = Block.fromHex(blockHex);
262
+ console.log(block.getId());
263
+ // '000000006c840ca5ff4dadcfeb4fe14b3d90c144be0fe5b8d06b329b8f8f3855'
264
+ ```
265
+
266
+ ---
267
+
268
+ ### block.getWitnessCommit()
269
+
270
+ Extracts the witness commitment hash from the coinbase transaction. The witness commitment is stored in an `OP_RETURN` output of the coinbase transaction, prefixed with `0x6a24aa21a9ed`. If multiple outputs match, the one with the highest index is used.
271
+
272
+ ```typescript
273
+ getWitnessCommit(): Bytes32 | null;
274
+ ```
275
+
276
+ **Returns:** 32-byte witness commitment, or `null` if the block has no witness commitment.
277
+
278
+ ```typescript
279
+ import { Block } from '@btc-vision/bitcoin';
280
+ import { toHex } from '@btc-vision/bitcoin';
281
+
282
+ const block = Block.fromHex(segwitBlockHex);
283
+ const commit = block.getWitnessCommit();
284
+ if (commit) {
285
+ console.log(toHex(commit)); // 32-byte witness commitment
286
+ }
287
+ ```
288
+
289
+ ---
290
+
291
+ ### block.hasWitnessCommit()
292
+
293
+ Checks whether the block contains a witness commitment, either from the already-set `witnessCommit` property or by scanning the coinbase transaction outputs.
294
+
295
+ ```typescript
296
+ hasWitnessCommit(): boolean;
297
+ ```
298
+
299
+ **Returns:** `true` if a witness commitment is present.
300
+
301
+ ---
302
+
303
+ ### block.hasWitness()
304
+
305
+ Checks whether any transaction in the block contains witness data.
306
+
307
+ ```typescript
308
+ hasWitness(): boolean;
309
+ ```
310
+
311
+ **Returns:** `true` if any transaction has non-empty witness fields. Returns `false` if `transactions` is `undefined`.
312
+
313
+ ---
314
+
315
+ ### block.checkProofOfWork()
316
+
317
+ Validates the block's proof-of-work by comparing the block hash against the target threshold derived from the `bits` field. The block hash (in reversed byte order) must be less than or equal to the target.
318
+
319
+ ```typescript
320
+ checkProofOfWork(): boolean;
321
+ ```
322
+
323
+ **Returns:** `true` if the block hash satisfies the target difficulty.
324
+
325
+ ```typescript
326
+ import { Block } from '@btc-vision/bitcoin';
327
+
328
+ const block = Block.fromHex(blockHex);
329
+
330
+ if (block.checkProofOfWork()) {
331
+ console.log('Block has valid proof-of-work');
332
+ } else {
333
+ console.log('Invalid proof-of-work');
334
+ }
335
+ ```
336
+
337
+ ---
338
+
339
+ ### block.checkTxRoots()
340
+
341
+ Validates both the transaction merkle root and the witness commitment (if present). Returns `false` if the block has witness data in its transactions but no witness commitment in the coinbase.
342
+
343
+ ```typescript
344
+ checkTxRoots(): boolean;
345
+ ```
346
+
347
+ **Returns:** `true` if the merkle root and witness commitment (when applicable) are valid.
348
+
349
+ | Throws | Condition |
350
+ |--------|-----------|
351
+ | `TypeError` | Block has no `transactions` array (header-only block). Message: `"Cannot compute merkle root for zero transactions"` |
352
+ | `TypeError` | Block has no `merkleRoot` set. Message: `"Block merkleRoot is required"` |
353
+
354
+ ```typescript
355
+ import { Block } from '@btc-vision/bitcoin';
356
+
357
+ const block = Block.fromHex(fullBlockHex);
358
+ console.log(block.checkTxRoots()); // true for valid blocks
359
+ ```
360
+
361
+ ---
362
+
363
+ ### block.weight()
364
+
365
+ Calculates the block weight as defined by BIP 141. Weight is used for block size limits in SegWit (maximum 4,000,000 weight units).
366
+
367
+ ```typescript
368
+ weight(): number;
369
+ ```
370
+
371
+ **Returns:** Block weight in weight units.
372
+
373
+ **Formula:** `weight = base_size * 3 + total_size`
374
+
375
+ Where `base_size` is the serialized size without witness data, and `total_size` includes witness data.
376
+
377
+ ---
378
+
379
+ ### block.byteLength(headersOnly?, allowWitness?)
380
+
381
+ Calculates the serialized byte length of the block.
382
+
383
+ ```typescript
384
+ byteLength(headersOnly?: boolean, allowWitness?: boolean): number;
385
+ ```
386
+
387
+ | Parameter | Type | Default | Description |
388
+ |-----------|------|---------|-------------|
389
+ | `headersOnly` | `boolean \| undefined` | `undefined` | If `true`, returns 80 (header size only) |
390
+ | `allowWitness` | `boolean` | `true` | If `true`, includes witness data in the calculation |
391
+
392
+ **Returns:** Byte length of the serialized block.
393
+
394
+ ```typescript
395
+ const block = Block.fromHex(fullBlockHex);
396
+
397
+ console.log(block.byteLength(true)); // 80 (header only)
398
+ console.log(block.byteLength(false, false)); // stripped size (no witness)
399
+ console.log(block.byteLength(false, true)); // total size (with witness)
400
+ ```
401
+
402
+ ---
403
+
404
+ ### block.getUTCDate()
405
+
406
+ Converts the block's `timestamp` field to a JavaScript `Date` object.
407
+
408
+ ```typescript
409
+ getUTCDate(): Date;
410
+ ```
411
+
412
+ **Returns:** `Date` object representing the block time in UTC.
413
+
414
+ ```typescript
415
+ const block = Block.fromHex(blockHex);
416
+ console.log(block.getUTCDate().toISOString());
417
+ // '2014-10-15T19:33:15.000Z'
418
+ ```
419
+
420
+ ---
421
+
422
+ ### block.toBuffer(headersOnly?)
423
+
424
+ Serializes the block to a `Uint8Array`. When `headersOnly` is `true`, only the 80-byte header is serialized. Otherwise, the full block including all transactions is serialized.
425
+
426
+ ```typescript
427
+ toBuffer(headersOnly?: boolean): Uint8Array;
428
+ ```
429
+
430
+ | Parameter | Type | Description |
431
+ |-----------|------|-------------|
432
+ | `headersOnly` | `boolean \| undefined` | If `true`, serialize only the 80-byte header |
433
+
434
+ **Returns:** Serialized block data as `Uint8Array`.
435
+
436
+ **Throws:** `TypeError` if `prevHash` or `merkleRoot` is not set.
437
+
438
+ ```typescript
439
+ const block = Block.fromHex(blockHex);
440
+
441
+ const headerBytes = block.toBuffer(true); // 80 bytes
442
+ const fullBytes = block.toBuffer(); // full block
443
+ ```
444
+
445
+ ---
446
+
447
+ ### block.toHex(headersOnly?)
448
+
449
+ Serializes the block to a hex string. This is a convenience wrapper around `toBuffer()`.
450
+
451
+ ```typescript
452
+ toHex(headersOnly?: boolean): string;
453
+ ```
454
+
455
+ | Parameter | Type | Description |
456
+ |-----------|------|-------------|
457
+ | `headersOnly` | `boolean \| undefined` | If `true`, serialize only the 80-byte header |
458
+
459
+ **Returns:** Hex string representation of the block.
460
+
461
+ ```typescript
462
+ const block = Block.fromHex(blockHex);
463
+ const headerHex = block.toHex(true); // 160-character hex string (80 bytes)
464
+ const fullHex = block.toHex(); // full block as hex
465
+ ```
466
+
467
+ ---
468
+
469
+ ## Witness Commitment (BIP 141)
470
+
471
+ SegWit blocks include a witness commitment in the coinbase transaction. The commitment is stored in an `OP_RETURN` output identified by the 6-byte prefix `0x6a24aa21a9ed`:
472
+
473
+ ```
474
+ OP_RETURN OP_PUSHBYTES_36 0xaa21a9ed <32-byte witness commitment>
475
+ ```
476
+
477
+ The witness commitment is computed as:
478
+
479
+ ```
480
+ witness_root = merkle_root(witness_hashes_of_all_transactions)
481
+ witness_commitment = hash256(witness_root || witness_nonce)
482
+ ```
483
+
484
+ Where `witness_nonce` is a 32-byte value stored in the coinbase input's witness field (typically all zeros).
485
+
486
+ The `Block` class handles witness commitments automatically:
487
+
488
+ 1. `fromBuffer()` / `fromHex()` -- Extracts the witness commitment during parsing and sets `witnessCommit`.
489
+ 2. `getWitnessCommit()` -- Scans the coinbase outputs for the commitment prefix and returns the 32-byte hash.
490
+ 3. `hasWitnessCommit()` -- Checks if a witness commitment exists.
491
+ 4. `checkTxRoots()` -- Validates both the standard merkle root and the witness commitment.
492
+
493
+ ```typescript
494
+ import { Block } from '@btc-vision/bitcoin';
495
+ import { toHex } from '@btc-vision/bitcoin';
496
+
497
+ const block = Block.fromHex(segwitBlockHex);
498
+
499
+ // Check for witness data
500
+ console.log(block.hasWitness()); // true
501
+ console.log(block.hasWitnessCommit()); // true
502
+
503
+ // Access the witness commitment
504
+ if (block.witnessCommit) {
505
+ console.log(toHex(block.witnessCommit));
506
+ }
507
+
508
+ // Validate witness merkle root
509
+ console.log(block.checkTxRoots()); // true
510
+ ```
511
+
512
+ ---
513
+
514
+ ## Examples
515
+
516
+ ### Parsing a Block from Hex
517
+
518
+ ```typescript
519
+ import { Block } from '@btc-vision/bitcoin';
520
+ import { toHex } from '@btc-vision/bitcoin';
521
+
522
+ const blockHex = '020000003385c4b2a3499669987f5d04fa4127b59dbf2ee625694fa0bf' +
523
+ '08000000000000cf52f0ed6571367818a801a169e64030d8cab1a9f17e27170a6924127e' +
524
+ '19dbb8eba43e54ffff001d12052ce00101000000010000000000000000000000000000000' +
525
+ '000000000000000000000000000000000ffffffff2403089904174b6e434d696e65724251' +
526
+ '521defe5cdcf04ad543ea4eb0101000000165e0000ffffffff0100f90295000000001976a' +
527
+ '9149e8985f82bc4e0f753d0492aa8d11cc39925774088ac00000000';
528
+
529
+ const block = Block.fromHex(blockHex);
530
+
531
+ // Header fields
532
+ console.log('Version:', block.version); // 2
533
+ console.log('Timestamp:', block.timestamp); // 1413391595
534
+ console.log('Bits:', block.bits); // 486604799
535
+ console.log('Nonce:', block.nonce); // 3760981266
536
+ console.log('Previous Hash:', toHex(block.prevHash!));
537
+ console.log('Merkle Root:', toHex(block.merkleRoot!));
538
+
539
+ // Block identification
540
+ console.log('Block ID:', block.getId());
541
+ // '000000006c840ca5ff4dadcfeb4fe14b3d90c144be0fe5b8d06b329b8f8f3855'
542
+
543
+ // Date
544
+ console.log('Date:', block.getUTCDate().toISOString());
545
+ // '2014-10-15T19:33:15.000Z'
546
+ ```
547
+
548
+ ---
549
+
550
+ ### Checking Proof-of-Work
551
+
552
+ ```typescript
553
+ import { Block } from '@btc-vision/bitcoin';
554
+ import { toHex } from '@btc-vision/bitcoin';
555
+
556
+ const block = Block.fromHex(blockHex);
557
+
558
+ // Compute the target from the bits field
559
+ const target = Block.calculateTarget(block.bits);
560
+ console.log('Target:', toHex(target));
561
+ // '00000000ffff0000000000000000000000000000000000000000000000000000'
562
+
563
+ // Validate proof-of-work
564
+ if (block.checkProofOfWork()) {
565
+ console.log('Valid PoW: block hash is below target');
566
+ } else {
567
+ console.log('Invalid PoW: block hash exceeds target');
568
+ }
569
+ ```
570
+
571
+ ---
572
+
573
+ ### Accessing Transactions
574
+
575
+ ```typescript
576
+ import { Block } from '@btc-vision/bitcoin';
577
+ import { toHex } from '@btc-vision/bitcoin';
578
+
579
+ const block = Block.fromHex(fullBlockHex);
580
+
581
+ if (block.transactions) {
582
+ console.log('Transaction count:', block.transactions.length);
583
+
584
+ // The first transaction is always the coinbase
585
+ const coinbase = block.transactions[0];
586
+ console.log('Coinbase TX ID:', coinbase.getId());
587
+
588
+ // Iterate over all transactions
589
+ for (const tx of block.transactions) {
590
+ console.log('TX:', tx.getId(), 'Inputs:', tx.ins.length, 'Outputs:', tx.outs.length);
591
+ }
592
+ } else {
593
+ console.log('Header-only block, no transactions available');
594
+ }
595
+ ```
596
+
597
+ ---
598
+
599
+ ### Validating Merkle Roots
600
+
601
+ ```typescript
602
+ import { Block } from '@btc-vision/bitcoin';
603
+ import { toHex } from '@btc-vision/bitcoin';
604
+
605
+ const block = Block.fromHex(fullBlockHex);
606
+
607
+ // Recompute and compare the merkle root
608
+ const computed = Block.calculateMerkleRoot(block.transactions!);
609
+ console.log('Header merkle root:', toHex(block.merkleRoot!));
610
+ console.log('Computed merkle root:', toHex(computed));
611
+
612
+ // Validate both merkle root and witness commitment in one call
613
+ console.log('Roots valid:', block.checkTxRoots()); // true
614
+ ```
615
+
616
+ ---
617
+
618
+ ### Round-Trip Serialization
619
+
620
+ ```typescript
621
+ import { Block } from '@btc-vision/bitcoin';
622
+
623
+ const original = '020000003385c4b2a3499669...'; // full block hex
624
+ const block = Block.fromHex(original);
625
+
626
+ // Serialize back to hex
627
+ const headerOnly = block.toHex(true); // 80-byte header (160 hex chars)
628
+ const full = block.toHex(); // full block including transactions
629
+
630
+ // The round-trip preserves the original data
631
+ console.log(full === original); // true
632
+ ```
633
+
634
+ ---
635
+
636
+ ### Block Weight and Size
637
+
638
+ ```typescript
639
+ import { Block } from '@btc-vision/bitcoin';
640
+
641
+ const block = Block.fromHex(fullBlockHex);
642
+
643
+ // Header size is always 80 bytes
644
+ console.log('Header size:', block.byteLength(true)); // 80
645
+
646
+ // Stripped size excludes witness data
647
+ const strippedSize = block.byteLength(false, false);
648
+ console.log('Stripped size:', strippedSize);
649
+
650
+ // Total size includes witness data
651
+ const totalSize = block.byteLength(false, true);
652
+ console.log('Total size:', totalSize);
653
+
654
+ // Weight = stripped_size * 3 + total_size
655
+ console.log('Weight:', block.weight());
656
+ console.log('Matches formula:', block.weight() === strippedSize * 3 + totalSize); // true
657
+ ```
658
+
659
+ ---
660
+
661
+ ## Compact Target Encoding (bits)
662
+
663
+ The `bits` field uses Bitcoin's compact representation of the 256-bit target threshold. The format splits the 4-byte value into an exponent and mantissa:
664
+
665
+ ```
666
+ bits = 0xEEMMMMMMM
667
+
668
+ exponent = (bits >> 24) - 3
669
+ mantissa = bits & 0x007fffff
670
+ target[29 - exponent .. 29 - exponent + 2] = mantissa (big-endian)
671
+ ```
672
+
673
+ | bits (hex) | Expanded Target |
674
+ |------------|-----------------|
675
+ | `0x1d00ffff` | `00000000ffff0000000000000000000000000000000000000000000000000000` |
676
+ | `0x1b0404cb` | `00000000000404cb000000000000000000000000000000000000000000000000` |
677
+ | `0x1814dd04` | `000000000000000014dd04000000000000000000000000000000000000000000` |
678
+
679
+ A block's proof-of-work is valid when its double-SHA256 hash, interpreted as a 256-bit big-endian number, is less than or equal to the expanded target.