OutCast3k / coinbin

Javascript Bitcoin Wallet. Supports Multisig, Stealth, HD, SegWit, Bech32, Time Locked Addresses, RBF and more!
https://coinb.in/
MIT License
906 stars 621 forks source link

Easy way to specify redeemScript while signing transaction #73

Open motatoes opened 7 years ago

motatoes commented 7 years ago

I ran into a problem when I was trying to use coinbin within a multisig spending. I've documented what I was tyring to do here. In summary, I was trying to generate a transaction in the core to spend out funds from a 2-of-2 multisig address. I wanted to partially sign the transaction on coinbin using 1 of the private keys, and then do the second signature in bitcoind. I kept getting the message error": "Script evaluated without error but finished with a false/empty top stack elementwhen I was tyring to get the final signature inbitocoind`.

After debugging this issue further I realised that bitcoind generates a transaction with an empty scriptSig for the inputs, and so coinbin signs it as if it were a normal pay to address transaction (I think). Unfortunately I was not able to solve my issue in the UI, but I did manage to solve it by manually modifying the transaction in JS as follows:

var rawtx2 = "01000000021a1f40dba3ab5c208b165d47bdcf2aadc517c4f2b90b781eab53dadcb35d61200100000000ffffffff05ec447a886d8711db0d5f4cbf1f61956cf227c82c5594ee195bb179e86faa910100000000ffffffff0138c70000000000001976a91472a2a94468e42593656cc9803c7a48c1863fc3e588ac00000000";

(function partialSignMultisig(window) {
    var coinjs = window.coinjs;
    var wifkey = "<WIFKEYHERE>";
    var script = rawtx2;
    var redeemScript = "5221020150ce6954f0cdcc2c5d57cf249f25eab0eed23e39549c4f06bcb42a37f308ce2102224aca2849ddad9c663c0bcfdac5ce3ca06f784ac8eca83404a4ea4ac61dbe7d52ae";

    var tx = coinjs.transaction();
    var t = tx.deserialize(script);

        // Manually specify scripts for inputs ..
    for (var i = 0; i < t.ins.length; i++) {
        t.ins[i].script = coinjs.script(redeemScript);
    }

    var signed = t.sign(wifkey);
    console.log( signed );

})(window);

However, I think the UI responsible for signing should also allow us to specify the redeemScript to use during the signature .. In particular I think we can merge the transaction verification UI as a first step for the signature. So the user can decode the transaction as a first step, and optionally specify the private key for each input in the transaction, and also a redeemScript (?) if any. This is also similar to the API that bitcoind facilities as a second argument to the signrawtransaction endpoint. This issue is also related to #62

dabura667 commented 7 years ago

Currently there is no specification of partially signed transactions, so Bitcoin Core uses one method, Electrum uses another, Coinb.in another, Copay another...

Someone should write a BIP to standardize serialization for partially signed / unsigned raw transactions...

motatoes commented 7 years ago

Maybe until standardization we should ensure that it works with the most popular client (core) ?

dabura667 commented 7 years ago

we should ensure that it works with the most popular client (core) ?

Pull requests are welcome. Just be sure to keep backwards compatibility in case someone is sitting on a partially signed transaction waiting to finish it in 5 years.

motatoes commented 7 years ago

@dabura667 How should I do it in the UI side ? Should it be like adding a field "redeem Script" and setting all the input scripts to that value before signing?

image

killingdex20 commented 4 years ago

I ran into a problem when I was trying to use coinbin within a multisig spending. I've documented what I was tyring to do here. In summary, I was trying to generate a transaction in the core to spend out funds from a 2-of-2 multisig address. I wanted to partially sign the transaction on coinbin using 1 of the private keys, and then do the second signature in bitcoind. I kept getting the message error": "Script evaluated without error but finished with a false/empty top stack elementwhen I was tyring to get the final signature inbitocoind`.

After debugging this issue further I realised that bitcoind generates a transaction with an empty scriptSig for the inputs, and so coinbin signs it as if it were a normal pay to address transaction (I think). Unfortunately I was not able to solve my issue in the UI, but I did manage to solve it by manually modifying the transaction in JS as follows:

var rawtx2 = "01000000013a799ce42cc742360e47b375bfa3ad73d0c9e87f8c6a02fae98fa3156c8a458b000000006a4730440220557321fbf50bdeb468656e7bc689e78d3f471813962908f13d3e14a57aa09b2002200542653833b541ee1ed06806739ceabefe4a4ac001c972577c84e0f90bd223c00121025286142ea756c8a33bf54e3b3a85b45da75c46936586c288630df4775ded1251ffffffff02401f00000000000017a914dfad28416f9832c74d3c53aaf34a2b0e7d77b3f6879c160200000000001976a914617f50110a9e11c3258b4ced0d9381802c861c0288ac00000000";

(function partialSignMultisig(window) {
  var coinjs = window.coinjs;
  var wifkey = "<L1doX5jsbaax1SLWdF1FbeFuVYiDckhHoQbWk7gQJwnLnrUXkLAk>";
  var script = rawtx2;
  var redeemScript = "522102926173747da12aedcac4c9be73923570936944995e67992902836569de82d64141044e21236e226546ec84192e047f6b91bb0e7ff5590f89775b084c2dd0247000e24fff35f8132093b82f4f4e4fc001303946b989028d60636ca68575ef386714bb410475bf207e3a94c0f229c4debabf6b215eedc1ee351acd3f7bac0c9d863c3b982acc3153da64be836e24147a5b1f6a6d0e804cebb7c9edbf840bd8cab856b8ad7b53ae ";

  var tx = coinjs.transaction();
      var t = tx.deserialize(script);

        // Manually specify scripts for inputs ..
  for (var i = 0; i < t.ins.length; i++) {
      t.ins[i].script = coinjs.script(redeemScript);
  }

  var signed = t.sign(wifkey);
  console.log( signed );

})(window);

However, I think the UI responsible for signing should also allow us to specify the redeemScript to use during the signature .. In particular I think we can merge the transaction verification UI as a first step for the signature. So the user can decode the transaction as a first step, and optionally specify the private key for each input in the transaction, and also a redeemScript (?) if any. This is also similar to the API that bitcoind facilities as a second argument to the signrawtransaction endpoint. This issue is also related to #62