-
Notifications
You must be signed in to change notification settings - Fork 57
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
Support compressed keys. #13
Comments
Hey, Thanks for the info. Your link to https://github.com/Bit-Wasp/bitcoin-lib-php/Raw_transaction.php isn't working... |
Sorry, right link is https://github.com/Bit-Wasp/bitcoin-lib-php/blob/master/src/RawTransaction.php The signing function is here: https://github.com/Bit-Wasp/bitcoin-lib-php/blob/master/src/RawTransaction.php#L920-988 If you decode the scriptPubKey of the Tx you're trying to redeem, you learn the script hash. This identifies the redeemScript in your wallet (line935) It then looks if it's scriptHash or pay-to-pubkeyhash. If its scriptHash, extract any signatures. Function for that is L987. Just decode the scriptSig['hex'], and check for anything that looks like a signature, or passes IsCanonicalSignature. At this stage, you have learned that there are already count($signatures) valid signatures. But you still want to apply whatever signatures you can. Loop through the $wallet[$scriptHash]['keys'] array to get the private keys you have for that address, creating signatures as you go, and adding them to $signatures. It will overwrite previous signatures you added, but only with another valid siganture, so thats fine. Now, to fix your scriptSig generation function (L1055). Start off adding the null byte to your scriptLoop through the $wallet[$scriptHash]['public_keys'] array, which could have uncompressed/compressed keys, create the hash160, and see if a signature exists for that hash160. If so, prefix with length in bytes. Now that your scriptSig is correctly encoded, just serialize the whole transaction and you're done. |
Quote "There probably is a function in bitcoinjs to decompress a public key" I do not believe there is, I could probably figure it out but it might take a bit of time and some testing. Are you aware of any javascript functions that allows you to decompress a compressed public key? |
You could try look at BitCore for ideas, I have a gist explaining the process (albeit with PHP to follow), but it should show you what you need to research https://gist.github.com/afk11/a3f1174f30e1e8d9ed2d |
https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/eckey.js#L24-29 I really don't know where to start with js.. but I'm skimming through, it looks as if it just learns the string length of the given public key (and private key as you see above), and just sets a 'compressed' object attribute to TRUE. How this links with your code, I'm not quite sure yet :P However, bitcoinjs also has support for BIP32, which uses compressed keys by specification. Check out there to see how they do it? BitCore also should support this. I see that there IS a function to extract the public key from the signature. Surely whatever that extracts will be usable for signature verification? My thoughts are, when you take a TX as input, look for signatures on each input by doing validation against the current Tx, with the right SigHash value, and by using bitcoinjs' extract pubkey from signature method. Although you still need a comparison against the keys in the redeemScript, implying you'll either decompress a key in one, or the other. (I refactored the repo above recently, updated the links to signing, and wallet fxns now) |
Maybe I am missing something here: but why would you need to decompress a public key? Keys in the redeemScript need to stay compressed. Is it just for the signature verification in BitcoinJS that does not understand compressed key? |
Indeed they need to stay uncompressed in the redeemScript. But when it comes to signature verification, this script doesn't handle compressed keys. Creating a temporary variable with the decompressed key around this step could be a simple fix. |
Please see http://coinb.in and https://github.com/OutCast3k/coinbin for a newer version which supports compressed |
At the moment there are several issues which stem from Coinb.in not supporting compressed keys.
So just to explain how annoying this is:
Bitcoin Core is the only client which supports multisig.
People can't use keys taken from Bitcoin Core and sign transactions using Coinbin.
People can't take transactions signed by someone using Bitcoin Core, and complete them using Coinbin.
Uncompressed keys are about twice as long as compressed - meaning you're bloating the blockchain by forcing these.
Electrum will soon only support compressed keys, as this is in the formal specification of BIP32.
Coinbin is the only web utility for signing these tx's, but it isn't compatible with ANYONE else. Please fix this, your tool is very important for multisigs usability right now.
I've implemented support for signing P2SH transactions in a PHP library of mine: https://github.com/Bit-Wasp/bitcoin-lib-php/Raw_transaction.php check out some of the examples. This wallet structure contains enough info to allow signature verification of sigs that are there, and also to add sigs where possible.
If you don't know PHP feel free to email me on thomas@bitwasp.co and I'll try explain how you might change your code - I can read JS, but don't know it well enough to fix this.
The text was updated successfully, but these errors were encountered: