Merge pull request #1133 from bitcoinjs/p2wpkhtest

tests: add bare P2W* integration tests (and fix a bug)
This commit is contained in:
Jonathan Underwood 2018-07-17 21:58:01 +09:00 committed by GitHub
commit 4b7c49d92d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 105 additions and 10 deletions

View file

@ -99,6 +99,7 @@ Some examples interact (via HTTPS) with a 3rd Party Blockchain Provider (3PBP).
- [Create (and broadcast via 3PBP) a Transaction with an OP\_RETURN output](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L87) - [Create (and broadcast via 3PBP) a Transaction with an OP\_RETURN output](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L87)
- [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#L109) - [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#L109)
- [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#L149) - [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#L149)
- [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 3-of-4 P2SH(P2WSH(multisig)) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L184) - [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#L184)
- [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L17) - [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L17)
- [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L24) - [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L24)

View file

@ -233,10 +233,10 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
} }
return { return {
redeemScript: redeemScript, redeemScript,
redeemScriptType: SCRIPT_TYPES.P2WSH, redeemScriptType: SCRIPT_TYPES.P2WSH,
witnessScript: witnessScript, witnessScript,
witnessScriptType: expanded.type, witnessScriptType: expanded.type,
prevOutType: SCRIPT_TYPES.P2SH, prevOutType: SCRIPT_TYPES.P2SH,
@ -274,14 +274,14 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
} }
return { return {
redeemScript: redeemScript, redeemScript,
redeemScriptType: expanded.type, redeemScriptType: expanded.type,
prevOutType: SCRIPT_TYPES.P2SH, prevOutType: SCRIPT_TYPES.P2SH,
prevOutScript: p2sh.output, prevOutScript: p2sh.output,
hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH, hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH,
signScript: signScript, signScript,
signType: expanded.type, signType: expanded.type,
pubkeys: expanded.pubkeys, pubkeys: expanded.pubkeys,
@ -304,7 +304,7 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
} }
return { return {
witnessScript: witnessScript, witnessScript,
witnessScriptType: expanded.type, witnessScriptType: expanded.type,
prevOutType: SCRIPT_TYPES.P2WSH, prevOutType: SCRIPT_TYPES.P2WSH,
@ -331,12 +331,17 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
expanded.signatures = input.signatures expanded.signatures = input.signatures
} }
let signScript = input.prevOutScript
if (expanded.type === SCRIPT_TYPES.P2WPKH) {
signScript = payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output
}
return { return {
prevOutType: expanded.type, prevOutType: expanded.type,
prevOutScript: input.prevOutScript, prevOutScript: input.prevOutScript,
hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH, hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH,
signScript: input.prevOutScript, signScript,
signType: expanded.type, signType: expanded.type,
pubkeys: expanded.pubkeys, pubkeys: expanded.pubkeys,

View file

@ -394,8 +394,8 @@
] ]
}, },
{ {
"description": "Transaction w/ P2WPKH -> P2WPKH", "description": "P2WPKH -> P2WPKH",
"txHex": "01000000000101ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff011027000000000000160014aa4d7985c57e011a8b3dd8e0e5a73aaef41629c502483045022100b4a9d46ea4d38d6b3ea098911c9f72c0ae6ebc72408e6be7880a6b22a4b3e4da02207996107d0e6437f80363f96f502a38f275156f7501ea51f67899ba78a0c129c101210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800000000", "txHex": "01000000000101ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff011027000000000000160014aa4d7985c57e011a8b3dd8e0e5a73aaef41629c502483045022100a8fc5e4c6d7073474eff2af5d756966e75be0cdfbba299518526080ce8b584be02200f26d41082764df89e3c815b8eaf51034a3b68a25f1be51208f54222c1bb6c1601210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800000000",
"version": 1, "version": 1,
"inputs": [ "inputs": [
{ {
@ -834,7 +834,7 @@
}, },
{ {
"description": "SIGHASH V0+V1, (P2PKH, P2WPKH) -> 2x P2PKH", "description": "SIGHASH V0+V1, (P2PKH, P2WPKH) -> 2x P2PKH",
"txHex": "01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000484730440220691a19d365c8d75f921346c70271506bde136f13a4b566dd796902c262e2ec6d02202b00c4aa030eedf294552bdfc163936d2f4e91c59e7798c4471250cf07cb859501eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff0230f45e13000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac00e9a435000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402200a7b08cccedf608e279410091acbd7e990e19a8edf401c3698763d2920de5871022060462ed172a02ecef73ebc19811d8fc72ed68f4419742df70241ad0a5a6a36410121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000", "txHex": "01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000484730440220691a19d365c8d75f921346c70271506bde136f13a4b566dd796902c262e2ec6d02202b00c4aa030eedf294552bdfc163936d2f4e91c59e7798c4471250cf07cb859501eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff0230f45e13000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac00e9a435000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac0002483045022100fddd014889f18d489b5400bfa8cb0a32301a768d934b1a0e2b55398119f26cab02207676c64c16ffa7ffaaf8e16b3b74e916687eebdfdb36b9b7997e838384d464640121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000",
"version": 1, "version": 1,
"inputs": [ "inputs": [
{ {
@ -1314,7 +1314,7 @@
}, },
{ {
"description": "P2WPKH -> P2PKH", "description": "P2WPKH -> P2PKH",
"txHex": "0100000000010133defbe3e28860007ff3e21222774c220cb35d554fa3e3796d25bf8ee983e1080000000000ffffffff0160ea0000000000001976a914851a33a5ef0d4279bd5854949174e2c65b1d450088ac02483045022100834f56825e880ab7926164458e10582d9fd8df005396b7e51a1efb8db277204e02206a3610b7101c3242643ac9c9d3487c2d28ffdad19ec26a7f81fc100bdac625f10121038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b00000000", "txHex": "0100000000010133defbe3e28860007ff3e21222774c220cb35d554fa3e3796d25bf8ee983e1080000000000ffffffff0160ea0000000000001976a914851a33a5ef0d4279bd5854949174e2c65b1d450088ac0248304502210097c3006f0b390982eb47f762b2853773c6cedf83668a22d710f4c13c4fd6b15502205e26ef16a81fc818a37f3a34fc6d0700e61100ea6c6773907c9c046042c440340121038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b00000000",
"version": 1, "version": 1,
"inputs": [ "inputs": [
{ {

View file

@ -171,6 +171,95 @@ describe('bitcoinjs-lib (transactions)', function () {
}) })
}) })
it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input (via a P2SH(P2WPKH) transaction)', function (done) {
this.timeout(30000)
const keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network: regtest })
// prepare a P2SH(P2WPKH) faucet transaction, as Bitcoin-core doesn't support bare P2WPKH outputs (...yet)
const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network: regtest })
regtestUtils.faucet(p2sh.address, 10e4, function (err, unspent) {
if (err) return done(err)
const txvb = new bitcoin.TransactionBuilder(regtest)
txvb.addInput(unspent.txId, unspent.vout)
txvb.addOutput(p2wpkh.address, 6e4) // funds a P2WPKH address
txvb.sign(0, keyPair, p2sh.redeem.output, null, unspent.value)
const txv = txvb.build()
// build and broadcast (the via transaction) to the Bitcoin RegTest network
regtestUtils.broadcast(txv.toHex(), function (err) {
if (err) return done(err)
// XXX: build the Transaction w/ a P2WPKH input
const txb = new bitcoin.TransactionBuilder(regtest)
txb.addInput(txv.getId(), 0, null, p2wpkh.output) // NOTE: provide the prevOutScript!
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
txb.sign(0, keyPair, null, null, 6e4) // NOTE: no redeem script
const tx = txb.build()
// build and broadcast (the P2WPKH transaction) to the Bitcoin RegTest network
regtestUtils.broadcast(tx.toHex(), function (err) {
if (err) return done(err)
regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
value: 2e4
}, done)
})
})
})
})
it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WSH(P2PK) input (via a P2SH(P2PK) transaction)', function (done) {
this.timeout(30000)
const keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
const p2pk = bitcoin.payments.p2pk({ pubkey: keyPair.publicKey, network: regtest })
const p2wsh = bitcoin.payments.p2wsh({ redeem: p2pk, network: regtest })
// prepare a P2SH(P2PK) faucet transaction, as Bitcoin-core doesn't support bare P2WSH outputs (...yet)
const p2sh = bitcoin.payments.p2sh({ redeem: p2pk, network: regtest })
regtestUtils.faucet(p2sh.address, 10e4, function (err, unspent) {
if (err) return done(err)
const txvb = new bitcoin.TransactionBuilder(regtest)
txvb.addInput(unspent.txId, unspent.vout)
txvb.addOutput(p2wsh.address, 6e4) // funds a P2WPKH address
txvb.sign(0, keyPair, p2sh.redeem.output)
const txv = txvb.build()
// build and broadcast (the via transaction) to the Bitcoin RegTest network
regtestUtils.broadcast(txv.toHex(), function (err) {
if (err) return done(err)
// XXX: build the Transaction w/ a P2WSH input
const txb = new bitcoin.TransactionBuilder(regtest)
txb.addInput(txv.getId(), 0, null, p2wsh.output) // NOTE: provide the prevOutScript!
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
txb.sign(0, keyPair, null, null, 6e4, p2wsh.redeem.output) // NOTE: provide a witnessScript!
const tx = txb.build()
// build and broadcast (the P2WSH transaction) to the Bitcoin RegTest network
regtestUtils.broadcast(tx.toHex(), function (err) {
if (err) return done(err)
regtestUtils.verify({
txId: tx.getId(),
address: regtestUtils.RANDOM_ADDRESS,
vout: 0,
value: 2e4
}, done)
})
})
})
})
it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input', function (done) { it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input', function (done) {
this.timeout(50000) this.timeout(50000)