Closed omrip30 closed 5 years ago
Can you please provide reproduction code?
Hi, Basically I receive a multisig(2-3) transaction without signatures and I sign it with one private key. Also, each input contains the redeem script:
const bitcoin = require('bitcoinjs-lib')
const wif = require('wif')
const privateHex = 'b820275a9d01127063bf0d134cccfa2250437590d51068e85fb058af1a0c18e5'
const txHex = '0100000001b033b2214568b49fda417371aba0634b0303a2b6a19884c25d03d0b91bdbe231000000006f000000004c6952210258db1bb3801f1ecde47602143beaeb9cac93251724b8e589fae5c08c1a399a9121038e803e3d84cfc821cc8bf46233a9c2bb359d529db0bcdd3f1a4f38678dd02d7f2103b83e59d848407d7f62a82c99905f5ca3e8e8f5d6400eb78a0b4b067aea0720d953aeffffffff0200e1f5050000000017a914a9974100aeee974a20cda9a2f545704a0ab54fdc87c72831010000000017a9149f57a6712ef023f85ffac631ed4263b977b2d0678700000000'
const tx = bitcoin.Transaction.fromHex(txHex) // missing, added by @dcousens
const txb = bitcoin.TransactionBuilder.fromTransaction(tx, bitcoin.networks.testnet)
const privateKey = Buffer.from(privateHex, 'hex')
const wifKey = wif.encode(239, privateKey, true)
const keyPair = bitcoin.ECPair.fromWIF(wifKey, bitcoin.networks.testnet)
for (let i = 0; i < txb.__inputs.length; i++) {
txb.sign(i, keyPair)
}
const privateKey = Buffer.from(privateHex, 'hex')
const wifKey = wif.encode(239, privateKey, true)
const keyPair = bitcoin.ECPair.fromWIF(wifKey, bitcoin.networks.testnet)
Could be
const privateKey = Buffer.from(privateHex, 'hex')
const keyPair = bitcoin.ECPair.fromPrivateKey(privateKey, { network: bitcoin.networks.testnet })
That's great, but the interesting part is:
for (let i = 0; i < txb.__inputs.length; i++) { txb.sign(i, keyPair) }
That's the one that throws the error.
Don't use txb.__inputs.length
, you have the transaction, use tx.ins.length
.
const privateKey = Buffer.from('b820275a9d01127063bf0d134cccfa2250437590d51068e85fb058af1a0c18e5', 'hex')
const txHex = '0100000001b033b2214568b49fda417371aba0634b0303a2b6a19884c25d03d0b91bdbe231000000006f000000004c6952210258db1bb3801f1ecde47602143beaeb9cac93251724b8e589fae5c'
const keyPair = bitcoin.ECPair.fromPrivateKey(privateKey, { network: bitcoin.networks.testnet })
const tx = bitcoin.Transaction.fromHex(txHex)
const txb = bitcoin.TransactionBuilder.fromTransaction(tx, bitcoin.networks.testnet)
for (let i = 0; i < tx.ins.length; i++) {
txb.sign(i, keyPair)
}
That said, it might be useful to have some way of accessing that information via the TransactionBuilder
API...
Thanks:) I tried the accessing the 'tx.ins' property but it was undefined for some reason. Anyway, I think that a getter for the inputs should be added to the TransactionBuilder API
You're awesome, thanks!
@omrip30 I've used your test fixture directly in https://github.com/bitcoinjs/bitcoinjs-lib/pull/1181#discussion_r211510641, thanks for the bug report :+1:
When creating a 'TransactionBuilder' object from an existing transaction and then signing an input, an error is thrown ('PrevOutScript is scripthash, requires redeemScript') even when the redeem script exists inside the input. The only way to avoid this is to add the redeem script again as the third parameter of the 'sign' method. Expected behaviour: the 'sign' function should check if the redeem script exists inside the input and if it does, it should use it (if no extra redeem script was provided as a parameter)