diff --git a/test/fixtures/transaction_builder.json b/test/fixtures/transaction_builder.json index 6896f30..7a3a8d2 100644 --- a/test/fixtures/transaction_builder.json +++ b/test/fixtures/transaction_builder.json @@ -1547,6 +1547,28 @@ ] } ], + "fromTransactionSequential": [ + { + "description": "Transaction w/ P2SH(P2MS 2/3) -> ?", + "network": "testnet", + "txHex": "0100000001b033b2214568b49fda417371aba0634b0303a2b6a19884c25d03d0b91bdbe231000000006f000000004c6952210258db1bb3801f1ecde47602143beaeb9cac93251724b8e589fae5c08c1a399a9121038e803e3d84cfc821cc8bf46233a9c2bb359d529db0bcdd3f1a4f38678dd02d7f2103b83e59d848407d7f62a82c99905f5ca3e8e8f5d6400eb78a0b4b067aea0720d953aeffffffff0200e1f5050000000017a914a9974100aeee974a20cda9a2f545704a0ab54fdc87c72831010000000017a9149f57a6712ef023f85ffac631ed4263b977b2d0678700000000", + "txHexAfter": "0100000001b033b2214568b49fda417371aba0634b0303a2b6a19884c25d03d0b91bdbe23100000000b60000004730440220793d87f2a8afeb856816efa38984418c692c15170e99ca371f547454079c0dd3022074ae95e438fee1f37619fabe0ce1083c3be0d65c3defb5337833d50fdc694b13014c6952210258db1bb3801f1ecde47602143beaeb9cac93251724b8e589fae5c08c1a399a9121038e803e3d84cfc821cc8bf46233a9c2bb359d529db0bcdd3f1a4f38678dd02d7f2103b83e59d848407d7f62a82c99905f5ca3e8e8f5d6400eb78a0b4b067aea0720d953aeffffffff0200e1f5050000000017a914a9974100aeee974a20cda9a2f545704a0ab54fdc87c72831010000000017a9149f57a6712ef023f85ffac631ed4263b977b2d0678700000000", + "incomplete": true, + "inputs": [ + { + "vout": 0, + "scriptSig": "OP_0 OP_0 OP_0 OP_0 52210258db1bb3801f1ecde47602143beaeb9cac93251724b8e589fae5c08c1a399a9121038e803e3d84cfc821cc8bf46233a9c2bb359d529db0bcdd3f1a4f38678dd02d7f2103b83e59d848407d7f62a82c99905f5ca3e8e8f5d6400eb78a0b4b067aea0720d953ae", + "scriptSigAfter": "OP_0 OP_0 OP_0 30440220793d87f2a8afeb856816efa38984418c692c15170e99ca371f547454079c0dd3022074ae95e438fee1f37619fabe0ce1083c3be0d65c3defb5337833d50fdc694b1301 52210258db1bb3801f1ecde47602143beaeb9cac93251724b8e589fae5c08c1a399a9121038e803e3d84cfc821cc8bf46233a9c2bb359d529db0bcdd3f1a4f38678dd02d7f2103b83e59d848407d7f62a82c99905f5ca3e8e8f5d6400eb78a0b4b067aea0720d953ae", + "signs": [ + { + "keyPair": "cTkcnMZoFYH1UgumzCFHv2veLMNN1PaJyHHUxFT127zhNGBqqEZ2", + "redeemScript": "OP_2 0258db1bb3801f1ecde47602143beaeb9cac93251724b8e589fae5c08c1a399a91 038e803e3d84cfc821cc8bf46233a9c2bb359d529db0bcdd3f1a4f38678dd02d7f 03b83e59d848407d7f62a82c99905f5ca3e8e8f5d6400eb78a0b4b067aea0720d9 OP_3 OP_CHECKMULTISIG" + } + ] + } + ] + } + ], "classification": { "hex": "01000000059c06fb641a8cd69be81ca91e68d8a115cb698396876ecd77120ec1e4ab9002279f000000b500483045022100d58f828ab39cfac592f89fe372fb520992975218698c683a893f29e39cf0080302207cc0485dab5ce621089bdd15e1f15db0ecbde8dd4bb661bcf0e3af6ecab075e6014c6952210327e023a353d111808f61d554c2e1934721eaf87f33b7a771e807006908a493722103251670bb6a179a0d43b75476c7e580c0ba274378a18077e8de0832c870e5381f2102cca7f9a64425a0466d26d5c7e9eb3ad6b64cd48ea89edb38bc08f58a792dde4753aeffffffff0821dc00213d2b7993f8f2a1553800c6f2f31106da176505d0ade467b68401d795000000b400473044022028e937a7bba888fe3428f442f6e22d92ce2ddba01548c38780d40890fa6cc305022043204d0bcfb1150b045d54cf9b13462e44e2ef47fee03d3cea08e84a8060fc30014c6952210327e023a353d111808f61d554c2e1934721eaf87f33b7a771e807006908a493722103251670bb6a179a0d43b75476c7e580c0ba274378a18077e8de0832c870e5381f2102cca7f9a64425a0466d26d5c7e9eb3ad6b64cd48ea89edb38bc08f58a792dde4753aeffffffffaa997ac385dc666af1f5947ef615431024eb314cac2308d5e1b903e28ca466f499000000b50048304502210093efc26facedc5f51e304aa270a7b4f1a911b2d912c3674e5c6e2ad4ac7a410402201cf0b62c240461902f9f16d8a0bc3a210b7bfcd2c06523dd4b4b63be22e85252014c6952210327e023a353d111808f61d554c2e1934721eaf87f33b7a771e807006908a493722103251670bb6a179a0d43b75476c7e580c0ba274378a18077e8de0832c870e5381f2102cca7f9a64425a0466d26d5c7e9eb3ad6b64cd48ea89edb38bc08f58a792dde4753aeffffffffd9f61bf98a021ee144f33ba5a6b04274de8fcb5c05f1ff7c12367fb7a608b2dd9e000000b4004730440220456e1201c1fa727288cba7fa0054dc02d8dd6c7418cae1e97006ef0652891c9202201192d0fbf3a9c00afb99a415f2bf515509e1150805acd8de95c496c27cb6570f014c6952210327e023a353d111808f61d554c2e1934721eaf87f33b7a771e807006908a493722103251670bb6a179a0d43b75476c7e580c0ba274378a18077e8de0832c870e5381f2102cca7f9a64425a0466d26d5c7e9eb3ad6b64cd48ea89edb38bc08f58a792dde4753aeffffffff1f8119e3bc7c2f451feaa79f42ec5a63502afb425c253c935e43d217d5c29bdea1000000b500483045022100f669004f770490093eba4ac4903cb7581f7d18ea9245c538585ef5367e520e4702205485fafe0be178563a599d41e0cc172bb01314ed65d0e48df19a5258f17bdbc4014c6952210327e023a353d111808f61d554c2e1934721eaf87f33b7a771e807006908a493722103251670bb6a179a0d43b75476c7e580c0ba274378a18077e8de0832c870e5381f2102cca7f9a64425a0466d26d5c7e9eb3ad6b64cd48ea89edb38bc08f58a792dde4753aeffffffff0380f0fa02000000001976a91439692085cf9d27e8c1cf63e76bd32d9bd15cab8b88ac50c300000000000017a9147204bb26950ce1595255897f63d205779f033f3e875b5409000000000017a9142538893d984a4b5695e4bfde1a90a9f02fabf8e38700000000" }, diff --git a/test/transaction_builder.js b/test/transaction_builder.js index 34ec9da..93f407e 100644 --- a/test/transaction_builder.js +++ b/test/transaction_builder.js @@ -19,9 +19,46 @@ function getAddress (node) { return baddress.toBase58Check(bcrypto.hash160(node.publicKey), NETWORKS.bitcoin.pubKeyHash) } +function constructSign (f, txb) { + const network = NETWORKS[f.network] + const stages = f.stages && f.stages.concat() + + f.inputs.forEach(function (input, index) { + if (!input.signs) return + input.signs.forEach(function (sign) { + const keyPair = ECPair.fromWIF(sign.keyPair, network) + let redeemScript + let witnessScript + let value + + if (sign.redeemScript) { + redeemScript = bscript.fromASM(sign.redeemScript) + } + + if (sign.value) { + value = sign.value + } + + if (sign.witnessScript) { + witnessScript = bscript.fromASM(sign.witnessScript) + } + + txb.sign(index, keyPair, redeemScript, sign.hashType, value, witnessScript) + + if (sign.stage) { + const tx = txb.buildIncomplete() + assert.strictEqual(tx.toHex(), stages.shift()) + txb = TransactionBuilder.fromTransaction(tx, network) + } + }) + }) + + return txb +} + function construct (f, dontSign) { const network = NETWORKS[f.network] - let txb = new TransactionBuilder(network) + const txb = new TransactionBuilder(network) if (Number.isFinite(f.version)) txb.setVersion(f.version) if (f.locktime !== undefined) txb.setLockTime(f.locktime) @@ -55,39 +92,7 @@ function construct (f, dontSign) { }) if (dontSign) return txb - - const stages = f.stages && f.stages.concat() - f.inputs.forEach(function (input, index) { - if (!input.signs) return - input.signs.forEach(function (sign) { - const keyPair = ECPair.fromWIF(sign.keyPair, network) - let redeemScript - let witnessScript - let value - - if (sign.redeemScript) { - redeemScript = bscript.fromASM(sign.redeemScript) - } - - if (sign.value) { - value = sign.value - } - - if (sign.witnessScript) { - witnessScript = bscript.fromASM(sign.witnessScript) - } - - txb.sign(index, keyPair, redeemScript, sign.hashType, value, witnessScript) - - if (sign.stage) { - const tx = txb.buildIncomplete() - assert.strictEqual(tx.toHex(), stages.shift()) - txb = TransactionBuilder.fromTransaction(tx, network) - } - }) - }) - - return txb + return constructSign(f, txb) } describe('TransactionBuilder', function () { @@ -142,6 +147,27 @@ describe('TransactionBuilder', function () { }) }) + fixtures.valid.fromTransactionSequential.forEach(function (f) { + it('with ' + f.description, function () { + const network = NETWORKS[f.network] + const tx = Transaction.fromHex(f.txHex) + const txb = TransactionBuilder.fromTransaction(tx, network) + + tx.ins.forEach(function (input, i) { + assert.equal(bscript.toASM(input.script), f.inputs[i].scriptSig) + }) + + constructSign(f, txb) + const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build() + + txAfter.ins.forEach(function (input, i) { + assert.equal(bscript.toASM(input.script), f.inputs[i].scriptSigAfter) + }) + + assert.equal(txAfter.toHex(), f.txHexAfter) + }) + }) + it('classifies transaction inputs', function () { const tx = Transaction.fromHex(fixtures.valid.classification.hex) const txb = TransactionBuilder.fromTransaction(tx)