LedgerHQ / ledgerjs

⛔️ MOVED to monorepo "ledger-live"
https://github.com/LedgerHQ/ledger-live
Apache License 2.0
573 stars 381 forks source link

signP2SHTransaction signature is incorrect #188

Closed bodymindarts closed 5 years ago

bodymindarts commented 5 years ago

I'm trying to use the btc.signP2SHTransaction function but am not getting the expected result. I have added a test in https://github.com/bodymindarts/ledgerjs/tree/failing-test (branched off of master) that fails when I execute it:

packages/test/src/testBtcSignP2SHSeg.js

import Btc from "@ledgerhq/hw-app-btc";

export default async transport => {
  const btc = new Btc(transport);

  // This transaction hex is complete and could be broadcast as is.
  // You can decode it to find the expected signature.
  const newTx = "01000000012776efd350c7557f652ef194d31c8a855cac19e478ec49d0e5e23ac9f5bc3626000000009200483045022100a82e92b5afc1765d91faafbd32b0918e7e54d1b2a58659438f2cd124f11316cf022066d81ae593d36a76ead4ebda98118e81a978ec5441ea732a62107ac3b21edb9601475121026666422d00f1b308fc7527198749f06fedb028b979c09f60d0348ef79c985e41210384257cf895f1ca492bbee5d7485ae0ef479036fdf59e15b92e37970a98d6fe7552aeffffffff0188130000000000001976a9140ae1441568d0d293764a347b191025c51556cecd88ac00000000"
  const bufferedData = btc.splitTransaction(newTx);
  const outputScript = btc
        .serializeTransactionOutputs(bufferedData)
        .toString("hex");

  var tx1 = btc.splitTransaction(
    "010000000132cff98f6f0e373028328355f7d20b6159b36992e8c0e2500157fc41e9fac98e010000008a473044022062dd099ebc4fb03d568732c55017d351cc9dffc0feb49ba30102441cef46e402022001508248e6337d8ab63b81d4ae3622f14bfc49a7e45dc8c615d24875e54d60900141044289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34cec320a0565fb7caf11b1ca2f445f9b7b012dda5718b3cface369ee3a034ded6ffffffff02102700000000000017a9143530cab7ca6700a1d2d579adbf2697a72dfeb6d28798af8f65170100001976a9140ae1441568d0d293764a347b191025c51556cecd88ac00000000"
  );

  const result = await btc.signP2SHTransaction(
    [
      [
        tx1,
        0,
        "5121026666422d00f1b308fc7527198749f06fedb028b979c09f60d0348ef79c985e41210384257cf895f1ca492bbee5d7485ae0ef479036fdf59e15b92e37970a98d6fe7552ae",
      ]
    ],
    ["0'/0/0"],
    outputScript
  );

  const expectedSignature = "3045022100a82e92b5afc1765d91faafbd32b0918e7e54d1b2a58659438f2cd124f11316cf022066d81ae593d36a76ead4ebda98118e81a978ec5441ea732a62107ac3b21edb96"
  if (expectedSignature != result[0]) {
    console.log("signatures didn't match!");
    console.log("Expected: " + expectedSignature);
    console.log("Actual: " + result[0]);
    throw("BAD SIGNATURE");
  };
  return result;
};

I have another branch where I have added segwit support to the signP2SHTransaction function, and am trying to verfiy that all is working as expected, but cannot even get the current version to return the expected result. Can anyone spot where I'm going wrong?

amougel commented 5 years ago

What do you mean by

cannot even get the current version to return the expected result

bodymindarts commented 5 years ago

This test for me is failing on current master. current version = without my changes to support segwit.

nickfogle commented 5 years ago

@bodymindarts, I'm experiencing the same thing, and it appears that many others are having issues with signP2SHTransaction. I'm including an extremely detailed summary of a 3 of 5 Multisignature transaction so others can dupe the issue easily.

Current Address - 2N6myFS4BNznBVAeyTJjvJLpogngohzHVCL (segwit wrapped in p2sh)

Public Keys: (see corresponding devices and private keys below)

[
  "0227f092c7f60c583da39c4e8b4bc7bce8c41eb66054adfb4e52c7bd8d4efceacc",
  "02ac9a0a212de42e59ac686344169dc5aaf850d0dcddf75915864bb02699c6959d",
  "02ec2bf8694f036c150073102154d2da4019337dffc3381bc5697d73c86038c6f9",
  "03a1f8f29eab1ab71081234e2beb236eeb84f8a15af6fd7f7fd2479c175772485c",
  "03f7313aab8a020cc90a157771457db575c615430469a6f13ee0c0fdd80d6db749"
]

Redeem Script: 532102986cf3443eb996838feb1c46c92c8a2a9c5c91c0b90f253538a8be87a1d0156a2102991739f1ae9ee3ff8d9a4494dd2c90fa562ed11267577a8fa0ddde365212c8c52102b7076be19654db2b0884f86a9be1906010606e4f6970ceb5339a01075cbf0765210327182d63d717222f7c7481a7d8281f46daa2f0ebefed204f6fa5f2ff47ec0a132103face804271b98f77b7330f545df8142c6d0a6d776dff9020dd411013da4cb93755ae

Device A

path: m/49/1/1/0/0 public key: 02ec2bf8694f036c150073102154d2da4019337dffc3381bc5697d73c86038c6f9 private key: cU97q2vDyxPwbiJCb34Ej8yxQtju5Ybcf5M1biP6fVjkqcvvyfme

Device B

path: m/49/1/0/0/0 public key: 0227f092c7f60c583da39c4e8b4bc7bce8c41eb66054adfb4e52c7bd8d4efceacc private key: cV7YsCrN6jLRRb1esPiJmHJSaJuW6tjqs83x2jZFmiW5x6ggPXnD

Device C

path: m/49/1/0/0/0 public key: 02ac9a0a212de42e59ac686344169dc5aaf850d0dcddf75915864bb02699c6959d private key: cPqfjDhCr1CJBd3LJsNBZM3ExNQ4cqJcxbvmNJ7HacT19SezzP68

Device D

path: m/49/1/0/0/0 public key: 03f7313aab8a020cc90a157771457db575c615430469a6f13ee0c0fdd80d6db749 private key: cTNHUH1efK7qLkDBDoDV74apzkPsixjvDowycYzcxLGzThr6Ms1h

Ledger Nano S

path: m/49/1/0/0/0 public key: 03a1f8f29eab1ab71081234e2beb236eeb84f8a15af6fd7f7fd2479c175772485c private key: cT22tdd7MDnuFN6m9GSWVqFqqVXYuLndQAjZGaXrwsT1NpDzh7F5

Expected Signature - based on bitcoin-cli 30450221008ceeec75ac004d38c59676c5bfa56988ad98c016cacbbee7f8a41b35f224d10e0220587b77f4008a1faed7af4967eeaf6f32055011880dc1eef894154fdc7a73339401


Decoded Funding Transaction

{
  "txid": "9935564bda06d9413862b73d45d5c6b9e1cbd82cc640eee7d06705eee2271b3d",
  "hash": "9935564bda06d9413862b73d45d5c6b9e1cbd82cc640eee7d06705eee2271b3d",
  "version": 1,
  "size": 223,
  "vsize": 223,
  "locktime": 0,
  "vin": [
    {
      "txid": "2f542c17a1e525c3713019cf6413c8b5b7c2f0aa5a2a735616db2a15b3e5fb68",
      "vout": 1,
      "scriptSig": {
        "asm": "3044022067062adeb1b1c849a0bd6b6b3df521161244f7ec7812ccc94e71cfbf7e147ee602207440525bd04ceae95902484341cf6de7dc4d58516e339dd8685d18ee35412d19[ALL] 029ea4de99104dc108052a6172e3bf7ffa75dd5e2f1caadbbc58d0b5be70e5cd3b",
        "hex": "473044022067062adeb1b1c849a0bd6b6b3df521161244f7ec7812ccc94e71cfbf7e147ee602207440525bd04ceae95902484341cf6de7dc4d58516e339dd8685d18ee35412d190121029ea4de99104dc108052a6172e3bf7ffa75dd5e2f1caadbbc58d0b5be70e5cd3b"
      },
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 5.00000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_HASH160 946a3a0696dc56b07dc133728271756bd4608b32 OP_EQUAL",
        "hex": "a914946a3a0696dc56b07dc133728271756bd4608b3287",
        "reqSigs": 1,
        "type": "scripthash",
        "addresses": [
          "2N6myFS4BNznBVAeyTJjvJLpogngohzHVCL"
        ]
      }
    },
    {
      "value": 894.99998426,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 c0c119d49acae24d95326f1577f635e1189d2a7f OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914c0c119d49acae24d95326f1577f635e1189d2a7f88ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "my69Mmgg5qzbuawsnRWvHk5TURK5HhxkxS"
        ]
      }
    }
  ],
  "hex": "010000000168fbe5b3152adb1656732a5aaaf0c2b7b5c81364cf193071c325e5a1172c542f010000006a473044022067062adeb1b1c849a0bd6b6b3df521161244f7ec7812ccc94e71cfbf7e147ee602207440525bd04ceae95902484341cf6de7dc4d58516e339dd8685d18ee35412d190121029ea4de99104dc108052a6172e3bf7ffa75dd5e2f1caadbbc58d0b5be70e5cd3bffffffff020065cd1d0000000017a914946a3a0696dc56b07dc133728271756bd4608b3287da989dd6140000001976a914c0c119d49acae24d95326f1577f635e1189d2a7f88ac00000000",
  "blockhash": "00000000e603b46ede73d69c2aa9a4a08a5164d088534e8382de6e1536e600c2",
  "confirmations": 10,
  "time": 1532010937,
  "blocktime": 1532010937
}

New Spending Transaction:

010000000001013d1b27e2ee0567d0e7ee40c62cd8cbe1b9c6d5453db7623841d906da4b563599000000002322002095c44d959e31ce03836027d3ff26cd6391068765433406c79c84e97613f7f886ffffffff01139ecb1d000000001976a914c0c119d49acae24d95326f1577f635e1189d2a7f88ac07000000000000ad53210227f092c7f60c583da39c4e8b4bc7bce8c41eb66054adfb4e52c7bd8d4efceacc2102ac9a0a212de42e59ac686344169dc5aaf850d0dcddf75915864bb02699c6959d2102ec2bf8694f036c150073102154d2da4019337dffc3381bc5697d73c86038c6f92103a1f8f29eab1ab71081234e2beb236eeb84f8a15af6fd7f7fd2479c175772485c2103f7313aab8a020cc90a157771457db575c615430469a6f13ee0c0fdd80d6db74955ae00000000

signrawtransaction (returns correct signature for Ledger's private key)

signrawtransaction '010000000001013d1b27e2ee0567d0e7ee40c62cd8cbe1b9c6d5453db7623841d906da4b563599000000002322002095c44d959e31ce03836027d3ff26cd6391068765433406c79c84e97613f7f886ffffffff01139ecb1d000000001976a914c0c119d49acae24d95326f1577f635e1189d2a7f88ac07000000000000ad53210227f092c7f60c583da39c4e8b4bc7bce8c41eb66054adfb4e52c7bd8d4efceacc2102ac9a0a212de42e59ac686344169dc5aaf850d0dcddf75915864bb02699c6959d2102ec2bf8694f036c150073102154d2da4019337dffc3381bc5697d73c86038c6f92103a1f8f29eab1ab71081234e2beb236eeb84f8a15af6fd7f7fd2479c175772485c2103f7313aab8a020cc90a157771457db575c615430469a6f13ee0c0fdd80d6db74955ae00000000' '[{"txid":"9935564bda06d9413862b73d45d5c6b9e1cbd82cc640eee7d06705eee2271b3d","vout":0,"scriptPubKey":"a914946a3a0696dc56b07dc133728271756bd4608b3287","redeemScript":"53210227f092c7f60c583da39c4e8b4bc7bce8c41eb66054adfb4e52c7bd8d4efceacc2102ac9a0a212de42e59ac686344169dc5aaf850d0dcddf75915864bb02699c6959d2102ec2bf8694f036c150073102154d2da4019337dffc3381bc5697d73c86038c6f92103a1f8f29eab1ab71081234e2beb236eeb84f8a15af6fd7f7fd2479c175772485c2103f7313aab8a020cc90a157771457db575c615430469a6f13ee0c0fdd80d6db74955ae", "amount":5.00000000}]' '["cT22tdd7MDnuFN6m9GSWVqFqqVXYuLndQAjZGaXrwsT1NpDzh7F5"]'

When passing the same data to Ledger's signP2SHTransaction, I get the wrong signature:

export const signTransaction = async() => {
  const transport = await TransportU2F.create();
  const btc = new Btc(transport);

  const previousTx = "010000000168fbe5b3152adb1656732a5aaaf0c2b7b5c81364cf193071c325e5a1172c542f010000006a473044022067062adeb1b1c849a0bd6b6b3df521161244f7ec7812ccc94e71cfbf7e147ee602207440525bd04ceae95902484341cf6de7dc4d58516e339dd8685d18ee35412d190121029ea4de99104dc108052a6172e3bf7ffa75dd5e2f1caadbbc58d0b5be70e5cd3bffffffff020065cd1d0000000017a914946a3a0696dc56b07dc133728271756bd4608b3287da989dd6140000001976a914c0c119d49acae24d95326f1577f635e1189d2a7f88ac00000000"
  var tx1 = btc.splitTransaction(previousTx, true);

  const newTx = "010000000001013d1b27e2ee0567d0e7ee40c62cd8cbe1b9c6d5453db7623841d906da4b563599000000002322002095c44d959e31ce03836027d3ff26cd6391068765433406c79c84e97613f7f886ffffffff01139ecb1d000000001976a914c0c119d49acae24d95326f1577f635e1189d2a7f88ac07000000000000ad53210227f092c7f60c583da39c4e8b4bc7bce8c41eb66054adfb4e52c7bd8d4efceacc2102ac9a0a212de42e59ac686344169dc5aaf850d0dcddf75915864bb02699c6959d2102ec2bf8694f036c150073102154d2da4019337dffc3381bc5697d73c86038c6f92103a1f8f29eab1ab71081234e2beb236eeb84f8a15af6fd7f7fd2479c175772485c2103f7313aab8a020cc90a157771457db575c615430469a6f13ee0c0fdd80d6db74955ae00000000"
  const splitNewTx = btc.splitTransaction(newTx, true);
  const outputScript = btc.serializeTransactionOutputs(splitNewTx).toString("hex");

  const redeemScript = "53210227f092c7f60c583da39c4e8b4bc7bce8c41eb66054adfb4e52c7bd8d4efceacc2102ac9a0a212de42e59ac686344169dc5aaf850d0dcddf75915864bb02699c6959d2102ec2bf8694f036c150073102154d2da4019337dffc3381bc5697d73c86038c6f92103a1f8f29eab1ab71081234e2beb236eeb84f8a15af6fd7f7fd2479c175772485c2103f7313aab8a020cc90a157771457db575c615430469a6f13ee0c0fdd80d6db74955ae"

  const result = await btc.signP2SHTransaction(
    [[tx1, 0, redeemScript]],
    ["m/49/1/0/0/0"],
    outputScript
  );

  // This is 
  const expectedSignature = "30450221008ceeec75ac004d38c59676c5bfa56988ad98c016cacbbee7f8a41b35f224d10e0220587b77f4008a1faed7af4967eeaf6f32055011880dc1eef894154fdc7a73339401"
  if (expectedSignature != result[0]) {
    console.log("signatures didn't match!");
    console.log("Expected: " + expectedSignature);
    console.log("Actual: " + result[0]);
    throw("BAD SIGNATURE");
  };
  return result;

};

Instead of returning the expected signature - 30450221008ceeec75ac004d38c59676c5bfa56988ad98c016cacbbee7f8a41b35f224d10e0220587b77f4008a1faed7af4967eeaf6f32055011880dc1eef894154fdc7a73339401, it returns the following: 3045022100bfc09cae64e61c0200d832d424fb615d10c188cf6819af2a5299bf3f965386f5022011abe15835197a4fbdf3ee70594fbeaa0c311237f9a3f0de1a6af443030e8518

blockchainguyy commented 5 years ago

@bodymindarts your newTx has 0 fees, I checked it here- https://live.blockcypher.com/btc/decodetx/

const newTx = "01000000012776efd350c7557f652ef194d31c8a855cac19e478ec49d0e5e23ac9f5bc3626000000009200483045022100a82e92b5afc1765d91faafbd32b0918e7e54d1b2a58659438f2cd124f11316cf022066d81ae593d36a76ead4ebda98118e81a978ec5441ea732a62107ac3b21edb9601475121026666422d00f1b308fc7527198749f06fedb028b979c09f60d0348ef79c985e41210384257cf895f1ca492bbee5d7485ae0ef479036fdf59e15b92e37970a98d6fe7552aeffffffff0188130000000000001976a9140ae1441568d0d293764a347b191025c51556cecd88ac00000000"

and also none of your outputs in your input UTXO:

var tx1 = btc.splitTransaction( "010000000132cff98f6f0e373028328355f7d20b6159b36992e8c0e2500157fc41e9fac98e010000008a473044022062dd099ebc4fb03d568732c55017d351cc9dffc0feb49ba30102441cef46e402022001508248e6337d8ab63b81d4ae3622f14bfc49a7e45dc8c615d24875e54d60900141044289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34cec320a0565fb7caf11b1ca2f445f9b7b012dda5718b3cface369ee3a034ded6ffffffff02102700000000000017a9143530cab7ca6700a1d2d579adbf2697a72dfeb6d28798af8f65170100001976a9140ae1441568d0d293764a347b191025c51556cecd88ac00000000" );

Belong to mgWUuj1J1N882jmqFxtDepEC73Rr22E9GU address, which is the address trying to spend this input in your newtx.

Are you sure you're asking the signature from the correct index?

I see similar issues in @nickfogle 's code.

bodymindarts commented 5 years ago

@ayush-techracers thank you so much I indeed must have made a mistake copy-pasting the tx hex values. I have pushed a fixed version and now the signature matches :-).

import Btc from "@ledgerhq/hw-app-btc";

export default async transport => {
  const btc = new Btc(transport);

  // This transaction hex is complete and could be broadcast as is.
  // You can decode it to find the expected signature.
  const newTx = "01000000015667f9c73939f8b05c97f87ca31910ca5323195ab9061b07e10e802a5b91b1d200000000910047304402203e2dfedce4336d4df2ea9b3e7c66f6a24ccaa43a3fb555b1c078c65b2b10ddcf02205b2e90679158793e2c3ed6c79f22d227b7c07e4de3e07ff211da04005248c28201475121026666422d00f1b308fc7527198749f06fedb028b979c09f60d0348ef79c985e41210384257cf895f1ca492bbee5d7485ae0ef479036fdf59e15b92e37970a98d6fe7552aeffffffff0188130000000000001976a9140ae1441568d0d293764a347b191025c51556cecd88ac00000000"
  const bufferedData = btc.splitTransaction(newTx);
  const outputScript = btc
        .serializeTransactionOutputs(bufferedData)
        .toString("hex");

  var tx1 = btc.splitTransaction(
    "010000000164e1b240e8c1523545ad3cf593cbb6e67c73b7f0737cc40807efd605622b736d010000008a4730440220682e9974955b61a665a96533efe8c35dfbb4a7b559a965d21a9855e4daea2235022027705c34e034187311f7c83775df6602e9c4db33d63580b39f64bb9da89da0670141044289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34cec320a0565fb7caf11b1ca2f445f9b7b012dda5718b3cface369ee3a034ded6ffffffff02102700000000000017a9143530cab7ca6700a1d2d579adbf2697a72dfeb6d2878c9e8e65170100001976a9140ae1441568d0d293764a347b191025c51556cecd88ac00000000"
  );

  const result = await btc.signP2SHTransaction(
    [
      [
        tx1,
        0,
        "5121026666422d00f1b308fc7527198749f06fedb028b979c09f60d0348ef79c985e41210384257cf895f1ca492bbee5d7485ae0ef479036fdf59e15b92e37970a98d6fe7552ae",
      ]
    ],
    ["0'/0/0"],
    outputScript
  );

  const expectedSignature = "304402203e2dfedce4336d4df2ea9b3e7c66f6a24ccaa43a3fb555b1c078c65b2b10ddcf02205b2e90679158793e2c3ed6c79f22d227b7c07e4de3e07ff211da04005248c282"
  if (expectedSignature != result[0]) {
    console.log("signatures didn't match!");
    console.log("Expected: " + expectedSignature);
    console.log("Actual: " + result[0]);
    throw("BAD SIGNATURE");
  };
  return result;
};
bodymindarts commented 5 years ago

For me this issue can be closed.

nickfogle commented 5 years ago

Thanks for taking a look @ayush-techracers and glad it worked for you @bodymindarts . If you don't mind leaving it open for a bit longer, I'd like to get some clarity around the fees issue. @ayush-techracers, are you saying that Ledger explicity requires setting the fees somehow?

I know Blockcypher shows 0 for the fee, but I don't think that's correct. Any input bitcoins that aren't redeemed in an output is considered a transaction fee. Here, I've got one input of 5.0 BTC and one output of 4.99883539 BTC, so the fee should be the difference right?

I've encountered discrepancies decoding transactions using Blockcypher in the past, so I prefer smartbit and bitcoin-cli for decoding transactions.

Here's the decoded raw transaction:

{
  "txid": "6413d03448ce2352ffad16426d71690eb2e9374628d2bbccdd7ac9e2846f9d9a",
  "hash": "a2699be65ebe0a8be636159431c94cce43ef8b203937c7b1891a5b732ef6a95e",
  "version": 1,
  "size": 303,
  "vsize": 166,
  "locktime": 0,
  "vin": [
    {
      "txid": "9935564bda06d9413862b73d45d5c6b9e1cbd82cc640eee7d06705eee2271b3d",
      "vout": 0,
      "scriptSig": {
        "asm": "002095c44d959e31ce03836027d3ff26cd6391068765433406c79c84e97613f7f886",
        "hex": "22002095c44d959e31ce03836027d3ff26cd6391068765433406c79c84e97613f7f886"
      },
      "txinwitness": [
        "",
        "",
        "",
        "",
        "",
        "",
        "53210227f092c7f60c583da39c4e8b4bc7bce8c41eb66054adfb4e52c7bd8d4efceacc2102ac9a0a212de42e59ac686344169dc5aaf850d0dcddf75915864bb02699c6959d2102ec2bf8694f036c150073102154d2da4019337dffc3381bc5697d73c86038c6f92103a1f8f29eab1ab71081234e2beb236eeb84f8a15af6fd7f7fd2479c175772485c2103f7313aab8a020cc90a157771457db575c615430469a6f13ee0c0fdd80d6db74955ae"
      ],
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 4.99883539,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 c0c119d49acae24d95326f1577f635e1189d2a7f OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914c0c119d49acae24d95326f1577f635e1189d2a7f88ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "my69Mmgg5qzbuawsnRWvHk5TURK5HhxkxS"
        ]
      }
    }
  ]
}

Any idea what field/ value I should expect to see that's not already there? Thanks again!

bodymindarts commented 5 years ago

I have also experienced that blockcypher doesn't decode the transaction correctly. In the working example I posted it also says fees: 0 but it still works. I think this is an issue with blockcypher.

Sent from my iPhone

On 20. Jul 2018, at 20:52, Nick Fogle notifications@github.com wrote:

Thanks for taking a look @ayush-techracers and glad it worked for you @bodymindarts . If you don't mind leaving it open for a bit longer, I'd like to get some clarity around the fees issue. @ayush-techracers, are you saying that Ledger explicity requires setting the fees somehow?

I know Blockcypher shows 0 for the fee, but I don't think that's correct. Any input bitcoins that aren't redeemed in an output is considered a transaction fee. Here, I've got one input of 5.0 BTC and one output of 4.99883539 BTC, so the fee should be the difference right?

I've encountered discrepancies decoding transactions using Blockcypher in the past (particularly with testnet), so I prefer smartbit and bitcoin-cli for decoding transactions.

Here's the decoded raw transaction:

{ "txid": "6413d03448ce2352ffad16426d71690eb2e9374628d2bbccdd7ac9e2846f9d9a", "hash": "a2699be65ebe0a8be636159431c94cce43ef8b203937c7b1891a5b732ef6a95e", "version": 1, "size": 303, "vsize": 166, "locktime": 0, "vin": [ { "txid": "9935564bda06d9413862b73d45d5c6b9e1cbd82cc640eee7d06705eee2271b3d", "vout": 0, "scriptSig": { "asm": "002095c44d959e31ce03836027d3ff26cd6391068765433406c79c84e97613f7f886", "hex": "22002095c44d959e31ce03836027d3ff26cd6391068765433406c79c84e97613f7f886" }, "txinwitness": [ "", "", "", "", "", "", "53210227f092c7f60c583da39c4e8b4bc7bce8c41eb66054adfb4e52c7bd8d4efceacc2102ac9a0a212de42e59ac686344169dc5aaf850d0dcddf75915864bb02699c6959d2102ec2bf8694f036c150073102154d2da4019337dffc3381bc5697d73c86038c6f92103a1f8f29eab1ab71081234e2beb236eeb84f8a15af6fd7f7fd2479c175772485c2103f7313aab8a020cc90a157771457db575c615430469a6f13ee0c0fdd80d6db74955ae" ], "sequence": 4294967295 } ], "vout": [ { "value": 4.99883539, "n": 0, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 c0c119d49acae24d95326f1577f635e1189d2a7f OP_EQUALVERIFY OP_CHECKSIG", "hex": "76a914c0c119d49acae24d95326f1577f635e1189d2a7f88ac", "reqSigs": 1, "type": "pubkeyhash", "addresses": [ "my69Mmgg5qzbuawsnRWvHk5TURK5HhxkxS" ] } } ] }

Any idea what field/ value I should expect to see that's not already there? Thanks again!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

blockchainguyy commented 5 years ago

@nickfogle your input tx, i.e:

const previousTx = "010000000168fbe5b3152adb1656732a5aaaf0c2b7b5c81364cf193071c325e5a1172c542f010000006a473044022067062adeb1b1c849a0bd6b6b3df521161244f7ec7812ccc94e71cfbf7e147ee602207440525bd04ceae95902484341cf6de7dc4d58516e339dd8685d18ee35412d190121029ea4de99104dc108052a6172e3bf7ffa75dd5e2f1caadbbc58d0b5be70e5cd3bffffffff020065cd1d0000000017a914946a3a0696dc56b07dc133728271756bd4608b3287da989dd6140000001976a914c0c119d49acae24d95326f1577f635e1189d2a7f88ac00000000"

should be an already broadcated tx, held by your Multisig address, (so it can consume it and create a new Tx) I noticed it had 0 confirmations after so many days you posted the code and when I search it's hash in bitcoin testnet I cannot find it.(9935564bda06d9413862b73d45d5c6b9e1cbd82cc640eee7d06705eee2271b3d)

Please try by consuming a proper input tx held by your multisig address.

nickfogle commented 5 years ago

@ayush-techracers, that input transaction was actually confirmed in block 1354483. I've double checked on smartbit, blocktrail, and my own full node.

If you're looking at blockcypher, their chain is about 5 days behind :(.

image

blockchainguyy commented 5 years ago

@nickfogle yep, you're right, it was an issue on blockcypher's side. I also noticed this txid (9935564bda06d9413862b73d45d5c6b9e1cbd82cc640eee7d06705eee2271b3d) belongs to 2N6myFS4BNznBVAeyTJjvJLpogngohzHVCL. But if I try to generate a 3 of 5 address using your private keys, I get 2NEaRBYfGq6vdWMYvuJHqaW7ZWd1mfP42ic. Here is the code I used:

const bitcoin = require("bitcoinjs-lib");
const bitcore = require("bitcore-lib");

const privateKeys = [
  new bitcore.PrivateKey(
    "cU97q2vDyxPwbiJCb34Ej8yxQtju5Ybcf5M1biP6fVjkqcvvyfme",
    "testnet"
  ),
  new bitcore.PrivateKey(
    "cV7YsCrN6jLRRb1esPiJmHJSaJuW6tjqs83x2jZFmiW5x6ggPXnD",
    "testnet"
  ),
  new bitcore.PrivateKey(
    "cPqfjDhCr1CJBd3LJsNBZM3ExNQ4cqJcxbvmNJ7HacT19SezzP68",
    "testnet"
  ),
  new bitcore.PrivateKey(
    "cTNHUH1efK7qLkDBDoDV74apzkPsixjvDowycYzcxLGzThr6Ms1h",
    "testnet"
  ),
  new bitcore.PrivateKey(
    "cT22tdd7MDnuFN6m9GSWVqFqqVXYuLndQAjZGaXrwsT1NpDzh7F5",
    "testnet"
  )
];

const publicKeys = privateKeys.map(bitcore.PublicKey, bitcoin.networks.testnet);
const address = new bitcore.Address(publicKeys, 3); // 2 of 2

console.log("\n\nCreated this Address:", address);
console.log("\n\nPublic keys:", publicKeys);
nickfogle commented 5 years ago

@ayush-techracers thanks for the continued investigation. The address you generated above would be correct if this was a typical P2SH address, but this is a P2SH-P2WSH address (wrapped segwit for backwards compatibility because many wallets don't support native segwit). In generating the address, I've referenced the procedure described in the wallet developers guide as well as BIP-141).

Also, I've confirmed that this transaction can be validly signed using the other private keys, so I know the address and other details are correct. Also, I've tested with other hardware wallets (Trezor) which produces correct signatures. At this point, I feel like I've exhausted all troubleshooting options and am left with this being something specific to Ledger signing P2SH/ Segwit.

bodymindarts commented 5 years ago

@nickfogle it is correct that ledger doesn't support BIP-141 in the signP2SHTransaction method. Thats why I've opened PR https://github.com/LedgerHQ/ledgerjs/pull/189. I'm still debugging my changes, and this ticket (getting a correct non-segwit signature) was my first step to seeing if the PR actually works as expected.

nickfogle commented 5 years ago

@bodymindarts that's good to know! Anything I can do to assist in reviewing/ testing your PR?

bodymindarts commented 5 years ago

@nickfogle I just got the it working.

blockchainguyy commented 5 years ago

Hi @bodymindarts , @nickfogle , @dhoffmann

Could you please take a look on the issue that I am currently facing and let me know your thoughts. https://github.com/LedgerHQ/ledgerjs/issues/246 when I try to sign transaction by method signP2SHTransaction from one of my ledger account and use 2 utxos then it gives me first one valid and second one signature is always invalid. ie. this method always gives first signature is correct and rest of the signatures are invalid when transaction consist multiple utxos.