Bitcoinjs-lib: RawTransaction send return mandatory-script-verify-flag-failed (Non-canonical DER signature)

Created on 19 Mar 2018  路  10Comments  路  Source: bitcoinjs/bitcoinjs-lib

I'm using bitcoinjs-lib 3.3.2 and running 2 bitcoin-qt nodes 0.16 on -regtest . I have tried to sign transaction using bitcoinjs and run it in bitcoin-qt console with sendrawtransaction but receive "16: mandatory-script-verify-flag-failed (Non-canonical DER signature) (code -26)"

There is unspent transaction :

{
    "txid": "77d0b6383f93b528333b0f0bd68aab33a3d08cdd05c50e258a7b775d7bfd2527",
    "vout": 0,
    "address": "mhZ1A3Cyqg9XQnRpmYkqjdTzL8yTaBpFf2",
    "scriptPubKey": "21039a0c9cb7c374df809965e4cfeb109ee0e1c7f3a0ee4b4f0cea04eebf25a27ee7ac",
    "amount": 50.00000000,
    "confirmations": 101,
    "spendable": true,
    "solvable": true,
    "safe": true
  }

I use dumpprivkey to get fromWIF value and getnewaccount for the receiver account

The code I'm using:

var testnet = bitcoin.networks.testnet
var value = 50 * 10e7 - 10000;
var key = bitcoin.ECPair.fromWIF("cMrFVDpeP3wvmNRpHLerhtwPY1mwHN3BTYCV1vNtP4zSvvZm11KN", testnet);
var tx = new bitcoin.TransactionBuilder(testnet);
tx.addInput("77d0b6383f93b528333b0f0bd68aab33a3d08cdd05c50e258a7b775d7bfd2527", 0);
tx.addOutput("2N9W57WJHgh8Yiev6s5he1Qn99DkZyKSkYg", value);
tx.sign(0, key);
console.log(tx.build().toHex());

Ive tried with sigwit as well - same result:

var keyPair = bitcoin.ECPair.fromWIF('cPzku2sUaQacgoKNjmS3FZtVrFxB4JtHFiS8y44g9Dr4rMMNn9Di', testnet)
var pubKey = keyPair.getPublicKeyBuffer()
var pubKeyHash = bitcoin.crypto.hash160(pubKey)

var redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash)
var redeemScriptHash = bitcoin.crypto.hash160(redeemScript)

var scriptPubKey = bitcoin.script.scriptHash.output.encode(redeemScriptHash)
var address = bitcoin.address.fromOutputScript(scriptPubKey, testnet)

var txb = new bitcoin.TransactionBuilder(testnet)
txb.addInput("77d0b6383f93b528333b0f0bd68aab33a3d08cdd05c50e258a7b775d7bfd2527", 0);
txb.addOutput("2MxSE48F9ZgsTghEgNjzNEDZoZbQnR4fcfh", value);
txb.sign(0, keyPair, redeemScript, null, value)

console.log(txb.build().toHex());

Any advice would be greatly appriciated

how to / question / docs

Most helpful comment

@Vutov

64: no-witness-yet (code -26)

You might need a minimum block-height on regtest of 432 blocks for segwit...
Try bitcoin-cli generate 432

All 10 comments

If you generated the address from the bitcoin 0.16, the segwit version is the correct version; there are few errors in the code, this should work.

var testnet = bitcoin.networks.testnet;
var value = 50 * 10e7;
var keyPair = bitcoin.ECPair.fromWIF('cPzku2sUaQacgoKNjmS3FZtVrFxB4JtHFiS8y44g9Dr4rMMNn9Di',  testnet)
var pubKey = keyPair.getPublicKeyBuffer()
var redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(pubKey))

var txb = new bitcoin.TransactionBuilder(testnet)
txb.addInput("77d0b6383f93b528333b0f0bd68aab33a3d08cdd05c50e258a7b775d7bfd2527", 0);
txb.addOutput("2MxSE48F9ZgsTghEgNjzNEDZoZbQnR4fcfh", value - 10000);
txb.sign(0, keyPair, redeemScript, null, value)

var tx = txb.build()
var txhex = tx.toHex()

Note that in addOutput we use (value - fee), while we use the input value (value) while signing

Unfortunately I'm having the same result. The decoderawtransaction is able to decode, however on send I still receive "mandatory-script-verify-flag-failed (Non-canonical DER signature)"

Could you paste the fully signed transaction?

decoderawtransaction 010000000001012725fd7b5d777b8a250ec505dd8cd0a333ab8ad60b0f3b3328b5933f38b6d0770000000017160014165378efb7a3886a99fba8b5aa0c239c61b661c0ffffffff01f0ca052a0100000017a914b2b7bfb3012e02e22ac474c14cdf48f9d3c80060870247304402200931caece196ae1a425c41043a34aca195a2050805e0976124f2b0a5765cb42202200382b638c9ec973a03fe08f0f8bbcd6b16313ab09da4a9bfa3f30792763d4f800121039a0c9cb7c374df809965e4cfeb109ee0e1c7f3a0ee4b4f0cea04eebf25a27ee700000000

{
  "txid": "4448658b58cb4c2f0646b64c0456a81299f9f1c2fcddd9704d7b4c747bef2251",
  "hash": "78b3bc36d4a0e4ac54a8f39a5155106a2bb55a2c560cfbe0ac1800bd876c3bc2",
  "version": 1,
  "size": 215,
  "vsize": 134,
  "locktime": 0,
  "vin": [
    {
      "txid": "77d0b6383f93b528333b0f0bd68aab33a3d08cdd05c50e258a7b775d7bfd2527",
      "vout": 0,
      "scriptSig": {
        "asm": "0014165378efb7a3886a99fba8b5aa0c239c61b661c0",
        "hex": "160014165378efb7a3886a99fba8b5aa0c239c61b661c0"
      },
      "txinwitness": [
        "304402200931caece196ae1a425c41043a34aca195a2050805e0976124f2b0a5765cb42202200382b638c9ec973a03fe08f0f8bbcd6b16313ab09da4a9bfa3f30792763d4f8001",
        "039a0c9cb7c374df809965e4cfeb109ee0e1c7f3a0ee4b4f0cea04eebf25a27ee7"
      ],
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 49.99990000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_HASH160 b2b7bfb3012e02e22ac474c14cdf48f9d3c80060 OP_EQUAL",
        "hex": "a914b2b7bfb3012e02e22ac474c14cdf48f9d3c8006087",
        "reqSigs": 1,
        "type": "scripthash",
        "addresses": [
          "2N9YCPXE8M2RTX1EsidfM2ci3Nkgcyrx2QF"
        ]
      }
    }
  ]
}

used code

var testnet = bitcoin.networks.testnet;
var value = 50 * 10e7;
var keyPair = bitcoin.ECPair.fromWIF('cMrFVDpeP3wvmNRpHLerhtwPY1mwHN3BTYCV1vNtP4zSvvZm11KN',  testnet)
var pubKey = keyPair.getPublicKeyBuffer()
var redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(pubKey))

var txb = new bitcoin.TransactionBuilder(testnet)
txb.addInput("77d0b6383f93b528333b0f0bd68aab33a3d08cdd05c50e258a7b775d7bfd2527", 0);
txb.addOutput("2N9YCPXE8M2RTX1EsidfM2ci3Nkgcyrx2QF", value - 10000);
txb.sign(0, keyPair, redeemScript, null, value)

var tx = txb.build()
var txhex = tx.toHex()

In your first unspent transaction output you used a P2PK output, but bitcoinjs may be guessing that it's P2PKH.. if it did, the first element popped would be the public key, leading to a non-canonical DER signature error.

Check out addInput, you can pass the prevOutScript: https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/transaction_builder.js#L532

for the P2SH|P2WPKH case, it fails because the referenced txid is the P2PK output from the first case, so you're using the wrong txid or you need to create a new output to test!

Thanks, I'm not sure how to do it, but I'll play with it and see what happens :)

I've tried to pass prevOutScript, but without much success, I kept getting error that is is not P2PK. In any case it seems there is something funny going with 0.16, regtest and addresses - it was giving me P2PK addresses.

I've managed to sign transaction and send it in 0.15.1 without segwit - all new addresses issued were P2WPKH. However when I try with segwit I get

 64: no-witness-yet (code -26)

code

var unspent = 
{
  "amount": 10.00000000,
  "confirmations": 10,
  "blockhash": "75c53f970687f7a937fc191d925892b8b4bde82d56fbab3942f73843dd1ad266",
  "blockindex": 1,
  "blocktime": 1521569043,
  "txid": "3f24f5deeb2c56c4604f9f59e78aa934476b9f86ca1e7916f5f3b5482c36db31",
  "walletconflicts": [
  ],
  "time": 1521569043,
  "timereceived": 1521569043,
  "bip125-replaceable": "no",
  "details": [
    {
      "account": "",
      "address": "n3EBECC3Uqiod4AmZA3maQYh1z8opLEPYG",
      "category": "receive",
      "amount": 10.00000000,
      "label": "",
      "vout": 1
    }
  ],
  "hex": "020000000197b3540456a1ec43c5f64766e19d5dec0648b9e892e4ba7b3e4165c1486d46f1010000006b483045022100c11717fad483ae29d3a6d47b2acfa6c26a94dad39585ed976288a0b03a1f6f700220670b996922f1cb9bf4bb82593378dd02954d186ee08b2aa043c7f0d02015044f012102573ee81738ca5d8b3cd0b354753391d87c3a89b3939a27c034a7068b1d473c48feffffff02583dd0b2000000001976a914b77ff0a76a2585153a33c269ad14e5f0a8d4c45488ac00ca9a3b000000001976a914ee267e0004a2ffc09fbbf3c9f910eaadb04f94dd88ac70000000"
}

var value = unspent.amount * 1e8
var keyPair = bitcoin.ECPair.fromWIF('cVfEgz79PLefBJovv2Ua2V7WxfjjUVkvATMZAUtzutNnbaZxgY2K', testnet)
var pubKey = keyPair.getPublicKeyBuffer()
var redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(pubKey))

var txb = new bitcoin.TransactionBuilder(testnet)
txb.addInput(unspent.txid, 0);
txb.addOutput("mptQbBteRrpxAh1kgJrmi1yUJWWPRvqf24", value - 10000);
txb.sign(0, keyPair, redeemScript, null, value)

var tx = txb.build()
var txhex = tx.toHex()

Any help would be greatly appreciated.

@Vutov

64: no-witness-yet (code -26)

You might need a minimum block-height on regtest of 432 blocks for segwit...
Try bitcoin-cli generate 432

@dcousens I got error:

16: mandatory-script-verify-flag-failed (Opcode missing or not understood). Code:-26' }

My raw tx:

0100000002e1fa9c541adf5940a33bbdf2d327026f8f78156286cc3ffcb59fa3f7b72b5d172d0000006b483045022100ffb21bfa0ffc1c6922b6049367d3632a163e4af5717f7dcac999ea931d287c69022056eb77099ab8328d7134c2ba9ac4e1265155509770de795b3dd9f960ce94ee26012103e60d48c08c5dc03bce108c32833cd65799d786e7a7be9ab1bc51dde3891e523afeffffffed69d728d5a566c4b6300b81d4afd00b77502a0ede033eb5b554be8373fb1ef3020000006a47304402207bf2fd081eb97b387e4e728824b112f61960636bb1ee33a9f1a5b085e0646b310220705cd051fd72650388984090c59b6036e8bc08dd90716dc87fbcb127d0067010012103e60d48c08c5dc03bce108c32833cd65799d786e7a7be9ab1bc51dde3891e523afeffffff03220200000000000017a914141e677049e539b02ab87c155a24d9743b94096a870000000000000000166a146f6d6e69000000000000001f0000000000989680623602000000000017a9142b41d74e2f0f44bea1856b221650a3dd66055c7b8700000000

Could you help me check?

@tangnv You are spending from P2SH with a P2PKH script.

You are making the transaction wrong.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

coingeek picture coingeek  路  4Comments

tuyennvtb picture tuyennvtb  路  3Comments

prahaladbelavadi picture prahaladbelavadi  路  3Comments

silence-may picture silence-may  路  3Comments

ghost picture ghost  路  3Comments