diff --git a/test/integration/_regtest.js b/test/integration/_regtest.js index 4cdb6da..f851d2c 100644 --- a/test/integration/_regtest.js +++ b/test/integration/_regtest.js @@ -67,12 +67,8 @@ function verify (txo, callback) { }) } -// TODO: remove -const baddress = bitcoin.address -const bcrypto = bitcoin.crypto function getAddress (node, network) { - network = network || bitcoin.networks.bitcoin - return baddress.toBase58Check(bcrypto.hash160(node.publicKey), network.pubKeyHash) + return bitcoin.payments.p2pkh({ pubkey: node.publicKey, network }).address } function randomAddress () { diff --git a/test/integration/addresses.js b/test/integration/addresses.js index e7c715b..412e792 100644 --- a/test/integration/addresses.js +++ b/test/integration/addresses.js @@ -18,18 +18,10 @@ const LITECOIN = { // deterministic RNG for testing only function rng () { return Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') } -// TODO: remove -const baddress = bitcoin.address -const bcrypto = bitcoin.crypto -function getAddress (node, network) { - network = network || bitcoin.networks.bitcoin - return baddress.toBase58Check(bcrypto.hash160(node.publicKey), network.pubKeyHash) -} - describe('bitcoinjs-lib (addresses)', function () { it('can generate a random address', function () { const keyPair = bitcoin.ECPair.makeRandom({ rng: rng }) - const address = getAddress(keyPair) + const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey }) assert.strictEqual(address, '1F5VhMHukdnUES9kfXqzPzMeF1GPHKiF64') }) @@ -38,7 +30,7 @@ describe('bitcoinjs-lib (addresses)', function () { const hash = bitcoin.crypto.sha256(Buffer.from('correct horse battery staple')) const keyPair = bitcoin.ECPair.fromPrivateKey(hash) - const address = getAddress(keyPair) + const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey }) // Generating addresses from SHA256 hashes is not secure if the input to the hash function is predictable // Do not use with predictable inputs @@ -47,76 +39,71 @@ describe('bitcoinjs-lib (addresses)', function () { it('can import an address via WIF', function () { const keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct') - const address = getAddress(keyPair) + const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey }) assert.strictEqual(address, '19AAjaTUbRjQCMuVczepkoPswiZRhjtg31') }) - it('can generate a 2-of-3 multisig P2SH address', function () { - const pubKeys = [ + it('can generate a P2SH, pay-to-multisig (2-of-3) address', function () { + const pubkeys = [ '026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01', '02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9', '03c6103b3b83e4a24a0e33a4df246ef11772f9992663db0c35759a5e2ebf68d8e9' - ].map(function (hex) { return Buffer.from(hex, 'hex') }) - - const redeemScript = bitcoin.script.multisig.output.encode(2, pubKeys) // 2 of 3 - const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript)) - const address = bitcoin.address.fromOutputScript(scriptPubKey) + ].map((hex) => Buffer.from(hex, 'hex')) + const { address } = bitcoin.payments.p2sh({ + redeem: bitcoin.payments.p2ms({ m: 2, pubkeys }) + }) assert.strictEqual(address, '36NUkt6FWUi3LAWBqWRdDmdTWbt91Yvfu7') }) it('can generate a SegWit address', function () { const keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct') - - const scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(keyPair.publicKey)) - const address = bitcoin.address.fromOutputScript(scriptPubKey) + const { address } = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey }) assert.strictEqual(address, 'bc1qt97wqg464zrhnx23upykca5annqvwkwujjglky') }) it('can generate a SegWit address (via P2SH)', function () { const keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct') - - const redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(keyPair.publicKey)) - const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript)) - const address = bitcoin.address.fromOutputScript(scriptPubKey) + const { address } = bitcoin.payments.p2sh({ + redeem: bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey }) + }) assert.strictEqual(address, '34AgLJhwXrvmkZS1o5TrcdeevMt22Nar53') }) - it('can generate a SegWit 3-of-4 multisig address', function () { - const pubKeys = [ + it('can generate a P2WSH (SegWit), pay-to-multisig (3-of-4) address', function () { + const pubkeys = [ '026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01', '02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9', '023e4740d0ba639e28963f3476157b7cf2fb7c6fdf4254f97099cf8670b505ea59', '03c6103b3b83e4a24a0e33a4df246ef11772f9992663db0c35759a5e2ebf68d8e9' - ].map(function (hex) { return Buffer.from(hex, 'hex') }) - - const witnessScript = bitcoin.script.multisig.output.encode(3, pubKeys) // 3 of 4 - const scriptPubKey = bitcoin.script.witnessScriptHash.output.encode(bitcoin.crypto.sha256(witnessScript)) - const address = bitcoin.address.fromOutputScript(scriptPubKey) + ].map((hex) => Buffer.from(hex, 'hex')) + const { address } = bitcoin.payments.p2wsh({ + redeem: bitcoin.payments.p2ms({ m: 3, pubkeys }) + }) assert.strictEqual(address, 'bc1q75f6dv4q8ug7zhujrsp5t0hzf33lllnr3fe7e2pra3v24mzl8rrqtp3qul') }) - it('can generate a SegWit 2-of-2 multisig address (via P2SH)', function () { - const pubKeys = [ + it('can generate a P2SH(P2WSH(...)), pay-to-multisig (2-of-2) address', function () { + const pubkeys = [ '026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01', '02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9' - ].map(function (hex) { return Buffer.from(hex, 'hex') }) - - const witnessScript = bitcoin.script.multisig.output.encode(2, pubKeys) // 2 of 2 - const redeemScript = bitcoin.script.witnessScriptHash.output.encode(bitcoin.crypto.sha256(witnessScript)) - const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript)) - const address = bitcoin.address.fromOutputScript(scriptPubKey) + ].map((hex) => Buffer.from(hex, 'hex')) + const { address } = bitcoin.payments.p2sh({ + redeem: bitcoin.payments.p2wsh({ + redeem: bitcoin.payments.p2ms({ m: 2, pubkeys }) + }) + }) 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 = getAddress(keyPair) + const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey }) dhttp({ method: 'GET', @@ -137,7 +124,7 @@ describe('bitcoinjs-lib (addresses)', function () { const testnet = bitcoin.networks.testnet const keyPair = bitcoin.ECPair.makeRandom({ network: testnet, rng: rng }) const wif = keyPair.toWIF() - const address = getAddress(keyPair, testnet) + const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: testnet }) assert.strictEqual(address, 'mubSzQNtZfDj1YdNP6pNDuZy6zs6GDn61L') assert.strictEqual(wif, 'cRgnQe9MUu1JznntrLaoQpB476M8PURvXVQB5R2eqms5tXnzNsrr') @@ -146,7 +133,7 @@ describe('bitcoinjs-lib (addresses)', function () { it('can generate a Litecoin address', function () { const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN, rng: rng }) const wif = keyPair.toWIF() - const address = getAddress(keyPair, LITECOIN) + const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: LITECOIN }) assert.strictEqual(address, 'LZJSxZbjqJ2XVEquqfqHg1RQTDdfST5PTn') assert.strictEqual(wif, 'T7A4PUSgTDHecBxW1ZiYFrDNRih2o7M8Gf9xpoCgudPF9gDiNvuS') diff --git a/test/integration/bip32.js b/test/integration/bip32.js index c780267..e6d5721 100644 --- a/test/integration/bip32.js +++ b/test/integration/bip32.js @@ -5,12 +5,8 @@ const bip32 = require('bip32') const bip39 = require('bip39') const bitcoin = require('../../') -// TODO: remove -const baddress = bitcoin.address -const bcrypto = bitcoin.crypto function getAddress (node, network) { - network = network || bitcoin.networks.bitcoin - return baddress.toBase58Check(bcrypto.hash160(node.publicKey), network.pubKeyHash) + return bitcoin.payments.p2pkh({ pubkey: node.publicKey, network }).address } describe('bitcoinjs-lib (BIP32)', function () { diff --git a/test/integration/stealth.js b/test/integration/stealth.js index 01a933b..813f48b 100644 --- a/test/integration/stealth.js +++ b/test/integration/stealth.js @@ -4,11 +4,8 @@ const assert = require('assert') const bitcoin = require('../../') const ecc = require('tiny-secp256k1') -// TODO: remove -const baddress = bitcoin.address -const bcrypto = bitcoin.crypto -function getAddress (node) { - return baddress.toBase58Check(bcrypto.hash160(node.publicKey), bitcoin.networks.bitcoin.pubKeyHash) +function getAddress (node, network) { + return bitcoin.payments.p2pkh({ pubkey: node.publicKey, network }).address } // vG = (dG \+ sha256(e * dG)G) diff --git a/test/integration/transactions.js b/test/integration/transactions.js index 3235851..991e0b6 100644 --- a/test/integration/transactions.js +++ b/test/integration/transactions.js @@ -5,14 +5,6 @@ const bitcoin = require('../../') const regtestUtils = require('./_regtest') const regtest = regtestUtils.network -// TODO: remove -const baddress = bitcoin.address -const bcrypto = bitcoin.crypto -function getAddress (node, network) { - network = network || bitcoin.networks.bitcoin - return baddress.toBase58Check(bcrypto.hash160(node.publicKey), network.pubKeyHash) -} - function rng () { return Buffer.from('YT8dAtK4d16A3P1z+TpwB2jJ4aFH3g9M1EioIBkLEV4=', 'base64') } @@ -59,18 +51,22 @@ describe('bitcoinjs-lib (transactions)', function () { const alice2 = bitcoin.ECPair.makeRandom({ network: regtest }) const aliceChange = bitcoin.ECPair.makeRandom({ network: regtest, rng: rng }) + const alice1pkh = bitcoin.payments.p2pkh({ pubkey: alice1.publicKey, network: regtest }) + const alice2pkh = bitcoin.payments.p2pkh({ pubkey: alice2.publicKey, network: regtest }) + const aliceCpkh = bitcoin.payments.p2pkh({ pubkey: aliceChange.publicKey, network: regtest }) + // give Alice 2 unspent outputs - regtestUtils.faucet(getAddress(alice1, regtest), 5e4, function (err, unspent0) { + regtestUtils.faucet(alice1pkh.address, 5e4, function (err, unspent0) { if (err) return done(err) - regtestUtils.faucet(getAddress(alice2, regtest), 7e4, function (err, unspent1) { + regtestUtils.faucet(alice2pkh.address, 7e4, function (err, unspent1) { if (err) return done(err) const txb = new bitcoin.TransactionBuilder(regtest) txb.addInput(unspent0.txId, unspent0.vout) // alice1 unspent txb.addInput(unspent1.txId, unspent1.vout) // alice2 unspent txb.addOutput('mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf', 8e4) // the actual "spend" - txb.addOutput(getAddress(aliceChange, regtest), 1e4) // Alice's change + txb.addOutput(aliceCpkh.address, 1e4) // Alice's change // (in)(4e4 + 2e4) - (out)(1e4 + 3e4) = (fee)2e4 = 20000, this is the miner fee // Alice signs each input with the respective private keys @@ -88,8 +84,9 @@ describe('bitcoinjs-lib (transactions)', function () { this.timeout(30000) const keyPair = bitcoin.ECPair.makeRandom({ network: regtest }) + const p2pkh = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: regtest }) - regtestUtils.faucet(getAddress(keyPair, regtest), 2e5, function (err, unspent) { + regtestUtils.faucet(p2pkh.address, 2e5, function (err, unspent) { if (err) return done(err) const txb = new bitcoin.TransactionBuilder(regtest) @@ -150,20 +147,16 @@ describe('bitcoinjs-lib (transactions)', function () { this.timeout(30000) const keyPair = bitcoin.ECPair.makeRandom({ network: regtest }) - const pubKeyHash = bitcoin.crypto.hash160(keyPair.publicKey) + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network: regtest }) + const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network: regtest }) - const redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash) - const redeemScriptHash = bitcoin.crypto.hash160(redeemScript) - const scriptPubKey = bitcoin.script.scriptHash.output.encode(redeemScriptHash) - const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest) - - regtestUtils.faucet(address, 5e4, function (err, unspent) { + regtestUtils.faucet(p2sh.address, 5e4, function (err, unspent) { if (err) return done(err) const txb = new bitcoin.TransactionBuilder(regtest) txb.addInput(unspent.txId, unspent.vout) txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4) - txb.sign(0, keyPair, redeemScript, null, unspent.value) + txb.sign(0, keyPair, p2sh.redeem.output, null, unspent.value) const tx = txb.build() @@ -190,22 +183,21 @@ describe('bitcoinjs-lib (transactions)', function () { bitcoin.ECPair.makeRandom({ network: regtest }), bitcoin.ECPair.makeRandom({ network: regtest }) ] - const pubKeys = keyPairs.map(function (x) { return x.publicKey }) + const pubkeys = keyPairs.map(x => x.publicKey) - const witnessScript = bitcoin.script.multisig.output.encode(3, pubKeys) - const redeemScript = bitcoin.script.witnessScriptHash.output.encode(bitcoin.crypto.sha256(witnessScript)) - const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript)) - const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest) + const p2ms = bitcoin.payments.p2ms({ m: 3, pubkeys, network: regtest }) + const p2wsh = bitcoin.payments.p2wsh({ redeem: p2ms, network: regtest }) + const p2sh = bitcoin.payments.p2sh({ redeem: p2wsh, network: regtest }) - regtestUtils.faucet(address, 6e4, function (err, unspent) { + regtestUtils.faucet(p2sh.address, 6e4, function (err, unspent) { if (err) return done(err) const txb = new bitcoin.TransactionBuilder(regtest) - txb.addInput(unspent.txId, unspent.vout) + txb.addInput(unspent.txId, unspent.vout, null, p2sh.output) txb.addOutput(regtestUtils.RANDOM_ADDRESS, 3e4) - txb.sign(0, keyPairs[0], redeemScript, null, unspent.value, witnessScript) - txb.sign(0, keyPairs[2], redeemScript, null, unspent.value, witnessScript) - txb.sign(0, keyPairs[3], redeemScript, null, unspent.value, witnessScript) + txb.sign(0, keyPairs[0], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output) + txb.sign(0, keyPairs[2], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output) + txb.sign(0, keyPairs[3], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output) const tx = txb.build() @@ -235,12 +227,14 @@ describe('bitcoinjs-lib (transactions)', function () { tx.ins.forEach(function (input, i) { const keyPair = keyPairs[i] - const prevOutScript = bitcoin.address.toOutputScript(getAddress(keyPair)) - const scriptSig = bitcoin.script.pubKeyHash.input.decode(input.script) - const ss = bitcoin.script.signature.decode(scriptSig.signature) - const hash = tx.hashForSignature(i, prevOutScript, ss.hashType) + const p2pkh = bitcoin.payments.p2pkh({ + pubkey: keyPair.publicKey, + input: input.script + }) + + const ss = bitcoin.script.signature.decode(p2pkh.signature) + const hash = tx.hashForSignature(i, p2pkh.output, ss.hashType) - assert.strictEqual(scriptSig.pubKey.toString('hex'), keyPair.publicKey.toString('hex')) assert.strictEqual(keyPair.verify(hash, ss.signature), true) }) })