bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.67k stars 2.1k forks source link

Get error "Can not sign for this input with the key" when migrating from TransactionBuilder to Psbt #1551

Closed HarryMarch closed 4 years ago

HarryMarch commented 4 years ago

Error: Can not sign for this input with the key

I got this error when tried to create a raw transaction with testnet, p2pkh address. Everything works fine if I use TransactionBuilder, except the warning message told me should use Psbt. When using signInput method, my pubkey seems not to match with utxo input.

This is my getPrivateKey function from mnemonic string, works fine with TransactionBuilder

const seed = bip39.mnemonicToSeedSync(mnemonic);
const root = bip32.fromSeed(seed, list_networks['test']);
const child = root
    .deriveHardened(44)
    .deriveHardened(coin_type['test'].index)
    .deriveHardened(0)
    .derive(0)
    .derive(index = 0);

return bitcoin.ECPair.fromPrivateKey(child.privateKey, { network: list_networks['test'] });

And this is my new createRawTransaction

// Get Private Key From Mnemonic Word Lists 
const key = getPrivateKey(mnemonic);
// Create Psbt Instance
const psbt = new bitcoin.Psbt({ network: list_networks['test'] });
// Add Unspent transaction outputs
utxos.forEach(utxo => {
// this object is from getrawtransaction bitcoin-cli
  psbt.addInput({
      hash: utox.hash,
      index: utox.index,
      nonWitnessUtxo: Buffer.from(utox.hex, 'hex'),
  })
});
// Add Output To Destination address
psbt.addOutput({
        address: destination,
        value: amount,
});
// Sign utxos Input
for (let i = 0; i < utxos.length; i++) {
     psbt.signInput(i, key); // worked with TransactionBuilder.sign 
}

What's missing? Shoud I stay with TransactionBuilder?

dakk commented 4 years ago

I'm not sure, but try to add a redeemScript to the input object passed to addInput()

HarryMarch commented 4 years ago

I'm not sure, but try to add a redeemScript to the input object passed to addInput()

https://github.com/bitcoinjs/bitcoinjs-lib/blob/c95e15de01519b30c5eeb0f89700d03e49afb0e1/test/integration/transactions.spec.ts#L54 It seems like redeemScript is unnecessary for p2pkh address.

dakk commented 4 years ago

You are right; is utox.hex the entire transaction or only the output? You need to put the whole transaction.

junderw commented 4 years ago

could you give us the data you used to get your error?

some (not all) possibilities:

HarryMarch commented 4 years ago

could you give us the data you used to get your error?

some (not all) possibilities:

  • uncompressed key
  • wrong path

The pubkey and pubkeyHash do not match with decompiled. Maybe my private key is wrong?

junderw commented 4 years ago

ah

it could also be the misspell of utxo

you reference utox, maybe it's passing undefined?

junderw commented 4 years ago

could you give us the data you used to get your error? some (not all) possibilities:

  • uncompressed key
  • wrong path

The pubkey and pubkeyHash do not match with decompiled. Maybe my private key is wrong?

that too.

that's what the error is saying.

HarryMarch commented 4 years ago

I did a quick check, the private key is fine with TransactionBuilder

HarryMarch commented 4 years ago

ah

it could also be the misspell of utxo

you reference utox, maybe it's passing undefined?

I rechecked the utxo object, with TransactionBuilder just need index, hash, but with Psbt we also need hex value right? I got hex value from the command bitcoin-cli getrawtransaction txid for nonWitnessUtxo. Can you please confirm what I did?

junderw commented 4 years ago

Did your signed transaction actually propagate and get in a block.

junderw commented 4 years ago

I rechecked the utxo object, with TransactionBuilder just need index, hash, but with Psbt we also need hex value right? I got hex value from the command bitcoin-cli getrawtransaction txid for nonWitnessUtxo. Can you please confirm what I did?

can you please just share the data?

you're using testnet, right?

then no one cares about your private keys.

it's like you're asking a doctor to diagnose a problem over the phone. lol

junderw commented 4 years ago
const bitcoin = require('bitcoinjs-lib')
const assert = require('assert')

const address = 'mkQ79xVG8agqxSNGyisAfQXg2CwL1ewamg'
const pubkey = Buffer.from('0300d89d29a8066b5f631187ec2c1065c5106d49b202ac8f0aa7287ccb7744c689', 'hex')
const wif = 'cP4Fzx3VSwpbfZbvyA4Fedj8tv6MePkWS1ieC5TaXhVipaaqU3Qi'

const key = bitcoin.ECPair.fromWIF(wif, bitcoin.networks.testnet)

assert(pubkey.equals(key.publicKey))
assert(address ===
    bitcoin.payments.p2pkh({
        pubkey,
        network: bitcoin.networks.testnet,
    }).address
)

console.log('Verified data...')

// pulled some data directly from a block explorer
const utxoTxHash = '544ca9285dfa5d44f71c06d4d0a7583dc48cade0b02e57b3f58f64e780850739'
const utxoOutputIndex = 0
const utxoOutputValue = 10000
const utxoTxFullHex = '0200000000010114d5fe5fe2a54a4b70aef5e3949e7e3429dcd434f909ba40efb928a5ca7cf86c01000000171600141d4a8ff6c6fa5ccfbc117be2bf381ae14afa8e57feffffff0210270000000000001976a914358d1d0d01f1abbb0fb49cf3d8475ea5500a518b88ac4c8341b40100000017a91482ecd3358fd7da4ff7cfc3db9f24e3dd3f1f814d870247304402200f0dc50e267a7227cbe57daf7881b96a2ba1b52fe750f4313f8ef0d52fe76c8e02201d2d106ca4431a8d6213c272bc04ec3fe4e8e78971209181027b8bd124d7275e012102a2dc69cd0197a429baefbf7657213a67985608919391e5a7777bcf47ab2c676acad31900'

// Create Psbt Instance
const psbt = new bitcoin.Psbt({ network: bitcoin.networks.testnet })

psbt.addInput({
  hash: utxoTxHash,
  index: utxoOutputIndex,
  nonWitnessUtxo: Buffer.from(utxoTxFullHex, 'hex'),
})

// Add Output To Destination address
psbt.addOutput({
        address: address, // send to self
        value: utxoOutputValue - 1000,
})
// Sign utxos Input
psbt.signInput(0, key)

console.log('Finished Signing PSBT...')

I have verified nothing is wrong on our end. Please feel free to continue troubleshooting here though. I will close the issue.

Try logging everything at every point of the code and show me all the log outputs and maybe we can find the culprit.

HarryMarch commented 4 years ago

I found out what I been missing. I passed a wrong utxo input index value. Sorry for wasting your time at the weekend. But I knew you'd show up as usual to help wandering people like me.