I'm slowly working my way through the technical details of bitcoin by writing custom Mathematica code (just for learning purpose). Last night I wrote my own code to convert an ECDSA public key into a bitcoin address. I (think I) understand everything except for the leading "1"s in the bitcoin address. Here's my Mathematica function for computing the bitcoin address from a public key :
bitcoinaddress[publicKey_Integer] := Module[{h1, h2, addr},
h1 = ripemd160[sha256[publicKey, 65], 32];
h2 = sha256[sha256[h1, 21], 32];
addr = 2^32 h1 + Quotient[h2, 2^224];
Return[ToBase58[addr]]];
(*Note that the second argument in the hash functions is the number of message bytes to assume since Mathematica is using arbitrary-precision integers*)
And here's the
flawed code I'm using for ToBase58[]. The flaw is at the end when I prepend the "1" in order to get the "right answer," but I realize this is a hack and will not always work if there are leading zeros in the pub-key hash:
ToBase58[y_Integer] :=
Module[{codestring = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", outputString = "", x = y},
While[x > 0, outputString = outputString <> StringTake[codestring, {Mod[x, 58] + 1}]; x = Quotient[x, 58]];
Return["1" <> StringReverse[outputString]]]; (*prepending the "1" like this is wrong*)
On the
bitcoin wiki, it says:
What I don't understand are these things in red:
address_byte_string (consisting of 0x01 + hash + 4-byte_check_code)If I prepend 0x01 prior to converting to base58 I get the wrong address, whereas if I ignore this byte I get the correct address.
repeat(number_of_leading_zero_bytes_in_hash)^^This seems strange and arbitrary to me. I add an extra "1" for every leading
byte that is 0?
NOTE TO READERS: Do not use this code for anything important. Use a real bitcoin library.