Bitcoin addresses are alphanumeric character strings (a hash) of the public key of the elliptic curve. This address is similar to the IBAN for bank transactions.
It can be communicated to anyone wishing to send you funds.
These addresses can begin with “1” or “3”.
(Note that there is also a new address type known as Bech32 that starts with “bc1”.This is a segwit address but is not widely adopted ( < 0.8% of existing Bitcoins).
Bitcoin uses cryptography based on elliptic curves.
The system will create the points on an elliptic curve using 65 bytes and generate a public key. The first byte is used to store the type of point in the elliptic curve.
A value of 0x04 indicates that the point is not compressed and means that the x and y coordinates of the point are stored.
A value of 0x02 or 0x03 indicates that the point is compressed and means that only the x coordinate of the elliptic curve point is retained: the y coordinate is removed from x and the elliptic curve equation. Whether this byte takes the value 0x02 or 0x03 depends on the parity (even or odd) of the omitted coordinate (y coordinate).
After the head byte are the two coordinates (x, y) of the elliptic curve point, in the case of an uncompressed point, or the x coordinate for the compressed points.
Bitcoin uses a 256-bit elliptic curve, so each coordinate would take 256 bits = 32 bytes of space. An uncompressed point takes a total of 65 bytes = 1 byte for the type and 32 bytes for each of the two coordinates.
The next step is to first hash using SHA256 and then RIPEMD160, the first hash function, i.e. SHA256 produces a hash of 256 bits = 32 bytes. The second hash function, RIPEMD160, produces a hash of 160 bits = 20 bytes. The creator of the Bitcoin chose this second hash to reduce the size of the address, reducing transactions, while maintaining a reasonable bit size that makes collisions unlikely.
Finally, the checksum is calculated as the double SHA256 of the hash result RIPEMD160. only the first 4 bytes of this hash are kept as checksum. The purpose of this checksum is similar to that of checksums in bank accounts or credit cards: to avoid transcription errors that would send funds to incorrect addresses. Bitcoin wallet software checks that the checksum of an address is correct before sending funds to that address. If a digit from a Bitcoin address was typed or copied by mistake, the wallet would detect the error and will not send funds to that address.
Sending funds to an address not linked to a known private key makes the funds inaccessible and may therefore be considered lost.
In the next step, by creating a Bitcoin address, a string of bytes is prepared to be encoded in Base58. This byte string starts with a byte indicating the address type, followed by the 20-byte result of the RIPEMD160 hash and ends with the 4 check sum bytes.
The value of the address type determines the start of the address once encoded in Base58. The address type can take the following values:
- 0 (decimal) for a public key address in the main network. This will result in a coded address beginning with 1 (P2PKH).
- 5 (decimal) for a script address in the main network. This will result in a coded address beginning with 3 (P2SH).
- 111 (decimal) for a public key address in testnet (Bitcoin test network). This will result in a coded address beginning with “m” or “n”.
- 196 (decimal) for a script address in the testnet (Bitcoin test network). This will result in a coded address beginning with 2.
The last step consists in encoding with the Base58. Base58 is a “binary text” coding algorithm that translates binary data into a text format. Base58 is similar to Base64 coding. Base64 uses the characters A-Z, a-z, 0-9 and the symbols + and /.
The Base58 uses the same characters, except for the symbols + and / and 0, O, I and l. This avoids confusion, because in some fonts 0, O and I and I have similar or sometimes identical representations. To encode a byte string, it is interpreted as an integer, and divided successively by 58. The remains at each stage of this division are coded as a character. This entire procedure results in Bitcoin addresses between 27 and 34 characters. It is important to note that the characters in a Bitcoin address are case sensitive.
Basically, the two types of addresses commonly used (starting with “1” or “3”) correspond to the following two cases :
Wallet beginning with “1” (P2PKH)
The destination of the funds is a single recipient (person or entity) who has full control over the funds and can therefore spend them as he or she sees fit.
Wallet beginning with “3” (P2SH)
The destination of funds is a more complex structure that specifies certain rules/arguments to be respected for funds to be spent or released.
The first type is known as the Pay to Public Key Hash or P2PKH address.
These addresses always start with “1”. The reason for the name is that all that is needed to create the address is a hash of the public key. In order to spend the available funds, the recipient signs a new transaction using their private key.
A two-step verification mechanism is then put in place:
First, the system compares the address used as the source of funds with that derived from the signatory’s public key. In case of a match, a second step validates whether or not the signature provided matches the sender’s public key. A match would indicate that the signatory is the rightful owner and can therefore spend the funds without problems.
To obtain the Bitcoin address associated with a given public key, we use two unidirectional hashing functions, namely SHA256 and RIPEMD160. The first hash function, the SHA256, produces a hash of 256 bits = 32 bytes. The second hash function, RIPEMD160, produces a hash of 160 bits = 20 bytes. The creator of the Bitcoin chose this second hash to reduce the size of the address, reducing transaction sizes, while maintaining a reasonable bit size that makes collisions unlikely.
The procedure is as follows:
- Apply a SHA256 hash to the binary representation of a public key (in compressed or uncompressed format).
- Then apply a RIPEMD160 hash to the binary representation of the previous SHA256.
- Perform Base58Check encoding on the output of the previous RIPEMD160 using a version prefix ’00’ in hexadecimal. The result is the desired Bitcoin address.
Note that the last step is similar to the one used to encode private keys in WIF format. However, there are two differences:
- The version prefix is set to ’00’ instead of ’80’ for the WIF format.
- Since adding a prefix ’00’ does not change the entire value of the bit sequence, we need a specifier to distinguish a string that starts with ’00’. The way Base58Check does this is byte mapping 0 to 1.
Example P2PKH wallet : 17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem
The second type is known as the Pay to Script Hash or P2SH address.
These addresses always start with “3”. They tend to be more complex than P2PKH in the sense that certain rules must be followed in order to release funds.
These rules require more than providing a unique public key hash and a signature derived from an appropriate private key. The applicable rules or conditions are entered in a construction known as a “script redeem”. The purpose of the P2SH name comes from the fact that all that is needed to create the address is a hash of the script.
An example script would be an M-of-N multisignature, whereby it is necessary to have a minimum of M out of a total of N authorized signatures in order to unlock and spend the funds associated with that address. A single entity cannot spend them and, therefore, a single private key is not enough. We will discuss the details of P2SH transactions in a future article.
The procedure used to generate a P2SH address is similar to that used to generate P2PKH addresses. However, there are two differences:
- The rules to perform a transaction is now a script as opposed to a public key (we will discuss script details in the Bitcoin transaction post).
- The version prefix is set to ’05’ instead of ’00’. Therefore, it is not necessary to add a 1 in the header when performing Base58Check encoding.
As an example, consider the following “reem script” in hexadecimal :
For interested people, this script has been retrieved from the block string (for example, use blockchain.com) from the transaction with the following identifier
Example of a P2SH wallet : 3P14159f73E4gFr7JterCCQh9QjiTjiZrG
The diagram below summarizes the interrelation between private keys and public keys as well as the generation of P2PKH and P2SH addresses: