bitcoinjs / bitcoinjs-lib

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

How do I spend a p2pk output? #1357

Closed aitorjs closed 5 years ago

aitorjs commented 5 years ago

Having this UTXO on a regtest:

{ txid:
   '5a2a44d78e5ea2136708e9754cd281d4bc0c654f191ae4af567940c6970f7364',
  vout: 0,
  address: 'mmr8Lpjh6HbCkRNH7qTDUAqsELaCv28bUi',
  scriptPubKey:
   '21021f016ed751a3bf635582d746bb72617379ac20325a5a323170cb8f46b2adde33ac',
  amount: 50,
  confirmations: 101,
  spendable: true,
  solvable: true,
  safe: true }

and this peace of code:

    const unspent = JSON.parse(body).result[0]
    console.log('Post successful: response: ', unspent)

    txb.addInput(unspent.txid, unspent.vout)
    txb.addOutput('2N96K4hpjAAh5AmRcFKfjqTXoW78EGwtPuM', 1)
    txb.addOutput('mmr8Lpjh6HbCkRNH7qTDUAqsELaCv28bUi', value - 500)

    const miner = bitcoin.ECPair.fromWIF('cTB7kygwJUB7BpWb3ivefP71Hohq5dt8EfXAcEgAgd6k9f5eTCtR', bitcoin.networks.regtest)
    txb.sign(0, miner)

I get "mandatory-script-verify-flag-failed (Signature is found in scriptCode) (code 16)" error. ¿Any idea why is happening? Decoderawtransaction return:

bitcoin-cli -rpcpassword=a -rpcuser=a -rpcport=18443 -regtest -named decoderawtransaction hexstring=020000000164730f97c6407956afe41a194f650cbcd481d24c75e9086713a25e8ed7442a5a000000006b483045022100b052fed4d85f22f27cc63e1d085ce114c81008e264d718772fd23e9d87458a9302206cfa9fc99242aee86f2171cc711e8c808af63f94985609235cee5e4f99663d640121021f016ed751a3bf635582d746bb72617379ac20325a5a323170cb8f46b2adde33ffffffff02010000000000000017a914add2819cc99bb4b152265c2e4a574577620349dc870cf0052a010000001976a91445710ba0b1897aa3b66c3a40500a4c634ea19b5488ac00000000
{
  "txid": "2559ef7949ec98c7df1fb518898fb5deb144aedd34b563ad48dac0d7eead6d0b",
  "hash": "2559ef7949ec98c7df1fb518898fb5deb144aedd34b563ad48dac0d7eead6d0b",
  "version": 2,
  "size": 224,
  "vsize": 224,
  "weight": 896,
  "locktime": 0,
  "vin": [
    {
      "txid": "5a2a44d78e5ea2136708e9754cd281d4bc0c654f191ae4af567940c6970f7364",
      "vout": 0,
      "scriptSig": {
        "asm": "3045022100b052fed4d85f22f27cc63e1d085ce114c81008e264d718772fd23e9d87458a9302206cfa9fc99242aee86f2171cc711e8c808af63f94985609235cee5e4f99663d64[ALL] 021f016ed751a3bf635582d746bb72617379ac20325a5a323170cb8f46b2adde33",
        "hex": "483045022100b052fed4d85f22f27cc63e1d085ce114c81008e264d718772fd23e9d87458a9302206cfa9fc99242aee86f2171cc711e8c808af63f94985609235cee5e4f99663d640121021f016ed751a3bf635582d746bb72617379ac20325a5a323170cb8f46b2adde33"
      },
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.00000001,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_HASH160 add2819cc99bb4b152265c2e4a574577620349dc OP_EQUAL",
        "hex": "a914add2819cc99bb4b152265c2e4a574577620349dc87",
        "reqSigs": 1,
        "type": "scripthash",
        "addresses": [
          "2N96K4hpjAAh5AmRcFKfjqTXoW78EGwtPuM"
        ]
      }
    },
    {
      "value": 49.99999500,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 45710ba0b1897aa3b66c3a40500a4c634ea19b54 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a91445710ba0b1897aa3b66c3a40500a4c634ea19b5488ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "mmr8Lpjh6HbCkRNH7qTDUAqsELaCv28bUi"
        ]
      }
    }
  ]
}
dabura667 commented 5 years ago

you are spending a p2sh with a p2pkh input. This is wrong.

You must add the redeemScript when signing, see the examples in the tests.

P2SH(Multisig) example:

https://github.com/bitcoinjs/bitcoinjs-lib/blob/02c1cdf1c274c3c7e5219f125894d032532e9b17/test/integration/transactions.js#L100-L134

P2SH(P2WPKH segwit) example:

https://github.com/bitcoinjs/bitcoinjs-lib/blob/02c1cdf1c274c3c7e5219f125894d032532e9b17/test/integration/transactions.js#L136-L163

aitorjs commented 5 years ago

Thanks for the help @dabura667 ! :-)

I change the piece of code for this:

    const miner = bitcoin.ECPair.fromWIF('cTB7kygwJUB7BpWb3ivefP71Hohq5dt8EfXAcEgAgd6k9f5eTCtR', bitcoin.networks.regtest)
    const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: miner.publicKey, network: bitcoin.networks.regtest }) 
    const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network: bitcoin.networks.regtest }) 

    const txb = new bitcoin.TransactionBuilder(bitcoin.networks.regtest)

    const unspent = JSON.parse(body).result[0]
    console.log('Post successful: response: ', unspent)

    txb.addInput(unspent.txid, unspent.vout)
    txb.addOutput('2N96K4hpjAAh5AmRcFKfjqTXoW78EGwtPuM', 49)

    txb.sign(0, miner, p2sh.redeem.output, null, unspent.value) 

but now I get this error: Error: scripthash not supported'. ¿Any ideas please? Thanks! :-D

junderw commented 5 years ago
  1. Which version of Bitcoin Core are you using?
  2. could you post the final raw transaction?
aitorjs commented 5 years ago

Thanks @junderw for the last reply.

1.- $ bitcoin-cli --version

Bitcoin Core RPC client version v0.17.1

2.- No I cant get final raw transaction because I get this error: 'scripthash not supported'. Trace: /home/user/Mahaigaina/prueba/node_modules/bitcoinjs-lib/src/transaction_builder.js:674 if (!canSign(input)) throw Error(input.prevOutType + ' not supported') ^

Error: scripthash not supported at TransactionBuilder.sign (/home/user/Mahaigaina/prueba/node_modules/bitcoinjs-lib/src/transaction_builder.js:674:32) at Request.request [as _callback] (/home/user/Mahaigaina/prueba/index.js:65:9) at Request.self.callback (/home/user/Mahaigaina/prueba/node_modules/request/request.js:185:22) at Request.emit (events.js:182:13) at Request. (/home/user/Mahaigaina/prueba/node_modules/request/request.js:1161:10) at Request.emit (events.js:182:13) at IncomingMessage. (/home/user/Mahaigaina/prueba/node_modules/request/request.js:1083:12) at Object.onceWrapper (events.js:273:13) at IncomingMessage.emit (events.js:187:15) at endReadableNT (_stream_readable.js:1094:12)

Thanks!

aitorjs commented 5 years ago

I find why I get 'scripthash not supported' error.

unspent.value of sign was undefined. I changed for 2e4 and this is the raw transaction:

bitcoin-cli -regtest -named -rpcuser=a -rpcpassword=a decoderawtransaction hexstring=0200000000010164730f97c6407956afe41a194f650cbcd481d24c75e9086713a25e8ed7442a5a000000001716001445710ba0b1897aa3b66c3a40500a4c634ea19b54ffffffff010cf0052a010000001976a914c692fe951985308f8e213d995e87b1b141d3f90688ac0247304402206d78fe18f952dcd87beb9c2ebfd03485be4ca32a17c4cadefc6d95db5a55e0050220784b1f33d4ef7f551d04682476c0d943c0c05a3ee36fb9bce7f904a7bbda54260121021f016ed751a3bf635582d746bb72617379ac20325a5a323170cb8f46b2adde3300000000
{
  "txid": "a509326fcbd2bc0a439d5d11483dfed2e5087c5f53bcac68ab1abf8e4a791ffe",
  "hash": "2f4918709e98a1f3c586ce8f3f0e1236023b928ce7fb39cad999184ae2704e21",
  "version": 2,
  "size": 217,
  "vsize": 136,
  "weight": 541,
  "locktime": 0,
  "vin": [
    {
      "txid": "5a2a44d78e5ea2136708e9754cd281d4bc0c654f191ae4af567940c6970f7364",
      "vout": 0,
      "scriptSig": {
        "asm": "001445710ba0b1897aa3b66c3a40500a4c634ea19b54",
        "hex": "16001445710ba0b1897aa3b66c3a40500a4c634ea19b54"
      },
      "txinwitness": [
        "304402206d78fe18f952dcd87beb9c2ebfd03485be4ca32a17c4cadefc6d95db5a55e0050220784b1f33d4ef7f551d04682476c0d943c0c05a3ee36fb9bce7f904a7bbda542601",
        "021f016ed751a3bf635582d746bb72617379ac20325a5a323170cb8f46b2adde33"
      ],
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 49.99999500,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 c692fe951985308f8e213d995e87b1b141d3f906 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914c692fe951985308f8e213d995e87b1b141d3f90688ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "mycvBPckuxzBzNPYa61P1wMr3Rtikm6X4h"
        ]
      }
    }
  ]
}

I'm still trying to understand why I'm getting "mandatory-script-verify-flag-failed (Signature is found in scriptCode) (code 16)" error. Thanks!

junderw commented 5 years ago

could you also post the transaction:

5a2a44d78e5ea2136708e9754cd281d4bc0c654f191ae4af567940c6970f7364

aitorjs commented 5 years ago

bitcoin-cli -regtest -rpcuser=a -rpcpassword=a gettransaction 5a2a44d78e5ea2136708e9754cd281d4bc0c654f191ae4af567940c6970f7364 { "amount": 50.00000000, "confirmations": 101, "generated": true, "blockhash": "557fb8e9f438cdcdaf4c1f26e4b2a97387a7a85e7b355db786ee63ee253fc343", "blockindex": 0, "blocktime": 1552091451, "txid": "5a2a44d78e5ea2136708e9754cd281d4bc0c654f191ae4af567940c6970f7364", "walletconflicts": [ ], "time": 1552091451, "timereceived": 1552091451, "bip125-replaceable": "no", "details": [ { "address": "mmr8Lpjh6HbCkRNH7qTDUAqsELaCv28bUi", "category": "generate", "amount": 50.00000000, "vout": 0 } ], "hex": "020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a010000002321021f016ed751a3bf635582d746bb72617379ac20325a5a323170cb8f46b2adde33ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000" }

Thank you very much @junderw

junderw commented 5 years ago

your output is p2pk, and you are trying to spend it as if it was a p2sh-p2wpkh.

That's why you have an error.

aitorjs commented 5 years ago

¿So I need to spend it as p2pk, p2pkh or which type of transaction could I use?

Thanks @junderw !

junderw commented 5 years ago

p2pk.

junderw commented 5 years ago

Try this:

const miner = bitcoin.ECPair.fromWIF('cTB7kygwJUB7BpWb3ivefP71Hohq5dt8EfXAcEgAgd6k9f5eTCtR', bitcoin.networks.regtest)
const p2pk = bitcoin.payments.p2pk({ pubkey: miner.publicKey, network: bitcoin.networks.regtest })

const txb = new bitcoin.TransactionBuilder(bitcoin.networks.regtest)

const unspent = JSON.parse(body).result[0]
console.log('Post successful: response: ', unspent)

txb.addInput(unspent.txid, unspent.vout, null, p2pk.output)
txb.addOutput('2N96K4hpjAAh5AmRcFKfjqTXoW78EGwtPuM', 49 * 1e8) // 49 BTC = 49 * 1e8 satoshis

txb.sign(0, miner)