bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.6k stars 2.08k forks source link

Converting public key to address #590

Closed starsoccer closed 8 years ago

starsoccer commented 8 years ago

I have been trying for a few days with no luck on how to convert a public key regular or compressed, but have not had much luck. Below is the code I have been using. I think I am just missing a step, but can't seem to figure out what step I am missing.

console.log(bitcoin.crypto.hash160("04ba2416481d6260e621d8f2b6aad3e9c51d438c1876b624303a16f2bcf8a06cd695cef87230180ceed5735e7bf6cb3f9db360f6fee50824c85f230a6bb3ca9573").toString('hex'));

dcousens commented 8 years ago

convert a public key regular or compressed

What do you mean by this? Please note, the bitcoin.crypto.* only accept Buffer as their input parameter, not hex strings. @jprichardson maybe we should enforce that or allow an encoding parameter that passes-through?

starsoccer commented 8 years ago

@dcousens by public key regular or compressed I meant a compressed public key. public keys normally start with a 04, but compressed they can start with a 03 or 02 I think. A great example of this is shown on https://coinb.in/#newAddress You can generate a new address and then have the public key compressed which shorts it down.

Thanks for the code, I have tried your code as provided and get an error, "Error: Expected UInt8, got undefined" I tried a compressed(03) and umcompressed(04) public key and both return the same error

dcousens commented 8 years ago

@starsoccer then why were you hashing it?

starsoccer commented 8 years ago

@dcousens I am not sure what you mean, I was hashing them simply trying to figure out how to get the address from the public key.

In any case, thanks for your help, I appreciate it.

For anyone else having issues I comment the code to make it cleared how the compressed/uncompressed public keys are compared to generation on coinb.in

var bitcoin = require('bitcoinjs-lib')

var publicKeyBuffer = new Buffer('04ff745ac23991715b685c94ce3484fa71e0d75b98a4ae88bb0ed861e89b5cb08235b642f3ebd9a391464b0adfb739d1e4de5e9ed06924e6378db4f56df0c1e308', 'hex')
var publicKey = bitcoin.ECPair.fromPublicKeyBuffer(publicKeyBuffer)

console.log(new bitcoin.ECPair(null, publicKey.Q, { compressed: true }).getAddress()) // compressed, starts with a 02 or 03
console.log(new bitcoin.ECPair(null, publicKey.Q, { compressed: false }).getAddress()) // not compressed, starts with a 04
jprichardson commented 8 years ago

@jprichardson maybe we should enforce that or allow an encoding parameter that passes-through?

Yeah, any method that requires a Buffer should be enforced to take a buffer. If it detects a string, what if by default it interpreted it as a hex? I don't think that we should add another parameter to specify encoding though. As a string in this context would almost always mean hex.... unless there's a bunch of peeps out there passing around keys as base64/utf8?? If so, they can encode to a buffer. 😀

dcousens commented 8 years ago

If it detects a string, what if by default it interpreted it as a hex

I've seen this constantly bite people in the wild, expecting "utf8" or "hex" to be the default. I think Buffer is the only sane option here.