There are lots of articles around how Bitcoin addresses are created. Most of the time you’ll be shown a few command lines to run and magically the results appear.
>> bitcoin-cli getnewaddress
will output a new Bitcoin address in the command line of the Bitcoin-qt application but how does it work under the covers?
I’ll cover this in a later post but the scope here is to show how base58Check encoding works.
The diagram above shows that a Bitcoin address is the result of a Base58Check encoding of the 160 bit hash of the public key. I’m going to just focus on this last part.
The wiki (https://en.bitcoin.it/wiki/Base58Check_encoding) provides great information but I wanted to know how to calculate it manually.
I’m going to reference the 160 bit hash of a public key and the resultant Bitcoin address from https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses
My starting point
The 25 bit Bitcoin address is my starting input. (This is obtained by taking the 160 bit hash of the public key from the diagram above and adding a version byte of 0x00 in the front and a 4 byte checksum D61967F6 at the end).
The Bitcoin address below is my desired output.
This is how it works.
- Divide the input by 58 and get a remainder. Convert the remainder to a letter based on a lookup table. (from link above).
- Take the letter and append to a string or array.
- Take the resulting answer (ignoring the remainder) and repeat step 1 until no longer possible.
Sounds easy, but I want to see it in action!
What I didn’t mention above is that the input needs to be converted to a number first before you can do the division. Take the input from above, which is a hexidecimal number and convert it. Chances are that a normal calculator can’t do this so you can either code something up yourself or use an online calculator. I used this calculator here which gave me
Now that’s a pretty big freakin number!
Then I used this calculator here to do the calculations. I first used the mod function to get the remainder which was 20 and using the table lookup, this gave me ‘M’. You will see that is indeed the last letter in my Bitcoin address from above.
I then copy the result (438280941262931555217863339656092286811272175269438181) and paste it back in to the x variable and mod the equation again.
I get 53 this time which equates to ‘v’. This is the second letter from the right.
So you can start to see how the address is built manually to help your understanding.
Continuing this process will result in remainders of 42, 51, 20, 54, 6, 23, 10, 44, 16, 38, 46, 18, 53, 27, 10, 48, 22, 38, 23, 2, 35, 50, 41, 24, 8, 19, 19, 54, 27.
At the end I get 317/58 = 5 remainder 27. I can’t divide the 5 any further so 5 becomes ‘6’ from the table.
The final 1 in front comes from the 0x00 version prefix because 0 gets encoded to a 1. This is why in general, Bitcoin addresses start with a 1.
The Base58Check encoding employs a simple divide by 58 formula where the remainder is matched to a table. The length is smaller and the Bitcoin address will always start with a 1 if the version is set at 0x00.