Bitcoinjs-lib: Cannot sign P2SH Transaction (Signature must be zero for failed CHECK(MULTI)SIG operation)

Created on 8 Aug 2019  路  6Comments  路  Source: bitcoinjs/bitcoinjs-lib

Getting started with this library and am having some issues sending transactions to the testnet.

Below is the code I am using to setup the transaction:

var bitcoin = require('bitcoinjs-lib');
var UtxoId = "64d81b327e3c9e3f7d723a91283fade2463d25c7361f9e3fd3dd3d175a9a4fa8";
var DestinationAddress = "2N31LULBy8T93qyko123t175mn4XjgwY4dL";
var privateKey = "cVmWEmVoG8SRi6s3G9CCtcXUsRydbZj3YuGBvE2zVkYVnPA6gNSq"
var data = Buffer.from("Hello World", "utf8");
var vout = 1;
var amount = 0.04109432 * 100000000);
var fee = 0.0005 * 100000000; 

const RawTransaction = new bitcoin.TransactionBuilder(bitcoin.networks.testnet);
RawTransaction.addInput(UtxoId, vout);
RawTransaction.addOutput(DestinationAddress, parseInt(amount - fee));
scrypt = bitcoin.script.compile([bitcoin.opcodes.OP_RETURN, data]);
RawTransaction.addOutput(scrypt, 0);
var keyPair = bitcoin.ECPair.fromWIF(privateKey, bitcoin.networks.testnet);

const p2wpkh = bitcoin.payments.p2wpkh({
  pubkey: keyPair.publicKey,
  network: bitcoin.networks.testnet
});
const p2sh = bitcoin.payments.p2sh({
  redeem: p2wpkh,
  network: bitcoin.networks.testnet
});

RawTransaction.sign(0, keyPair, p2sh.redeem.output, null, parseInt(amount));

var Transaction = RawTransaction.build().toHex();

When I use the hex generated by this code by issuing the command:

bitcoin-cli sendrawtransaction 02000000000101a84f9a5a173dddd33f9e1f36c7253d46e2ad3f28913a727d3f9e3c7e321bd8640100000017160014ec4db03ff1508f19a1926c4c61a5317f03638d4affffffff0227f13d000000000017a9146b10d8ba5e98e588799f13a05f154dff410f55398700000000000000000d6a0b48656c6c6f20576f726c64024830450221008e8a93169b746f4cece1180dc1043b92d09867b65a4987f8c02f11a72a7aeae6022001dbae63f7bf723991784aa755c4fe4280c3b0953567fd31611dfd63480cfd1a01210387ff0aeb60b4db299b8750f12740d3d7ca1319c284dd6e26e830b0dbb4724cf000000000

I receive the following error: non-mandatory-script-verify-flag (Signature must be zero for failed CHECK(MULTI)SIG operation) (code 64)

I've spent a week trying to figure out whats going on. Read through several issues, studied the repo code, the test cases, read a bunch of documentation as well. No luck, hoping you awesome people can help me out.

All 6 comments

@sirlanceoflompoc

Rule # 1 of Javascript: When precision is needed avoid floats (decimal values) at ALL COST! lol

> 0.04109432 * 100000000
4109431.9999999995
> parseInt(0.04109432 * 100000000)
4109431

instead of dealing with BTC and multiplying 100M, deal with satoshis only and you will have less headaches.

This should work:


doh thank you so much @junderw !
Looks like whenever we pass data to these functions we will need to use parseInt on the float that was converted to from BTC -> satoshi.

Interesting...
Oh floats... a bane of computer science.

Looks like whenever we pass data to these functions we will need to use parseInt on the float that was converted to from BTC -> satoshi.

No. You should only use satoshis. Any "conversion" has a small chance of creating a bug like the above.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

itsMikeLowrey picture itsMikeLowrey  路  3Comments

askucher picture askucher  路  3Comments

panpan2 picture panpan2  路  3Comments

zhaozhiming picture zhaozhiming  路  3Comments

tuyennvtb picture tuyennvtb  路  3Comments