Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transaction rejected by network (code -26). Reason: 64: non-canonical #1136

Closed
trevinhofmann opened this issue Mar 6, 2015 · 3 comments
Closed

Comments

@trevinhofmann
Copy link
Contributor

I am attempting to broadcast a 2-of-3 multisignature transaction with the Insight API. The transaction was created with Bitcore, but I am getting a 'non-canonical' error. Could this be an issue with the order of the signatures?

Here is the rawtx:

0100000001a8e825e97723b40afbbc702d56b1f215b8e14d978357b55cdd754862b2bd2f5c01000000fdfd0000473044022001f4524959d67cbb94ec3b467701855994a28105190a116402996f82fdbf210b02205579e4a9fb3a79619aab36e839140907924afa9aedc56f0d0a4ffa91e16ae7150148304502210089d971e533932f4052c03c888525ba5d41f833a7e0ecef565e4106ef2dd4caff022060aa16868d08c85f7864b5be2b3f3d715b3aff15e36aeb47d48d7182684e2fae014c695221029c17ce9a40a71d21cf53844704dd611c85a2dc0072e22c9f14a485e6bb4ad4f42102b732df6d447e7fc04466522ebefe48fd07d9b5810ca1f572985f4386e36d5d132103e5c93bd1fbf87b30b093c2613b5c6ad7727005fd39fbee95136368c6918f13c053aeffffffff01905f01000000000017a9146e785c7efebeefbf201533ed5c8d07b6a524eadc8700000000

Which decodes to this:

{
   "lock_time":0,
   "size":338,
   "inputs":[
      {
         "prev_out":{
            "index":1,
            "hash":"5c2fbdb2624875dd5cb55783974de1b815f2b1562d70bcfb0ab42377e925e8a8"
         },
         "script":"00473044022001f4524959d67cbb94ec3b467701855994a28105190a116402996f82fdbf210b02205579e4a9fb3a79619aab36e839140907924afa9aedc56f0d0a4ffa91e16ae7150148304502210089d971e533932f4052c03c888525ba5d41f833a7e0ecef565e4106ef2dd4caff022060aa16868d08c85f7864b5be2b3f3d715b3aff15e36aeb47d48d7182684e2fae014c695221029c17ce9a40a71d21cf53844704dd611c85a2dc0072e22c9f14a485e6bb4ad4f42102b732df6d447e7fc04466522ebefe48fd07d9b5810ca1f572985f4386e36d5d132103e5c93bd1fbf87b30b093c2613b5c6ad7727005fd39fbee95136368c6918f13c053ae"
      }
   ],
   "version":1,
   "vin_sz":1,
   "hash":"38bae70129b7ff77df9bb33484581e37f52a49914f3d3993a47529e442fcfab0",
   "vout_sz":1,
   "out":[
      {
         "script_string":"OP_HASH160 6e785c7efebeefbf201533ed5c8d07b6a524eadc OP_EQUAL",
         "address":"3Bm8SVhsEHQkZJMhsmFq7zMvDCpbVXZrSc",
         "value":90000,
         "script":"a9146e785c7efebeefbf201533ed5c8d07b6a524eadc87"
      }
   ]
}
@maraoz
Copy link
Contributor

maraoz commented Mar 6, 2015

Interesting. Thanks for reporting, we'll dig into that. Off the top of my head, this seems to be related to BIP62, but we'll have to see in detail.

@maraoz maraoz added the ready label Mar 10, 2015
@trevinhofmann
Copy link
Contributor Author

Here are the relevant pieces of my signing implementation.

Building the transactions on the server:

  var pubkeys = [escrowInfo.clientPubkey, escrowInfo.senderPubkey, escrowInfo.recipientPubkey];
  var escrowAddress = new bitcore.Address(pubkeys, 2).toString();
  var destinationAddress = new bitcore.Address(escrowInfo.destinationAddress);
  var refundAddress = new bitcore.Address(escrowInfo.refundAddress);
  var escrowTxid = fundingTx.txid;
  var escrowTxVout = fundingTx.vout;
  var escrowFeeAddress = new bitcore.Address('[removed]');
  var escrowAmount = parseInt(escrowInfo.amount);
  var escrowFeeRate = 0.0005;
  var escrowFee = Math.floor(escrowAmount * escrowFeeRate);
  if (escrowFee <= 5430){
    escrowFee = 0;
  }
  var minerFee = 10000;
  var deliveredAmount = escrowAmount;
  deliveredAmount -= minerFee;
  deliveredAmount -= escrowFee;
  var refundedAmount = escrowAmount;
  refundedAmount -= minerFee;
  pubkeys = [
    new PublicKey(pubkeys[0].toString('hex')),
    new PublicKey(pubkeys[1].toString('hex')),
    new PublicKey(pubkeys[2].toString('hex'))
  ];
  var utxo = {
    txId: escrowTxid,
    outputIndex: escrowTxVout,
    script: Script.buildMultisigOut(pubkeys, 2).toScriptHashOut(),
    satoshis: escrowAmount
  };
  var paymentTx = new Transaction()
    .from(utxo, pubkeys, 2)
    .to(destinationAddress, deliveredAmount);
  if (escrowFee > 0){
    paymentTx = paymentTx.to(escrowFeeAddress, escrowFee);
  }
  var serializedPaymentTx = paymentTx.toJSON();
  var refundTx = new Transaction()
    .from(utxo, pubkeys, 2)
    .to(refundAddress, refundedAmount);
  var serializedRefundTx = refundTx.toJSON();
  var builtTxs = [serializedPaymentTx, serializedRefundTx];
  return builtTxs;

Transactions are then serialized and sent to the client's browser for signing:

  $('#submit-received-password').on('click', function(){
    var password = $('#received-password').val();
    var mnemonic = $('#mnemonic').val();
    var orderID = parseInt($('#order-id').val());
    var index = parseInt($('#sender-index').val());
    var privateKey = (new Mnemonic(mnemonic)).toHDPrivateKey(password).derive('m/'+index).privateKey;
    var tx = $('#payment-tx').val();
    var txjson = JSON.parse(tx);
    tx = (new Transaction()).fromObject(txjson);
    var signature = tx.getSignatures(privateKey)[0];
    var url = '/order/'+orderID+'/submitSignature';
    var params = {
      'signature': signature.toJSON(),
      'to': 'destination'
    };
    $.post(url, params, function(data){
      window.location.replace('/orders/');
    });
  });

After POSTing back the serialized Signature, the server applies it:

  var sig = TransactionSignature.fromJSON(data.signature);
  if (tx.isFullySigned()){
    return errorJSON(req, res, 'Transaction already complete.');
  }
  if (tx.isValidSignature(sig)){
    tx.applySignature(sig);
  } else {
    return errorJSON(req, res, 'Signature invalid.');
  }
  var serializedTx = tx.toJSON();

After 2 of the 3 signatures have been applied, isFullySigned returns true and the server attempts to broadcast the raw transaction. This is where the non-canonical error is reached.

@trevinhofmann
Copy link
Contributor Author

2 BTC bounty thread with helpful replies: https://bitcointalk.org/index.php?topic=999414.0;topicseen

It does seem that this could be related to BIP62.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants