From b93d9d99ccc240d3e022f1a680024469fcc04cf5 Mon Sep 17 00:00:00 2001 From: Apichan Chaiyutthasat Date: Sat, 6 Oct 2018 13:13:40 +0700 Subject: [PATCH 01/12] Update addresses.js --- test/integration/addresses.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/integration/addresses.js b/test/integration/addresses.js index 4bd71c8..9ad7502 100644 --- a/test/integration/addresses.js +++ b/test/integration/addresses.js @@ -19,6 +19,7 @@ function rng () { return Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') } describe('bitcoinjs-lib (addresses)', function () { it('can generate a random address', function () { + // in production: const keyPair = bitcoin.ECPair.makeRandom({}) const keyPair = bitcoin.ECPair.makeRandom({ rng: rng }) const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey }) @@ -121,6 +122,7 @@ describe('bitcoinjs-lib (addresses)', function () { // other networks it('can generate a Testnet address', function () { const testnet = bitcoin.networks.testnet + // in production: const keyPair = bitcoin.ECPair.makeRandom({ network: testnet }) const keyPair = bitcoin.ECPair.makeRandom({ network: testnet, rng: rng }) const wif = keyPair.toWIF() const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: testnet }) @@ -130,6 +132,7 @@ describe('bitcoinjs-lib (addresses)', function () { }) it('can generate a Litecoin address', function () { + // in production: const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN }) const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN, rng: rng }) const wif = keyPair.toWIF() const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: LITECOIN }) From 959ba5ae96a3c04cb14a795fc64a4b0a1c67e866 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Thu, 6 Dec 2018 13:16:30 +1100 Subject: [PATCH 02/12] add P2SH(P2WPKH) signature verification example --- test/integration/transactions.js | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/test/integration/transactions.js b/test/integration/transactions.js index e828414..0d88d78 100644 --- a/test/integration/transactions.js +++ b/test/integration/transactions.js @@ -258,7 +258,7 @@ describe('bitcoinjs-lib (transactions)', function () { }) }) - it('can verify Transaction signatures', function () { + it('can verify Transaction (P2PKH) signatures', function () { const txHex = '010000000321c5f7e7bc98b3feda84aad36a5c99a02bcb8823a2f3eccbcd5da209698b5c20000000006b48304502210099e021772830207cf7c55b69948d3b16b4dcbf1f55a9cd80ebf8221a169735f9022064d33f11d62cd28240b3862afc0b901adc9f231c7124dd19bdb30367b61964c50121032b4c06c06c3ec0b7fa29519dfa5aae193ee2cc35ca127f29f14ec605d62fb63dffffffff8a75ce85441ddb3f342708ee33cc8ed418b07d9ba9e0e7c4e1cccfe9f52d8a88000000006946304302207916c23dae212c95a920423902fa44e939fb3d542f4478a7b46e9cde53705800021f0d74e9504146e404c1b8f9cba4dff2d4782e3075491c9ed07ce4a7d1c4461a01210216c92abe433106491bdeb4a261226f20f5a4ac86220cc6e37655aac6bf3c1f2affffffffdfef93f69fe32e944fad79fa8f882b3a155d80383252348caba1a77a5abbf7ef000000006b483045022100faa6e9ca289b46c64764a624c59ac30d9abcf1d4a04c4de9089e67cbe0d300a502206930afa683f6807502de5c2431bf9a1fd333c8a2910a76304df0f3d23d83443f0121039e05da8b8ea4f9868ecebb25998c7701542986233f4401799551fbecf316b18fffffffff01ff4b0000000000001976a9146c86476d1d85cd60116cd122a274e6a570a5a35c88acc96d0700' const keyPairs = [ '032b4c06c06c3ec0b7fa29519dfa5aae193ee2cc35ca127f29f14ec605d62fb63d', @@ -281,4 +281,34 @@ describe('bitcoinjs-lib (transactions)', function () { assert.strictEqual(keyPair.verify(hash, ss.signature), true) }) }) + + it('can verify Transaction (P2SH(P2WPKH)) signatures', function () { + const utxos = { + 'f72d1d83ac40fcedd01415751556a905844ab5f44bbb7728565ebb91b1590109:0': { + value: 50000 + } + } + + const txHex = '02000000000101090159b191bb5e562877bb4bf4b54a8405a95615751514d0edfc40ac831d2df7000000001716001435a179e5516947a39ae9c8a25e9fe62c0fc598edffffffff01204e0000000000001976a91431d43308d3c886d53e9ae8a45728370571ff456988ac0247304402206ec41f685b997a51f325b07ee852e82a535f6b52ef54485cc133e05168aa052a022070bafa86108acb51c77b2b259ae8fb7fd1efa10fef804fcfe9b13c2db719acf5012103fb03e9d0a9af86cbed94225dbb8bb70f6b82109bce0a61ddcf41dab6cbb4871100000000' + const tx = bitcoin.Transaction.fromHex(txHex) + + tx.ins.forEach(function (input, i) { + const txId = Buffer.from(input.hash).reverse().toString('hex') + const utxo = utxos[`${txId}:${i}`] + if (!utxo) throw new Error('Missing utxo') + + const p2sh = bitcoin.payments.p2sh({ + input: input.script, + witness: input.witness + }) + const p2wpkh = bitcoin.payments.p2wpkh(p2sh.redeem) + const p2pkh = bitcoin.payments.p2pkh({ pubkey: p2wpkh.pubkey }) // because P2WPKH is annoying + + const ss = bitcoin.script.signature.decode(p2wpkh.signature) + const hash = tx.hashForWitnessV0(i, p2pkh.output, utxo.value, ss.hashType) + const keyPair = bitcoin.ECPair.fromPublicKey(p2wpkh.pubkey) // aka, cQ3EtF4mApRcogNGSeyPTKbmfxxn3Yfb1wecfKSws9a8bnYuxoAk + + assert.strictEqual(keyPair.verify(hash, ss.signature), true) + }) + }) }) From 912d6d41becf3b4b77b00038c481d71b34c64b2e Mon Sep 17 00:00:00 2001 From: junderw Date: Sat, 29 Dec 2018 17:02:32 +0900 Subject: [PATCH 03/12] Fix some small bugs --- src/payments/p2ms.js | 2 +- src/transaction_builder.js | 4 ++-- test/fixtures/p2ms.json | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/payments/p2ms.js b/src/payments/p2ms.js index 5c90a4d..8c5a380 100644 --- a/src/payments/p2ms.js +++ b/src/payments/p2ms.js @@ -129,7 +129,7 @@ function p2ms (a, opts) { if (a.input[0] !== OPS.OP_0) throw new TypeError('Input is invalid') if (o.signatures.length === 0 || !o.signatures.every(isAcceptableSignature)) throw new TypeError('Input has invalid signature(s)') - if (a.signatures && !stacksEqual(a.signatures.equals(o.signatures))) throw new TypeError('Signature mismatch') + if (a.signatures && !stacksEqual(a.signatures, o.signatures)) throw new TypeError('Signature mismatch') if (a.m !== undefined && a.m !== a.signatures.length) throw new TypeError('Signature count mismatch') } } diff --git a/src/transaction_builder.js b/src/transaction_builder.js index bea1ded..6508a86 100644 --- a/src/transaction_builder.js +++ b/src/transaction_builder.js @@ -217,7 +217,7 @@ function expandOutput (script, ourPubKey) { return { type } } -function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScript) { +function prepareInput (input, ourPubKey, redeemScript, witnessScript) { if (redeemScript && witnessScript) { const p2wsh = payments.p2wsh({ redeem: { output: witnessScript } }) const p2wshAlt = payments.p2wsh({ output: redeemScript }) @@ -665,7 +665,7 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy } if (!canSign(input)) { - const prepared = prepareInput(input, ourPubKey, redeemScript, witnessValue, witnessScript) + const prepared = prepareInput(input, ourPubKey, redeemScript, witnessScript) // updates inline Object.assign(input, prepared) diff --git a/test/fixtures/p2ms.json b/test/fixtures/p2ms.json index 8ea033e..2f41270 100644 --- a/test/fixtures/p2ms.json +++ b/test/fixtures/p2ms.json @@ -310,6 +310,20 @@ ] } }, + { + "exception": "Signature mismatch", + "arguments": { + "m": 1, + "pubkeys": [ + "030000000000000000000000000000000000000000000000000000000000000001", + "030000000000000000000000000000000000000000000000000000000000000001" + ], + "signatures": [ + "300602010002010001" + ], + "input": "OP_0 300602010002010101" + } + }, { "exception": "Too many signatures provided", "arguments": { From 53b8f966e768e9ee69337412d23ba9d5f038bd2b Mon Sep 17 00:00:00 2001 From: "Sam (Sangho Kim)" Date: Mon, 31 Dec 2018 12:24:27 +0900 Subject: [PATCH 04/12] Update transactions.js I think this is typo. --- test/integration/transactions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/transactions.js b/test/integration/transactions.js index 0d88d78..f725241 100644 --- a/test/integration/transactions.js +++ b/test/integration/transactions.js @@ -64,7 +64,7 @@ describe('bitcoinjs-lib (transactions)', function () { txb.addInput(unspent1.txId, unspent1.vout) // alice2 unspent txb.addOutput('mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf', 8e4) // the actual "spend" txb.addOutput(aliceCpkh.address, 1e4) // Alice's change - // (in)(4e4 + 2e4) - (out)(1e4 + 3e4) = (fee)2e4 = 20000, this is the miner fee + // (in)(5e4 + 7e4) - (out)(8e4 + 1e4) = (fee)3e4 = 30000, this is the miner fee // Alice signs each input with the respective private keys txb.sign(0, alice1) From f8490b6c0d89ab44f3408a6cdbd44c6da2c718ef Mon Sep 17 00:00:00 2001 From: Jonathan Underwood Date: Mon, 31 Dec 2018 15:17:00 +0900 Subject: [PATCH 05/12] Update rng function In case someone copy pastes, instead of getting a dangerous key, they will get a random key, and a console error. --- test/integration/addresses.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/integration/addresses.js b/test/integration/addresses.js index 9ad7502..501e7ac 100644 --- a/test/integration/addresses.js +++ b/test/integration/addresses.js @@ -15,7 +15,14 @@ const LITECOIN = { } // deterministic RNG for testing only -function rng () { return Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') } +function rng (c) { + if (describe === undefined || it === undefined) { + console.error('DO NOT USE THIS rng FUNCTION OUTSIDE OF AUTOMATED TESTING!') + const randomBytes = require('randombytes') + return randomBytes(c) + } + return Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') +} describe('bitcoinjs-lib (addresses)', function () { it('can generate a random address', function () { From 7d8dd860d1208ed715579a1ec4364d9f9d7aa4b2 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Tue, 1 Jan 2019 11:30:20 +1100 Subject: [PATCH 06/12] testing: use NODE_ENV instead of mocha constants --- package.json | 2 +- test/integration/addresses.js | 23 ++++++++++------------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 755be28..c9ab813 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "coverage-report": "nyc report --reporter=lcov", "coverage-html": "nyc report --reporter=html", "coverage": "nyc --check-coverage --branches 90 --functions 90 mocha", - "integration": "mocha --timeout 50000 test/integration/", + "integration": "NODE_ENV=TESTING-BITCOINJS mocha --timeout 50000 test/integration/", "standard": "standard", "test": "npm run standard && npm run coverage", "unit": "mocha" diff --git a/test/integration/addresses.js b/test/integration/addresses.js index 76c0330..9a70172 100644 --- a/test/integration/addresses.js +++ b/test/integration/addresses.js @@ -14,20 +14,17 @@ const LITECOIN = { wif: 0xb0 } -// deterministic RNG for testing only -function rng (c) { - if (describe === undefined || it === undefined) { - console.error('DO NOT USE THIS rng FUNCTION OUTSIDE OF AUTOMATED TESTING!') - const randomBytes = require('randombytes') - return randomBytes(c) - } +// deterministic random number generator for TESTING ONLY +// WARNING: DO NOT USE THIS - IT IS NOT RANDOM - it produces the same private key every time for the purposes of testing. +function unsafeDeterministicRng (c) { + if (process.env.NODE_ENV !== 'TESTING-BITCOINJS') throw new Error('DO NOT USE THIS FUNCTION - IT IS NOT RANDOM - IT IS FOR TESTING ONLY - IT PRODUCES THE SAME PRIVATE KEY EVERY TIME') return Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') } describe('bitcoinjs-lib (addresses)', function () { it('can generate a random address', function () { - // in production: const keyPair = bitcoin.ECPair.makeRandom({}) - const keyPair = bitcoin.ECPair.makeRandom({ rng: rng }) + // const keyPair = bitcoin.ECPair.makeRandom() + const keyPair = bitcoin.ECPair.makeRandom({ rng: unsafeDeterministicRng }) const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey }) assert.strictEqual(address, '1F5VhMHukdnUES9kfXqzPzMeF1GPHKiF64') @@ -118,8 +115,8 @@ describe('bitcoinjs-lib (addresses)', function () { // other networks it('can generate a Testnet address', function () { const testnet = bitcoin.networks.testnet - // in production: const keyPair = bitcoin.ECPair.makeRandom({ network: testnet }) - const keyPair = bitcoin.ECPair.makeRandom({ network: testnet, rng: rng }) + // const keyPair = bitcoin.ECPair.makeRandom({ network: testnet }) + const keyPair = bitcoin.ECPair.makeRandom({ network: testnet, rng: unsafeDeterministicRng }) const wif = keyPair.toWIF() const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: testnet }) @@ -128,8 +125,8 @@ describe('bitcoinjs-lib (addresses)', function () { }) it('can generate a Litecoin address', function () { - // in production: const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN }) - const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN, rng: rng }) + // const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN }) + const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN, rng: unsafeDeterministicRng }) const wif = keyPair.toWIF() const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: LITECOIN }) From e5781d97b9f3a8631fdfadadd75b3fe78b244bf4 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Tue, 1 Jan 2019 11:41:00 +1100 Subject: [PATCH 07/12] testing: extra warnings --- test/integration/addresses.js | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/test/integration/addresses.js b/test/integration/addresses.js index 9a70172..661d5b6 100644 --- a/test/integration/addresses.js +++ b/test/integration/addresses.js @@ -3,6 +3,17 @@ const assert = require('assert') const bitcoin = require('../../') const dhttp = require('dhttp/200') +// WARNING: DO NOT USE THIS - IT IS NOT RANDOM +// WARNING: It produces the same 'number' every time for the purposes of testing. +function unsafeDeterministicRng (c) { + if (process.env.NODE_ENV !== 'TESTING-BITCOINJS') { + throw new Error('DO NOT USE THIS FUNCTION - IT IS NOT RANDOM - IT IS FOR TESTING ONLY - IT PRODUCES THE SAME NUMBER EVERY TIME') + } + + // deterministic result for TESTING ONLY + return Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') +} + const LITECOIN = { messagePrefix: '\x19Litecoin Signed Message:\n', bip32: { @@ -14,16 +25,11 @@ const LITECOIN = { wif: 0xb0 } -// deterministic random number generator for TESTING ONLY -// WARNING: DO NOT USE THIS - IT IS NOT RANDOM - it produces the same private key every time for the purposes of testing. -function unsafeDeterministicRng (c) { - if (process.env.NODE_ENV !== 'TESTING-BITCOINJS') throw new Error('DO NOT USE THIS FUNCTION - IT IS NOT RANDOM - IT IS FOR TESTING ONLY - IT PRODUCES THE SAME PRIVATE KEY EVERY TIME') - return Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') -} - describe('bitcoinjs-lib (addresses)', function () { it('can generate a random address', function () { // const keyPair = bitcoin.ECPair.makeRandom() + + // WARNING: uses unsafeDeterministicRng function for testing, see warning at top of file const keyPair = bitcoin.ECPair.makeRandom({ rng: unsafeDeterministicRng }) const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey }) @@ -116,6 +122,8 @@ describe('bitcoinjs-lib (addresses)', function () { it('can generate a Testnet address', function () { const testnet = bitcoin.networks.testnet // const keyPair = bitcoin.ECPair.makeRandom({ network: testnet }) + + // WARNING: uses unsafeDeterministicRng function for testing, see warning at top of file const keyPair = bitcoin.ECPair.makeRandom({ network: testnet, rng: unsafeDeterministicRng }) const wif = keyPair.toWIF() const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: testnet }) @@ -126,6 +134,8 @@ describe('bitcoinjs-lib (addresses)', function () { it('can generate a Litecoin address', function () { // const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN }) + + // WARNING: uses unsafeDeterministicRng function for testing, see warning at top of file const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN, rng: unsafeDeterministicRng }) const wif = keyPair.toWIF() const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: LITECOIN }) From 88951d34dbe5834a1330282a5b7b97d6157cdc28 Mon Sep 17 00:00:00 2001 From: Jonathan Underwood Date: Tue, 1 Jan 2019 14:26:34 +0900 Subject: [PATCH 08/12] Update LICENSE Happy new year! --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index fadd21b..064b885 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2011-2018 bitcoinjs-lib contributors +Copyright (c) 2011-2019 bitcoinjs-lib contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 49be171583d40eb0d4d638caf9d16df78ac3d178 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Tue, 1 Jan 2019 23:24:26 +1100 Subject: [PATCH 09/12] rm usage of unsafeDeterministicRng --- README.md | 62 +++++++++++----------- test/integration/addresses.js | 98 +++++++++++++---------------------- 2 files changed, 67 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index 9342696..b8f70f2 100644 --- a/README.md +++ b/README.md @@ -108,37 +108,37 @@ The below examples are implemented as integration tests, they should be very eas Otherwise, pull requests are appreciated. Some examples interact (via HTTPS) with a 3rd Party Blockchain Provider (3PBP). -- [Generate a random address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L22) -- [Import an address via WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L40) -- [Generate a 2-of-3 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L47) -- [Generate a SegWit address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L60) -- [Generate a SegWit P2SH address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L67) -- [Generate a SegWit 3-of-4 multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L76) -- [Generate a SegWit 2-of-2 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L90) -- [Support the retrieval of transactions for an address (3rd party blockchain)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L104) -- [Generate a Testnet address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L123) -- [Generate a Litecoin address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L133) -- [Create a 1-to-1 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L13) -- [Create a 2-to-2 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L28) -- [Create (and broadcast via 3PBP) a typical Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L47) -- [Create (and broadcast via 3PBP) a Transaction with an OP\_RETURN output](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L83) -- [Create (and broadcast via 3PBP) a Transaction with a 2-of-4 P2SH(multisig) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L105) -- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2SH(P2WPKH) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L143) -- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2WPKH input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L174) -- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2PK input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L218) -- [Create (and broadcast via 3PBP) a Transaction with a SegWit 3-of-4 P2SH(P2WSH(multisig)) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L263) -- [Verify a Transaction signature](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L304) -- [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L12) -- [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L20) -- [Export a BIP32 xpub](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L31) -- [Create a BIP32, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L40) -- [Create a BIP44, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L55) -- [Create a BIP49, bitcoin testnet, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L71) -- [Use BIP39 to generate BIP32 addresses](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L86) -- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L43) -- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L88) -- [Create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L144) -- [Create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L190) +- [Generate a random address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js) +- [Import an address via WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js) +- [Generate a 2-of-3 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js) +- [Generate a SegWit address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js) +- [Generate a SegWit P2SH address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js) +- [Generate a SegWit 3-of-4 multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js) +- [Generate a SegWit 2-of-2 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js) +- [Support the retrieval of transactions for an address (3rd party blockchain)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js) +- [Generate a Testnet address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js) +- [Generate a Litecoin address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js) +- [Create a 1-to-1 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js) +- [Create a 2-to-2 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js) +- [Create (and broadcast via 3PBP) a typical Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js) +- [Create (and broadcast via 3PBP) a Transaction with an OP\_RETURN output](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js) +- [Create (and broadcast via 3PBP) a Transaction with a 2-of-4 P2SH(multisig) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js) +- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2SH(P2WPKH) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js) +- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2WPKH input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js) +- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2PK input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js) +- [Create (and broadcast via 3PBP) a Transaction with a SegWit 3-of-4 P2SH(P2WSH(multisig)) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js) +- [Verify a Transaction signature](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js) +- [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js) +- [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js) +- [Export a BIP32 xpub](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js) +- [Create a BIP32, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js) +- [Create a BIP44, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js) +- [Create a BIP49, bitcoin testnet, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js) +- [Use BIP39 to generate BIP32 addresses](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js) +- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js) +- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js) +- [Create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js) +- [Create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js) If you have a use case that you feel could be listed here, please [ask for it](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new)! diff --git a/test/integration/addresses.js b/test/integration/addresses.js index 661d5b6..51d2264 100644 --- a/test/integration/addresses.js +++ b/test/integration/addresses.js @@ -2,38 +2,28 @@ const { describe, it } = require('mocha') const assert = require('assert') const bitcoin = require('../../') const dhttp = require('dhttp/200') - -// WARNING: DO NOT USE THIS - IT IS NOT RANDOM -// WARNING: It produces the same 'number' every time for the purposes of testing. -function unsafeDeterministicRng (c) { - if (process.env.NODE_ENV !== 'TESTING-BITCOINJS') { - throw new Error('DO NOT USE THIS FUNCTION - IT IS NOT RANDOM - IT IS FOR TESTING ONLY - IT PRODUCES THE SAME NUMBER EVERY TIME') - } - - // deterministic result for TESTING ONLY - return Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') -} - -const LITECOIN = { - messagePrefix: '\x19Litecoin Signed Message:\n', - bip32: { - public: 0x019da462, - private: 0x019d9cfe - }, - pubKeyHash: 0x30, - scriptHash: 0x32, - wif: 0xb0 -} +const TESTNET = bitcoin.networks.testnet describe('bitcoinjs-lib (addresses)', function () { - it('can generate a random address', function () { - // const keyPair = bitcoin.ECPair.makeRandom() - - // WARNING: uses unsafeDeterministicRng function for testing, see warning at top of file - const keyPair = bitcoin.ECPair.makeRandom({ rng: unsafeDeterministicRng }) + it('can generate a random address [and support the retrieval of transactions for that address (via 3PBP)', function (done) { + const keyPair = bitcoin.ECPair.makeRandom() const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey }) - assert.strictEqual(address, '1F5VhMHukdnUES9kfXqzPzMeF1GPHKiF64') + // bitcoin P2PKH addresses start with a '1' + assert.strictEqual(address.startsWith('1'), true) + + dhttp({ + method: 'GET', + url: 'https://blockchain.info/rawaddr/' + address + }, function (err, result) { + if (err) return done(err) + + // random private keys [probably!] have no transactions + assert.strictEqual(result.n_tx, 0) + assert.strictEqual(result.total_received, 0) + assert.strictEqual(result.total_sent, 0) + done() + }) }) it('can import an address via WIF', function () { @@ -100,47 +90,31 @@ describe('bitcoinjs-lib (addresses)', function () { assert.strictEqual(address, '3P4mrxQfmExfhxqjLnR2Ah4WES5EB1KBrN') }) - it('can support the retrieval of transactions for an address (via 3PBP)', function (done) { - const keyPair = bitcoin.ECPair.makeRandom() - const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey }) - - dhttp({ - method: 'GET', - url: 'https://blockchain.info/rawaddr/' + address - }, function (err, result) { - if (err) return done(err) - - // random private keys [probably!] have no transactions - assert.strictEqual(result.n_tx, 0) - assert.strictEqual(result.total_received, 0) - assert.strictEqual(result.total_sent, 0) - done() - }) - }) - - // other networks + // examples using other network information it('can generate a Testnet address', function () { - const testnet = bitcoin.networks.testnet - // const keyPair = bitcoin.ECPair.makeRandom({ network: testnet }) + const keyPair = bitcoin.ECPair.makeRandom({ network: TESTNET }) + const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: TESTNET }) - // WARNING: uses unsafeDeterministicRng function for testing, see warning at top of file - const keyPair = bitcoin.ECPair.makeRandom({ network: testnet, rng: unsafeDeterministicRng }) - const wif = keyPair.toWIF() - const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: testnet }) - - assert.strictEqual(address, 'mubSzQNtZfDj1YdNP6pNDuZy6zs6GDn61L') - assert.strictEqual(wif, 'cRgnQe9MUu1JznntrLaoQpB476M8PURvXVQB5R2eqms5tXnzNsrr') + // bitcoin testnet P2PKH addresses start with a 'm' + assert.strictEqual(address.startsWith('m'), true) }) it('can generate a Litecoin address', function () { - // const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN }) + // WARNING: although possible, bitcoinjs is NOT necessarily compatible with Litecoin + const LITECOIN = { + messagePrefix: '\x19Litecoin Signed Message:\n', + bip32: { + public: 0x019da462, + private: 0x019d9cfe + }, + pubKeyHash: 0x30, + scriptHash: 0x32, + wif: 0xb0 + } - // WARNING: uses unsafeDeterministicRng function for testing, see warning at top of file - const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN, rng: unsafeDeterministicRng }) - const wif = keyPair.toWIF() + const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN }) const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: LITECOIN }) - assert.strictEqual(address, 'LZJSxZbjqJ2XVEquqfqHg1RQTDdfST5PTn') - assert.strictEqual(wif, 'T7A4PUSgTDHecBxW1ZiYFrDNRih2o7M8Gf9xpoCgudPF9gDiNvuS') + assert.strictEqual(address.startsWith('L'), true) }) }) From c68dfc058fa984d1fb5431cc4ce4ef23a8b0cbc5 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Tue, 1 Jan 2019 23:30:10 +1100 Subject: [PATCH 10/12] testing: rm NODE_ENV --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c9ab813..755be28 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "coverage-report": "nyc report --reporter=lcov", "coverage-html": "nyc report --reporter=html", "coverage": "nyc --check-coverage --branches 90 --functions 90 mocha", - "integration": "NODE_ENV=TESTING-BITCOINJS mocha --timeout 50000 test/integration/", + "integration": "mocha --timeout 50000 test/integration/", "standard": "standard", "test": "npm run standard && npm run coverage", "unit": "mocha" From f3d918a2cbc6653247e939c367f5aafd5c48f73c Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Tue, 1 Jan 2019 23:49:57 +1100 Subject: [PATCH 11/12] tests: use privateKey 0x000...0001 for examples --- test/integration/addresses.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/integration/addresses.js b/test/integration/addresses.js index 51d2264..5afc5e8 100644 --- a/test/integration/addresses.js +++ b/test/integration/addresses.js @@ -27,10 +27,10 @@ describe('bitcoinjs-lib (addresses)', function () { }) it('can import an address via WIF', function () { - const keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct') + const keyPair = bitcoin.ECPair.fromWIF('KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn') const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey }) - assert.strictEqual(address, '19AAjaTUbRjQCMuVczepkoPswiZRhjtg31') + assert.strictEqual(address, '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH') }) it('can generate a P2SH, pay-to-multisig (2-of-3) address', function () { @@ -47,19 +47,19 @@ describe('bitcoinjs-lib (addresses)', function () { }) it('can generate a SegWit address', function () { - const keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct') + const keyPair = bitcoin.ECPair.fromWIF('KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn') const { address } = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey }) - assert.strictEqual(address, 'bc1qt97wqg464zrhnx23upykca5annqvwkwujjglky') + assert.strictEqual(address, 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4') }) it('can generate a SegWit address (via P2SH)', function () { - const keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct') + const keyPair = bitcoin.ECPair.fromWIF('KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn') const { address } = bitcoin.payments.p2sh({ redeem: bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey }) }) - assert.strictEqual(address, '34AgLJhwXrvmkZS1o5TrcdeevMt22Nar53') + assert.strictEqual(address, '3JvL6Ymt8MVWiCNHC7oWU6nLeHNJKLZGLN') }) it('can generate a P2WSH (SegWit), pay-to-multisig (3-of-4) address', function () { From 1ed037025c69cf65c50db0b1bef16022cff91cf1 Mon Sep 17 00:00:00 2001 From: junderw Date: Mon, 7 Jan 2019 16:33:57 +0900 Subject: [PATCH 12/12] Fix testnet address test --- test/integration/addresses.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/addresses.js b/test/integration/addresses.js index 5afc5e8..7cf2612 100644 --- a/test/integration/addresses.js +++ b/test/integration/addresses.js @@ -95,8 +95,8 @@ describe('bitcoinjs-lib (addresses)', function () { const keyPair = bitcoin.ECPair.makeRandom({ network: TESTNET }) const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: TESTNET }) - // bitcoin testnet P2PKH addresses start with a 'm' - assert.strictEqual(address.startsWith('m'), true) + // bitcoin testnet P2PKH addresses start with a 'm' or 'n' + assert.strictEqual(address.startsWith('m') || address.startsWith('n'), true) }) it('can generate a Litecoin address', function () {