Address
An easy to share format of a locking script.

An address is what you give to people so that they can “send” you bitcoins.
When someone receives it, they can create a specific locking script based on the type of address you have given them.
Try it!
How do you create an address?
Well, that depends on how you’d like your bitcoins to be locked up.
But in general, an address contains:
- Some specific data that you would like included in the lock. For example, your
public key hash
. - A prefix to indicate what kind of lock to create.
- And a checksum to help with catching any typos.
Finally, all of that gets converted to Base58, which makes it a little more user-friendly.
Pay To PubKey Hash (P2PKH)
P2PKH: This is a typical address that locks bitcoins to a public key
(or to be more precise: the public key hash
).
As mentioned, we append a prefix and prepend a checksum to our hashed public key, then encode it all in base58.
Now we have an address to give to people.
Decoded:
When someone creates a locking script from this address, they just decode the base58 to retrieve the hash160 inside it, then create a P2PKH lock around it, as follows:
So the prefix indicates what kind of lock to create, and the hash160 tells them what to put inside it.
Pay To Script Hash (P2SH)
P2SH: This lock includes the hash of a script. We provide the actual locking script later on (when we come to unlock it), which allows us to construct complex locking scripts without others having to worry about the details of it.
Same as before, except this time we’re including the hash of a script, and using the prefix 05
to indicate a P2SH.
Decoded:
And this is what a P2SH looks like:
Prefixes
As mentioned, the prefix you use will indicate the type of locking script to create.
Here are a list of common address prefixes:
In Bitcoin, different prefixes are added to data before converting to base58 to influence the leading character of the result. This leading character then helps us to identify what each base58 string represents.
These are the most common prefixes used in bitcoin:
Prefix (hex) | Base58 Leading Character | Represents | Example |
---|---|---|---|
00
|
1 | P2PKH Address |
1AKDDsfTh8uY4X3ppy1m7jw1fVMBSMkzjP
|
05
|
3 | P2SH Address |
34nSkinWC9rDDJiUY438qQN1JHmGqBHGW7
|
80
|
K / L |
WIF Private Key ![]() |
L4mee2GrpBSckB9SgC9WhHxvtEgKUvgvTiyYcGu38mr9CGKBGp93
|
80
|
5 |
WIF Private Key ![]() |
5KXWNXeaVMwjzMsrKPv8dmdEZuVPmPay4nm5SfVZCjLHoy1B56w
|
0488ADE4
|
xprv | Extended Private Key |
xprv9tuogRdb5YTgcL3P8Waj7REqDuQx4sXcodQaWTtEVFEp6yRKh1CjrWfXChnhgHeLDuXxo2auDZegMiVMGGxwxcrb2PmiGyCngLxvLeGsZRq
|
0488B21E
|
xpub | Extended Public Key |
xpub67uA5wAUuv1ypp7rEY7jUZBZmwFSULFUArLBJrHr3amnymkUEYWzQJz13zLacZv33sSuxKVmerpZeFExapBNt8HpAqtTtWqDQRAgyqSKUHu
|
Prefix (hex) | Base58 Leading Character | Represents | Example |
---|---|---|---|
6F
|
m / n | P2PKH Address |
ms2qxPw1Q2nTkm4eMHqe6mM7JAFqAwDhpB
|
C4
|
2 | P2SH Address |
2MwSNRexxm3uhAKF696xq3ztdiqgMj36rJo
|
EF
|
c |
WIF Private Key ![]() |
cV8e6wGiFF8succi4bxe4cTzWTyj9NncXm81ihMYdtW9T1QXV5gS
|
EF
|
9 |
WIF Private Key ![]() |
93J8xGU85b1sxRP8wjp3WNBCDZr6vZ8AQjd2XHr4YU5Lb21jS1L
|
04358394
|
tprv | Extended Private Key |
tprv9tuogRdb5YTgcL3P8Waj7REqDuQx4sXcodQaWTtEVFEp6yRKh1CjrWfXChnhgHeLDuXxo2auDZegMiVMGGxwxcrb2PmiGyCngLxvLeGsZRq
|
043587CF
|
tpub | Extended Public Key |
tpub67uA5wAUuv1ypp7rEY7jUZBZmwFSULFUArLBJrHr3amnymkUEYWzQJz13zLacZv33sSuxKVmerpZeFExapBNt8HpAqtTtWqDQRAgyqSKUHu
|
The hex prefix 00
does not naturally get converted to a “1” when encoding to base58. This conversion is performed manually in the code instead.
You’ll notice that WIF Private Keys use the same hex prefix, but produce different leading characters. This is because if a private key is used to create a compressed public key (which will produce a different address to an uncompressed public key), we also append a 01
to it before converting to base58. This extra byte has an effect on the leading character in the base58 result.
Extended Keys contain extra metadata alongside the original public and private keys, which is why their base58 strings are much longer.
https://en.bitcoin.it/wiki/List_of_address_prefixes
The prefix will also alter the leading character of an address, so you can tell what kind of locking script has been used by just looking at the address itself.
Why do we use addresses?
An address is a short-hand way of writing locking scripts in a human-readable way. - echeveria (on IRC)
If we didn’t use addresses, we would have to send other people complete locking scripts, like this:
76a914662ad25db00e7bb38bc04831ae48b4b446d1269888ac # P2PKH script
But by using addresses, we can just send something like this instead:
1AKDDsfTh8uY4X3ppy1m7jw1fVMBSMkzjP
They both achieve the same result, but addresses give us a more user-friendly format to pass around. Not to mention the fact that they contain a checksum, which means that errors can be detected if someone writes an address incorrectly.
Code
Note: This code requires the checksum.rb and base58_encode.rb functions.
def hash160_to_address(hash160, type=:p2pkh)
prefixes = {p2pkh: '00', # 1address - For standard bitcoin addresses
p2sh: '05', # 3address - For sending to an address that requires multiple signatures (multisig)
p2pkh_testnet: '6F', # (m/n)address
p2sh_testnet: 'C4' # 2address
}
prefix = prefixes[type]
checksum = checksum(prefix + hash160)
address = base58_encode(prefix + hash160 + checksum)
return address
end
'662ad25db00e7bb38bc04831ae48b4b446d12698'
hash160 = # 1AKDDsfTh8uY4X3ppy1m7jw1fVMBSMkzjP puts hash160_to_address(hash160)