@btc-vision/bitcoin 6.4.10 → 6.5.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.
- package/.babelrc +13 -4
- package/.mocharc.json +13 -13
- package/.prettierrc.json +12 -12
- package/CHANGELOG.md +403 -403
- package/CONTRIBUTING.md +83 -83
- package/LICENSE +21 -21
- package/README.md +201 -201
- package/browser/chunks/crypto-C6FlKKmp.js +2006 -0
- package/browser/chunks/payments-BE4vwHhV.js +1045 -0
- package/browser/chunks/psbt-Dlosf9CT.js +3853 -0
- package/browser/chunks/script-COWGdiOo.js +318 -0
- package/browser/chunks/transaction-BiXwH2v4.js +421 -0
- package/browser/chunks/utils-BKmkTzNZ.js +759 -0
- package/browser/crypto/crypto.d.ts +1 -1
- package/browser/index.d.ts +7 -27
- package/browser/index.js +92 -2
- package/build/index.d.ts +7 -27
- package/build/index.js +2 -2
- package/cjs/package.json +3 -3
- package/gulpfile.js +42 -42
- package/package.json +153 -150
- package/src/bip66.ts +107 -107
- package/src/block.ts +233 -233
- package/src/bufferutils.ts +188 -188
- package/src/crypto.ts +108 -108
- package/src/ecc_lib.ts +94 -94
- package/src/hooks/AdvancedSignatureManager.ts +104 -104
- package/src/hooks/SignatureManager.ts +84 -84
- package/src/index.ts +83 -105
- package/src/merkle.ts +31 -31
- package/src/opcodes.ts +280 -280
- package/src/payments/bip341.ts +140 -140
- package/src/payments/embed.ts +61 -61
- package/src/payments/index.ts +172 -172
- package/src/payments/lazy.ts +28 -28
- package/src/payments/p2ms.ts +156 -156
- package/src/payments/p2op.ts +195 -195
- package/src/payments/p2pk.ts +93 -93
- package/src/payments/p2pkh.ts +214 -214
- package/src/payments/p2tr.ts +309 -309
- package/src/psbt/bip371.ts +441 -441
- package/src/push_data.ts +97 -97
- package/src/script.ts +247 -247
- package/src/script_number.ts +72 -72
- package/src/script_signature.ts +91 -91
- package/src/transaction.ts +656 -656
- package/test/address.spec.ts +155 -155
- package/test/bitcoin.core.spec.ts +212 -212
- package/test/block.spec.ts +171 -171
- package/test/bufferutils.spec.ts +450 -450
- package/test/crypto.spec.ts +49 -49
- package/test/fixtures/address.json +329 -329
- package/test/fixtures/block.json +148 -148
- package/test/fixtures/bufferutils.json +102 -102
- package/test/fixtures/core/README.md +26 -26
- package/test/fixtures/core/base58_encode_decode.json +50 -50
- package/test/fixtures/core/base58_keys_invalid.json +152 -152
- package/test/fixtures/core/base58_keys_valid.json +452 -452
- package/test/fixtures/core/blocks.json +27 -27
- package/test/fixtures/core/sig_canonical.json +7 -7
- package/test/fixtures/core/sig_noncanonical.json +33 -33
- package/test/fixtures/core/sighash.json +3505 -3505
- package/test/fixtures/core/tx_valid.json +2023 -2023
- package/test/fixtures/crypto.json +43 -43
- package/test/fixtures/ecdsa.json +217 -217
- package/test/fixtures/ecpair.json +141 -141
- package/test/fixtures/embed.json +108 -108
- package/test/fixtures/p2ms.json +434 -434
- package/test/fixtures/p2pk.json +179 -179
- package/test/fixtures/p2pkh.json +276 -276
- package/test/fixtures/p2sh.json +508 -508
- package/test/fixtures/p2tr.json +1198 -1198
- package/test/fixtures/p2wpkh.json +290 -290
- package/test/fixtures/p2wsh.json +489 -489
- package/test/fixtures/psbt.json +924 -924
- package/test/fixtures/script.json +465 -465
- package/test/fixtures/script_number.json +225 -225
- package/test/fixtures/signature.json +140 -140
- package/test/fixtures/transaction.json +916 -916
- package/test/integration/_regtest.ts +6 -6
- package/test/integration/addresses.spec.ts +142 -142
- package/test/integration/bip32.spec.ts +130 -130
- package/test/integration/blocks.spec.ts +28 -28
- package/test/integration/cltv.spec.ts +241 -241
- package/test/integration/csv.spec.ts +452 -452
- package/test/integration/payments.spec.ts +110 -110
- package/test/integration/taproot.spec.ts +663 -663
- package/test/integration/transactions.spec.ts +668 -668
- package/test/payments.spec.ts +114 -114
- package/test/payments.utils.ts +165 -165
- package/test/psbt.spec.ts +1285 -1285
- package/test/script.spec.ts +186 -186
- package/test/script_number.spec.ts +26 -26
- package/test/script_signature.spec.ts +66 -66
- package/test/transaction.spec.ts +337 -337
- package/test/ts-node-register.js +7 -7
- package/test/tsconfig.json +48 -48
- package/test/types.spec.ts +53 -53
- package/tsconfig.base.json +27 -27
- package/tsconfig.json +19 -19
- package/tsconfig.webpack.json +18 -18
- package/vite.config.browser.ts +93 -0
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/.ready +0 -0
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/.release-please-manifest.json +0 -3
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/CHANGELOG.md +0 -962
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/CONTRIBUTING.md +0 -34
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/LICENSE +0 -24
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/README.md +0 -273
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/SECURITY.md +0 -2
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/addon.gypi +0 -204
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/bin/node-gyp.js +0 -138
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/.release-please-manifest.json +0 -3
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/LICENSE +0 -28
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/data/ninja/build.ninja +0 -4
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/data/win/large-pdb-shim.cc +0 -12
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/docs/GypVsCMake.md +0 -116
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/docs/Hacking.md +0 -46
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/docs/InputFormatReference.md +0 -1080
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/docs/LanguageSpecification.md +0 -430
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/docs/README.md +0 -27
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/docs/Testing.md +0 -450
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/docs/UserDocumentation.md +0 -965
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/gyp +0 -8
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/gyp.bat +0 -5
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/gyp_main.py +0 -45
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py +0 -365
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py +0 -206
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py +0 -1272
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py +0 -1547
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py +0 -59
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py +0 -153
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py +0 -271
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +0 -574
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +0 -692
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/common.py +0 -711
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/common_test.py +0 -171
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py +0 -169
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py +0 -113
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py +0 -55
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py +0 -0
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py +0 -804
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py +0 -1173
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py +0 -1318
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py +0 -127
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py +0 -103
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +0 -461
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py +0 -89
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py +0 -57
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py +0 -2745
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +0 -3976
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py +0 -44
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +0 -2964
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +0 -67
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py +0 -1391
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py +0 -25
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/input.py +0 -3115
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/input_test.py +0 -98
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +0 -771
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +0 -1260
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py +0 -174
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +0 -61
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py +0 -373
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +0 -1938
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation_test.py +0 -53
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py +0 -302
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py +0 -3198
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py +0 -65
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/LICENSE +0 -3
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.APACHE +0 -177
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.BSD +0 -23
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/__init__.py +0 -15
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/_elffile.py +0 -108
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/_manylinux.py +0 -252
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/_musllinux.py +0 -83
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/_parser.py +0 -359
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/_structures.py +0 -61
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/_tokenizer.py +0 -192
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/markers.py +0 -252
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/metadata.py +0 -825
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/py.typed +0 -0
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/requirements.py +0 -90
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/specifiers.py +0 -1030
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/tags.py +0 -553
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/utils.py +0 -172
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pylib/packaging/version.py +0 -563
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/pyproject.toml +0 -120
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/release-please-config.json +0 -11
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/gyp/test_gyp.py +0 -261
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/Find-VisualStudio.cs +0 -250
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/build.js +0 -227
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/clean.js +0 -15
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/configure.js +0 -328
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/create-config-gypi.js +0 -150
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/download.js +0 -39
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/find-node-directory.js +0 -63
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/find-python.js +0 -310
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/find-visualstudio.js +0 -590
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/install.js +0 -415
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/list.js +0 -26
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/log.js +0 -168
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/node-gyp.js +0 -188
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/process-release.js +0 -146
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/rebuild.js +0 -12
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/remove.js +0 -43
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/lib/util.js +0 -81
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/macOS_Catalina_acid_test.sh +0 -21
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/package.json +0 -51
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/release-please-config.json +0 -40
- package/.yarn/unplugged/node-gyp-npm-10.2.0-cad1109948/node_modules/node-gyp/src/win_delay_load_hook.cc +0 -39
- package/browser/index.js.LICENSE.txt +0 -14
- package/browser/ops.d.ts +0 -126
- package/build/ops.d.ts +0 -126
- package/build/ops.js +0 -127
- package/coverage/tmp/coverage-31752-1735543485354-0.json +0 -1
- package/coverage/tmp/coverage-59920-1735543484555-0.json +0 -1
- package/coverage/tmp/coverage-66252-1735543483919-0.json +0 -1
- package/coverage/tmp/coverage-68440-1735543485236-0.json +0 -1
- package/coverage/tmp/coverage-70588-1735543484426-0.json +0 -1
- package/coverage/tmp/coverage-79292-1735543485296-0.json +0 -1
- package/coverage/tmp/coverage-80212-1735543483980-0.json +0 -1
package/src/block.ts
CHANGED
|
@@ -1,233 +1,233 @@
|
|
|
1
|
-
import { BufferReader, BufferWriter, reverseBuffer, varuint } from './bufferutils.js';
|
|
2
|
-
import * as bcrypto from './crypto.js';
|
|
3
|
-
import { fastMerkleRoot } from './merkle.js';
|
|
4
|
-
import { Transaction } from './transaction.js';
|
|
5
|
-
import * as types from './types.js';
|
|
6
|
-
|
|
7
|
-
const { typeforce } = types;
|
|
8
|
-
|
|
9
|
-
const errorMerkleNoTxes = new TypeError('Cannot compute merkle root for zero transactions');
|
|
10
|
-
const errorWitnessNotSegwit = new TypeError('Cannot compute witness commit for non-segwit block');
|
|
11
|
-
|
|
12
|
-
export class Block {
|
|
13
|
-
version: number = 1;
|
|
14
|
-
prevHash?: Buffer = undefined;
|
|
15
|
-
merkleRoot?: Buffer = undefined;
|
|
16
|
-
timestamp: number = 0;
|
|
17
|
-
witnessCommit?: Buffer = undefined;
|
|
18
|
-
bits: number = 0;
|
|
19
|
-
nonce: number = 0;
|
|
20
|
-
transactions?: Transaction[] = undefined;
|
|
21
|
-
|
|
22
|
-
static fromBuffer(buffer: Buffer): Block {
|
|
23
|
-
if (buffer.length < 80) throw new Error('Buffer too small (< 80 bytes)');
|
|
24
|
-
|
|
25
|
-
const bufferReader = new BufferReader(buffer);
|
|
26
|
-
|
|
27
|
-
const block = new Block();
|
|
28
|
-
block.version = bufferReader.readInt32();
|
|
29
|
-
block.prevHash = bufferReader.readSlice(32);
|
|
30
|
-
block.merkleRoot = bufferReader.readSlice(32);
|
|
31
|
-
block.timestamp = bufferReader.readUInt32();
|
|
32
|
-
block.bits = bufferReader.readUInt32();
|
|
33
|
-
block.nonce = bufferReader.readUInt32();
|
|
34
|
-
|
|
35
|
-
if (buffer.length === 80) return block;
|
|
36
|
-
|
|
37
|
-
const readTransaction = (): any => {
|
|
38
|
-
const tx = Transaction.fromBuffer(bufferReader.buffer.slice(bufferReader.offset), true);
|
|
39
|
-
bufferReader.offset += tx.byteLength();
|
|
40
|
-
return tx;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const nTransactions = bufferReader.readVarInt();
|
|
44
|
-
block.transactions = [];
|
|
45
|
-
|
|
46
|
-
for (let i = 0; i < nTransactions; ++i) {
|
|
47
|
-
const tx = readTransaction();
|
|
48
|
-
block.transactions.push(tx);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const witnessCommit = block.getWitnessCommit();
|
|
52
|
-
// This Block contains a witness commit
|
|
53
|
-
if (witnessCommit) block.witnessCommit = witnessCommit;
|
|
54
|
-
|
|
55
|
-
return block;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
static fromHex(hex: string): Block {
|
|
59
|
-
return Block.fromBuffer(Buffer.from(hex, 'hex'));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
static calculateTarget(bits: number): Buffer {
|
|
63
|
-
const exponent = ((bits & 0xff000000) >> 24) - 3;
|
|
64
|
-
const mantissa = bits & 0x007fffff;
|
|
65
|
-
const target = Buffer.alloc(32, 0);
|
|
66
|
-
target.writeUIntBE(mantissa, 29 - exponent, 3);
|
|
67
|
-
return target;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
static calculateMerkleRoot(transactions: Transaction[], forWitness?: boolean): Buffer {
|
|
71
|
-
typeforce([{ getHash: types.Function }], transactions);
|
|
72
|
-
if (transactions.length === 0) throw errorMerkleNoTxes;
|
|
73
|
-
if (forWitness && !txesHaveWitnessCommit(transactions)) throw errorWitnessNotSegwit;
|
|
74
|
-
|
|
75
|
-
const hashes = transactions.map((transaction) => transaction.getHash(forWitness!));
|
|
76
|
-
|
|
77
|
-
const rootHash = fastMerkleRoot(hashes, bcrypto.hash256);
|
|
78
|
-
|
|
79
|
-
return forWitness
|
|
80
|
-
? bcrypto.hash256(Buffer.concat([rootHash, transactions[0].ins[0].witness[0]]))
|
|
81
|
-
: rootHash;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
getWitnessCommit(): Buffer | null {
|
|
85
|
-
if (!txesHaveWitnessCommit(this.transactions!)) return null;
|
|
86
|
-
|
|
87
|
-
// The merkle root for the witness data is in an OP_RETURN output.
|
|
88
|
-
// There is no rule for the index of the output, so use filter to find it.
|
|
89
|
-
// The root is prepended with 0xaa21a9ed so check for 0x6a24aa21a9ed
|
|
90
|
-
// If multiple commits are found, the output with highest index is assumed.
|
|
91
|
-
const witnessCommits = this.transactions![0].outs.filter((out) =>
|
|
92
|
-
out.script.slice(0, 6).equals(Buffer.from('6a24aa21a9ed', 'hex')),
|
|
93
|
-
).map((out) => out.script.slice(6, 38));
|
|
94
|
-
if (witnessCommits.length === 0) return null;
|
|
95
|
-
// Use the commit with the highest output (should only be one though)
|
|
96
|
-
const result = witnessCommits[witnessCommits.length - 1];
|
|
97
|
-
|
|
98
|
-
if (!(result instanceof Buffer && result.length === 32)) return null;
|
|
99
|
-
return result;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
hasWitnessCommit(): boolean {
|
|
103
|
-
if (this.witnessCommit instanceof Buffer && this.witnessCommit.length === 32) return true;
|
|
104
|
-
if (this.getWitnessCommit() !== null) return true;
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
hasWitness(): boolean {
|
|
109
|
-
return anyTxHasWitness(this.transactions!);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
weight(): number {
|
|
113
|
-
const base = this.byteLength(false, false);
|
|
114
|
-
const total = this.byteLength(false, true);
|
|
115
|
-
return base * 3 + total;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
byteLength(headersOnly?: boolean, allowWitness: boolean = true): number {
|
|
119
|
-
if (headersOnly || !this.transactions) return 80;
|
|
120
|
-
|
|
121
|
-
return (
|
|
122
|
-
80 +
|
|
123
|
-
varuint.encodingLength(this.transactions.length) +
|
|
124
|
-
this.transactions.reduce((a, x) => a + x.byteLength(allowWitness), 0)
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
getHash(): Buffer {
|
|
129
|
-
return bcrypto.hash256(this.toBuffer(true));
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
getId(): string {
|
|
133
|
-
return reverseBuffer(this.getHash()).toString('hex');
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
getUTCDate(): Date {
|
|
137
|
-
const date = new Date(0); // epoch
|
|
138
|
-
date.setUTCSeconds(this.timestamp);
|
|
139
|
-
|
|
140
|
-
return date;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// TODO: buffer, offset compatibility
|
|
144
|
-
toBuffer(headersOnly?: boolean): Buffer {
|
|
145
|
-
const buffer: Buffer = Buffer.allocUnsafe(this.byteLength(headersOnly));
|
|
146
|
-
|
|
147
|
-
const bufferWriter = new BufferWriter(buffer);
|
|
148
|
-
|
|
149
|
-
bufferWriter.writeInt32(this.version);
|
|
150
|
-
bufferWriter.writeSlice(this.prevHash!);
|
|
151
|
-
bufferWriter.writeSlice(this.merkleRoot!);
|
|
152
|
-
bufferWriter.writeUInt32(this.timestamp);
|
|
153
|
-
bufferWriter.writeUInt32(this.bits);
|
|
154
|
-
bufferWriter.writeUInt32(this.nonce);
|
|
155
|
-
|
|
156
|
-
if (headersOnly || !this.transactions) return buffer;
|
|
157
|
-
|
|
158
|
-
const encoded = varuint.encode(this.transactions.length, buffer, bufferWriter.offset);
|
|
159
|
-
bufferWriter.offset += encoded.bytes;
|
|
160
|
-
|
|
161
|
-
this.transactions.forEach((tx) => {
|
|
162
|
-
const txSize = tx.byteLength(); // TODO: extract from toBuffer?
|
|
163
|
-
tx.toBuffer(buffer, bufferWriter.offset);
|
|
164
|
-
bufferWriter.offset += txSize;
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
return buffer;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
toHex(headersOnly?: boolean): string {
|
|
171
|
-
return this.toBuffer(headersOnly).toString('hex');
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
checkTxRoots(): boolean {
|
|
175
|
-
// If the Block has segwit transactions but no witness commit,
|
|
176
|
-
// there's no way it can be valid, so fail the check.
|
|
177
|
-
const hasWitnessCommit = this.hasWitnessCommit();
|
|
178
|
-
if (!hasWitnessCommit && this.hasWitness()) return false;
|
|
179
|
-
return this.__checkMerkleRoot() && (hasWitnessCommit ? this.__checkWitnessCommit() : true);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
checkProofOfWork(): boolean {
|
|
183
|
-
const hash: Buffer = reverseBuffer(this.getHash());
|
|
184
|
-
const target = Block.calculateTarget(this.bits);
|
|
185
|
-
|
|
186
|
-
return hash.compare(target) <= 0;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
private __checkMerkleRoot(): boolean {
|
|
190
|
-
if (!this.transactions) throw errorMerkleNoTxes;
|
|
191
|
-
|
|
192
|
-
const actualMerkleRoot = Block.calculateMerkleRoot(this.transactions);
|
|
193
|
-
return this.merkleRoot!.compare(actualMerkleRoot) === 0;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
private __checkWitnessCommit(): boolean {
|
|
197
|
-
if (!this.transactions) throw errorMerkleNoTxes;
|
|
198
|
-
if (!this.hasWitnessCommit()) throw errorWitnessNotSegwit;
|
|
199
|
-
|
|
200
|
-
const actualWitnessCommit = Block.calculateMerkleRoot(this.transactions, true);
|
|
201
|
-
return this.witnessCommit!.compare(actualWitnessCommit) === 0;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function txesHaveWitnessCommit(transactions: Transaction[]): boolean {
|
|
206
|
-
return (
|
|
207
|
-
transactions instanceof Array &&
|
|
208
|
-
transactions[0] &&
|
|
209
|
-
transactions[0].ins &&
|
|
210
|
-
transactions[0].ins instanceof Array &&
|
|
211
|
-
transactions[0].ins[0] &&
|
|
212
|
-
transactions[0].ins[0].witness &&
|
|
213
|
-
transactions[0].ins[0].witness instanceof Array &&
|
|
214
|
-
transactions[0].ins[0].witness.length > 0
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function anyTxHasWitness(transactions: Transaction[]): boolean {
|
|
219
|
-
return (
|
|
220
|
-
transactions instanceof Array &&
|
|
221
|
-
transactions.some(
|
|
222
|
-
(tx) =>
|
|
223
|
-
typeof tx === 'object' &&
|
|
224
|
-
tx.ins instanceof Array &&
|
|
225
|
-
tx.ins.some(
|
|
226
|
-
(input) =>
|
|
227
|
-
typeof input === 'object' &&
|
|
228
|
-
input.witness instanceof Array &&
|
|
229
|
-
input.witness.length > 0,
|
|
230
|
-
),
|
|
231
|
-
)
|
|
232
|
-
);
|
|
233
|
-
}
|
|
1
|
+
import { BufferReader, BufferWriter, reverseBuffer, varuint } from './bufferutils.js';
|
|
2
|
+
import * as bcrypto from './crypto.js';
|
|
3
|
+
import { fastMerkleRoot } from './merkle.js';
|
|
4
|
+
import { Transaction } from './transaction.js';
|
|
5
|
+
import * as types from './types.js';
|
|
6
|
+
|
|
7
|
+
const { typeforce } = types;
|
|
8
|
+
|
|
9
|
+
const errorMerkleNoTxes = new TypeError('Cannot compute merkle root for zero transactions');
|
|
10
|
+
const errorWitnessNotSegwit = new TypeError('Cannot compute witness commit for non-segwit block');
|
|
11
|
+
|
|
12
|
+
export class Block {
|
|
13
|
+
version: number = 1;
|
|
14
|
+
prevHash?: Buffer = undefined;
|
|
15
|
+
merkleRoot?: Buffer = undefined;
|
|
16
|
+
timestamp: number = 0;
|
|
17
|
+
witnessCommit?: Buffer = undefined;
|
|
18
|
+
bits: number = 0;
|
|
19
|
+
nonce: number = 0;
|
|
20
|
+
transactions?: Transaction[] = undefined;
|
|
21
|
+
|
|
22
|
+
static fromBuffer(buffer: Buffer): Block {
|
|
23
|
+
if (buffer.length < 80) throw new Error('Buffer too small (< 80 bytes)');
|
|
24
|
+
|
|
25
|
+
const bufferReader = new BufferReader(buffer);
|
|
26
|
+
|
|
27
|
+
const block = new Block();
|
|
28
|
+
block.version = bufferReader.readInt32();
|
|
29
|
+
block.prevHash = bufferReader.readSlice(32);
|
|
30
|
+
block.merkleRoot = bufferReader.readSlice(32);
|
|
31
|
+
block.timestamp = bufferReader.readUInt32();
|
|
32
|
+
block.bits = bufferReader.readUInt32();
|
|
33
|
+
block.nonce = bufferReader.readUInt32();
|
|
34
|
+
|
|
35
|
+
if (buffer.length === 80) return block;
|
|
36
|
+
|
|
37
|
+
const readTransaction = (): any => {
|
|
38
|
+
const tx = Transaction.fromBuffer(bufferReader.buffer.slice(bufferReader.offset), true);
|
|
39
|
+
bufferReader.offset += tx.byteLength();
|
|
40
|
+
return tx;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const nTransactions = bufferReader.readVarInt();
|
|
44
|
+
block.transactions = [];
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < nTransactions; ++i) {
|
|
47
|
+
const tx = readTransaction();
|
|
48
|
+
block.transactions.push(tx);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const witnessCommit = block.getWitnessCommit();
|
|
52
|
+
// This Block contains a witness commit
|
|
53
|
+
if (witnessCommit) block.witnessCommit = witnessCommit;
|
|
54
|
+
|
|
55
|
+
return block;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static fromHex(hex: string): Block {
|
|
59
|
+
return Block.fromBuffer(Buffer.from(hex, 'hex'));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static calculateTarget(bits: number): Buffer {
|
|
63
|
+
const exponent = ((bits & 0xff000000) >> 24) - 3;
|
|
64
|
+
const mantissa = bits & 0x007fffff;
|
|
65
|
+
const target = Buffer.alloc(32, 0);
|
|
66
|
+
target.writeUIntBE(mantissa, 29 - exponent, 3);
|
|
67
|
+
return target;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static calculateMerkleRoot(transactions: Transaction[], forWitness?: boolean): Buffer {
|
|
71
|
+
typeforce([{ getHash: types.Function }], transactions);
|
|
72
|
+
if (transactions.length === 0) throw errorMerkleNoTxes;
|
|
73
|
+
if (forWitness && !txesHaveWitnessCommit(transactions)) throw errorWitnessNotSegwit;
|
|
74
|
+
|
|
75
|
+
const hashes = transactions.map((transaction) => transaction.getHash(forWitness!));
|
|
76
|
+
|
|
77
|
+
const rootHash = fastMerkleRoot(hashes, bcrypto.hash256);
|
|
78
|
+
|
|
79
|
+
return forWitness
|
|
80
|
+
? bcrypto.hash256(Buffer.concat([rootHash, transactions[0].ins[0].witness[0]]))
|
|
81
|
+
: rootHash;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
getWitnessCommit(): Buffer | null {
|
|
85
|
+
if (!txesHaveWitnessCommit(this.transactions!)) return null;
|
|
86
|
+
|
|
87
|
+
// The merkle root for the witness data is in an OP_RETURN output.
|
|
88
|
+
// There is no rule for the index of the output, so use filter to find it.
|
|
89
|
+
// The root is prepended with 0xaa21a9ed so check for 0x6a24aa21a9ed
|
|
90
|
+
// If multiple commits are found, the output with highest index is assumed.
|
|
91
|
+
const witnessCommits = this.transactions![0].outs.filter((out) =>
|
|
92
|
+
out.script.slice(0, 6).equals(Buffer.from('6a24aa21a9ed', 'hex')),
|
|
93
|
+
).map((out) => out.script.slice(6, 38));
|
|
94
|
+
if (witnessCommits.length === 0) return null;
|
|
95
|
+
// Use the commit with the highest output (should only be one though)
|
|
96
|
+
const result = witnessCommits[witnessCommits.length - 1];
|
|
97
|
+
|
|
98
|
+
if (!(result instanceof Buffer && result.length === 32)) return null;
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
hasWitnessCommit(): boolean {
|
|
103
|
+
if (this.witnessCommit instanceof Buffer && this.witnessCommit.length === 32) return true;
|
|
104
|
+
if (this.getWitnessCommit() !== null) return true;
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
hasWitness(): boolean {
|
|
109
|
+
return anyTxHasWitness(this.transactions!);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
weight(): number {
|
|
113
|
+
const base = this.byteLength(false, false);
|
|
114
|
+
const total = this.byteLength(false, true);
|
|
115
|
+
return base * 3 + total;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
byteLength(headersOnly?: boolean, allowWitness: boolean = true): number {
|
|
119
|
+
if (headersOnly || !this.transactions) return 80;
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
80 +
|
|
123
|
+
varuint.encodingLength(this.transactions.length) +
|
|
124
|
+
this.transactions.reduce((a, x) => a + x.byteLength(allowWitness), 0)
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
getHash(): Buffer {
|
|
129
|
+
return bcrypto.hash256(this.toBuffer(true));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
getId(): string {
|
|
133
|
+
return reverseBuffer(this.getHash()).toString('hex');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
getUTCDate(): Date {
|
|
137
|
+
const date = new Date(0); // epoch
|
|
138
|
+
date.setUTCSeconds(this.timestamp);
|
|
139
|
+
|
|
140
|
+
return date;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// TODO: buffer, offset compatibility
|
|
144
|
+
toBuffer(headersOnly?: boolean): Buffer {
|
|
145
|
+
const buffer: Buffer = Buffer.allocUnsafe(this.byteLength(headersOnly));
|
|
146
|
+
|
|
147
|
+
const bufferWriter = new BufferWriter(buffer);
|
|
148
|
+
|
|
149
|
+
bufferWriter.writeInt32(this.version);
|
|
150
|
+
bufferWriter.writeSlice(this.prevHash!);
|
|
151
|
+
bufferWriter.writeSlice(this.merkleRoot!);
|
|
152
|
+
bufferWriter.writeUInt32(this.timestamp);
|
|
153
|
+
bufferWriter.writeUInt32(this.bits);
|
|
154
|
+
bufferWriter.writeUInt32(this.nonce);
|
|
155
|
+
|
|
156
|
+
if (headersOnly || !this.transactions) return buffer;
|
|
157
|
+
|
|
158
|
+
const encoded = varuint.encode(this.transactions.length, buffer, bufferWriter.offset);
|
|
159
|
+
bufferWriter.offset += encoded.bytes;
|
|
160
|
+
|
|
161
|
+
this.transactions.forEach((tx) => {
|
|
162
|
+
const txSize = tx.byteLength(); // TODO: extract from toBuffer?
|
|
163
|
+
tx.toBuffer(buffer, bufferWriter.offset);
|
|
164
|
+
bufferWriter.offset += txSize;
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
return buffer;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
toHex(headersOnly?: boolean): string {
|
|
171
|
+
return this.toBuffer(headersOnly).toString('hex');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
checkTxRoots(): boolean {
|
|
175
|
+
// If the Block has segwit transactions but no witness commit,
|
|
176
|
+
// there's no way it can be valid, so fail the check.
|
|
177
|
+
const hasWitnessCommit = this.hasWitnessCommit();
|
|
178
|
+
if (!hasWitnessCommit && this.hasWitness()) return false;
|
|
179
|
+
return this.__checkMerkleRoot() && (hasWitnessCommit ? this.__checkWitnessCommit() : true);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
checkProofOfWork(): boolean {
|
|
183
|
+
const hash: Buffer = reverseBuffer(this.getHash());
|
|
184
|
+
const target = Block.calculateTarget(this.bits);
|
|
185
|
+
|
|
186
|
+
return hash.compare(target) <= 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private __checkMerkleRoot(): boolean {
|
|
190
|
+
if (!this.transactions) throw errorMerkleNoTxes;
|
|
191
|
+
|
|
192
|
+
const actualMerkleRoot = Block.calculateMerkleRoot(this.transactions);
|
|
193
|
+
return this.merkleRoot!.compare(actualMerkleRoot) === 0;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private __checkWitnessCommit(): boolean {
|
|
197
|
+
if (!this.transactions) throw errorMerkleNoTxes;
|
|
198
|
+
if (!this.hasWitnessCommit()) throw errorWitnessNotSegwit;
|
|
199
|
+
|
|
200
|
+
const actualWitnessCommit = Block.calculateMerkleRoot(this.transactions, true);
|
|
201
|
+
return this.witnessCommit!.compare(actualWitnessCommit) === 0;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function txesHaveWitnessCommit(transactions: Transaction[]): boolean {
|
|
206
|
+
return (
|
|
207
|
+
transactions instanceof Array &&
|
|
208
|
+
transactions[0] &&
|
|
209
|
+
transactions[0].ins &&
|
|
210
|
+
transactions[0].ins instanceof Array &&
|
|
211
|
+
transactions[0].ins[0] &&
|
|
212
|
+
transactions[0].ins[0].witness &&
|
|
213
|
+
transactions[0].ins[0].witness instanceof Array &&
|
|
214
|
+
transactions[0].ins[0].witness.length > 0
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function anyTxHasWitness(transactions: Transaction[]): boolean {
|
|
219
|
+
return (
|
|
220
|
+
transactions instanceof Array &&
|
|
221
|
+
transactions.some(
|
|
222
|
+
(tx) =>
|
|
223
|
+
typeof tx === 'object' &&
|
|
224
|
+
tx.ins instanceof Array &&
|
|
225
|
+
tx.ins.some(
|
|
226
|
+
(input) =>
|
|
227
|
+
typeof input === 'object' &&
|
|
228
|
+
input.witness instanceof Array &&
|
|
229
|
+
input.witness.length > 0,
|
|
230
|
+
),
|
|
231
|
+
)
|
|
232
|
+
);
|
|
233
|
+
}
|