Author: Anony, BTC Study
When users come into contact with Bitcoin, they often encounter the concept of "address" for the first time. When you try to receive Bitcoin payments, you need to provide your own address. When checking whether the payment has been received in the block browser, the specific address is often used as the search condition.
You may think: "An address is equivalent to a bank account in the Bitcoin world, which can be used to receive Bitcoin." But this understanding may still confuse you when facing some situations in the process of using the wallet. For example: When you first use a Bitcoin software wallet, it may ask you to choose an address "type", such as: "Bech32 (SegWit)", "P2PKH", "Nested-SegWit (P2SH)", etc. Even when you want to switch to another software wallet, it will scare you: the new software wallet may give you a set of Bitcoin addresses that are completely different from the original software wallet; at this time, what should you do?
This article is to explain the concept and type of Bitcoin addresses in a slightly deeper way, in order to help readers solve some problems that may be encountered in the process of self-custody of Bitcoin, including but not limited to the choice of address type and the troubles that may occur during the migration of software wallets.
The last chapter will focus on describing the characteristics and economics of different addresses that readers may come into contact with; if you are not interested in the technical details at all, or just want to quickly verify the information, you can jump to the last chapter; but if you want to plan a method of self-custody, it is recommended that you read from the beginning.
In short, Bitcoin addresses are actually the key data of the standardized Bitcoin script after special encoding (translation); the special encoding method makes it more suitable for transmission and provides the ability to warn of errors; and the difference in its economics comes from the difference in the economics of its underlying Bitcoin script.
Standardized Bitcoin Script
As we all know, Bitcoin is an electronic currency running in a peer-to-peer network. When developing Bitcoin, Satoshi Nakamoto designed a form of existence for this currency that was later called "UTXO". This form makes Bitcoin funds less like money placed in one account after another, but more like checks that are independent of each other. These checks record two key pieces of information: the denomination of the funds (in sats) and the script public key, which defines under what circumstances the money can be spent. The script public key is like a lock that requires a specific key to open it.
Satoshi realized that if we could customize clever locks, Bitcoin could be used more flexibly in different scenarios. So he also designed a programming language called "Bitcoin Script" and a UTXO-based transaction verification mode; thus, we can write programs that serve as script public keys, and when the relevant funds are spent, they can be verified according to such programs.
This innovation brings a practical difficulty: when transactions are propagated in a peer-to-peer network, the nodes that receive the transactions will first run some verification work. If this programming language and programming have inherent vulnerabilities that can cause nodes to crash in the process of verifying transactions, then transactions that can exploit this vulnerability can be used to destroy the entire network. How to strike a balance between the free propagation of transactions and the security of the network?
In addition to intentionally limiting the flexibility of Bitcoin Script, Satoshi Nakamoto also came up with a solution: define some scripts that are known to be concise enough and will not trigger failures as "standardized Bitcoin scripts" [1]; when spending funds using such scripts, the transaction is treated as a "standard Bitcoin transaction" and can be propagated unhindered in the network. On the contrary, if such a standardized script is not used, even if the transaction is valid, it can only be submitted directly to the miners, who will package it into a block and mine it before propagating it to the entire network. This limits the propagation of transactions that may cause security issues in the network and cause node crashes.
There are two earliest standardized Bitcoin scripts implemented: "P2PKH" and "P2PK"; as the name implies, they place a public key (or a hash of a public key) in the script public key, requiring transactions that spend funds to provide a signature of the public key (the private key behind it).
A P2PKH script public key looks like this:
OP_DUP OP_HASH160 55ae51684c43435da751ac8d2173b2652eb64105 OP_EQUALVERIFY OP_CHECKSIG
(From the famous Bitcoin popular science website: learn me a bitcoin)
The concept of address
Standardized scripts give the Bitcoin system basic functions (individuals can keep Bitcoins by holding private keys and initiate electronic currency payments to others). However, it is still a kind of data designed for computers - the subject to understand these strings is a computer. Computers are not sensitive to the length of the string, and will not make mistakes in the process of copying data. People are the opposite in many ways.
The problem is that people, as users of this system, do have to deal with this data: when a person receives a Bitcoin payment, what he requires is that the other party sends a sum of Bitcoin funds to a Bitcoin script controlled by him (or that he can successfully unlock); in addition, when he wants to keep his funds for a long time, he may need to back up his Bitcoin script.
What should we do at this time? A long string like the one above is obviously not suitable for transmission (too long) or backup (easy to copy wrong).
As we mentioned earlier, scripts that are useful to most people are standardized. This standardization means that two scripts differ only in one key data: for two P2PKH scripts, their only difference is the different public key hash values recorded. Therefore, when receiving payment, we only need to provide this hash value and the type of script (it is a P2PKH script), which is enough. The sender (their software) uses this information to recover the full Bitcoin script, which sends the bitcoins to the right place in the transaction.
And (Satoshi, being an engineering savvy, realized) we don’t have to pass the hexadecimal form of this hash (55ae51684c43435da751ac8d2173b2652eb64105
, 40 characters). With a specially designed encoding method, we can convert it into a shorter, more easily recognizable form.
This is the “address”: the encoded data that carries the key information that allows us to correctly recover the Bitcoin script.
Encoding method
Base58
"Base58" [2] It is an encoding method invented by Satoshi Nakamoto, which is modified from a famous encoding method "Base64". The character set of Base64 includes: all numbers and uppercase and lowercase letters, and two symbols ("+" and "/"); a total of 64 characters. Satoshi Nakamoto deleted the number 0, uppercase letters I and O, lowercase letter l and symbols from it, and it became Base58.
This deletion is deliberate. Satoshi Nakamoto's own statement is:
Why use base58 instead of base64?
0OIl is not used because these characters look similar and can be used to create accounts that look almost identical.
People are not easily accepted to have characters other than letters and numbers in account numbers.
If punctuation is not used, it will not be interrupted by line breaks in e-mail.
Double-clicking can select the entire string because it only contains letters and numbers.
– Satoshi Nakamoto, Bitcoin v0.1 (base58.h)
The address is to be restored to the Bitcoin script, so as long as one character is wrong, the funds may be sent to a completely different Bitcoin script (which may be a script that cannot be unlocked at all!), resulting in fund loss; even if such confusing characters are allowed, malware can quietly replace your address with an address that looks similar but is actually controlled by the attacker, causing you to lose funds when receiving payments.
Therefore, Satoshi Nakamoto's considerations are completely reasonable.
Before performing Base58 encoding, we also need to prefix the key data (such as the hash value in the above P2PKH script) with the type code as a prefix and the first 4 bytes of the result of two consecutive SHA256 operations of the prefixed key data as a suffix.
The prefix can quickly indicate the type and purpose of the data; and because of the prefix, the same type of data will always have the same beginning in the Base58 encoded result. This is why we only need to look at the beginning of a Bitcoin address to know what type of address it is.
The suffix can act as a checksum: if you enter an address with a typo into the software, the software will remind you that you may have made a mistake (although it cannot indicate where the mistake was).
That is, before we start encoding, we need to construct a string like this:
Type code + key data + SHA256(SHA256(type code + key data))[0:4] (the "+" here means string concatenation)
Taking the above P2PKH script as an example, we first need to prefix the key data (55ae51684c43435da751ac8d2173b2652eb64105
) with a prefix of 00
; then run two consecutive SHA256 calculations on this data, taking the first 4 bytes (8 in hexadecimal) characters, 96ab3cb1
), as the suffix, and get 0055ae51684c43435da751ac8d2173b2652eb6410596ab3cb1
. Finally, run Base58 encoding to get: 18p3G8gQ3oKy4U9EqnWs7UZswdqAMhE3r8
.
This string contains the key information used in the Bitcoin script (public key hash value), explains how to use it (the prefix 1
indicates that it should be restored to a P2PKH script), and has the function of detecting transcription errors. It is still only 34 characters, shorter than the original hash value.
Bech32
“Bech32” is an encoding method defined by BIP 0173 [3], the two authors of which are Pieter Wuille and Greg Maxwell. However, this encoding also has its own origins: "Bech" refers to "BCH" [4], which is a cyclic error correction coding algorithm invented by three mathematicians in 1959 and 1960 respectively (the name BCH comes from the surnames of these three mathematicians). And "32" means that the character set of this encoding method has only 32 characters: lowercase English letters and numbers, excluding the number "1", the letters "b", "i" and "o".
The consideration of this BIP is to use a new encoding method for the addresses of two new standardized scripts "P2WPKH" and "P2WSH" by taking advantage of the "Segregated Witness (SegWit)" upgrade.
At the beginning of BIP 0173, the authors pointed out the undesirable aspects of Base58:
Base58 uses both uppercase and lowercase English letters, which makes it impossible to use the smaller "digital alphabet" mode when drawing its data into a QR code, and can only use the larger "byte data" mode.
The use of both uppercase and lowercase also makes it difficult to copy, enter on a mobile phone keyboard, and read aloud.
The checksum requires two consecutive SHA256 operations, which is slow and has no error detection function.
Most encoding methods that can detect errors are only applicable when the character set size is a prime power, and 58 is not a prime power.
Base58 decoding is more complicated and the operation is slower.
Therefore, the new method of Bech32 only uses lowercase letters and numbers; when necessary (such as when drawing a QR code), these letters can be replaced with uppercase to obtain a more compact representation. At the same time, Bech32 also has the ability to locate errors: it can not only find out that you have copied incorrectly, but also point out which digits you copied incorrectly (this ability to find errors is far better than Base58).
In fact, the BCH algorithm also has an "error correction" function: it can not only point out which digits you copied incorrectly, but also point out what character it should be. However, the authors of BIP 0173 discovered its inherent dangers: on the one hand, strengthening the error correction function will weaken the function of locating errors; on the other hand, if users trust the software's error correction ability too much, the software may correct the wrong data entered by the user into a "valid but useless" data - although as a piece of BCH encoded data, it is valid; however, the Bitcoin script restored by it may not be controlled by the payee or even by anyone. This is extremely dangerous. Therefore, BIP 0173 carefully reminds: "In addition to reminding users which ones may have copied incorrectly, the software should not implement error correction capabilities (giving correction suggestions)."
In addition, Bech32 follows the pattern in Base58 encoding:
There will be a "meaningful data (hrp)" at the beginning of the Bech32 data, which is similar to the prefix in Base58, which can explain what kind of data this is.
hrp can use far more than 32 characters; therefore, Bech32 also uses the number "1" as a delimiter to separate hrp and the actual data to be decoded.
In addition to Bitcoin, many other projects have also adopted Bech32; data from different projects is distinguished from each other using hrp. Here is a list of registered hrp, which is very interesting (but only interesting) [5].
Bech32 also designs a checksum, which occupies the last 6 characters of the encoded data.
Assuming that we use exactly the same public key hash value as in the above case, its P2WPKH script will be: 0 55ae51684c43435da751ac8d2173b2652eb64105
(yes, it is simpler and more abstract than the original P2PKH); and its Bech32 encoded address is: bc1q2kh9z6zvgdp4mf634jxjzuajv5htvsg9ulykp8
, which is 42 characters long.
Bech32m
"Bech32m" is developed by BIP 0350 [6] The defined encoding method. It was proposed because developers found a vulnerability in Bech32 encoding:
When the last character is "p", inserting or deleting any number of "q" in front of the character will not cause the checksum error, so the checksum mechanism is completely useless.
If no more standardized Bitcoin scripts are added, this problem is easy to solve: P2WPKH addresses and P2WSH addresses have a fixed length, and adding length checks will be enough. However, considering that we will add new standardized scripts in the future, the address length may change, so it is necessary to fix this problem.
Bech32m fixes this problem by changing a parameter in the Bech32 checksum generation program.
Currently, Bech32m is only used to encode the address of the "P2TR" script added with the "Taproot" upgrade. It may be used in the address encoding of other standardized scripts in the future.
Economics
Once we understand that an address is a special form of a standardized Bitcoin script and that the type of address actually comes from the type of a standardized Bitcoin script, the question of why different types of addresses have different economics - and may have different transaction fees when spent - is also solved. This is because different Bitcoin scripts have different economics.
In order to maintain the decentralization and security of the network, the block size of Bitcoin is limited, and scripts that can make transactions smaller have an economic advantage.
In this regard, the biggest change was the "Segregated Witness (SegWit)" soft fork activated in 2017. While Segregated Witness brings two new standardized scripts "P2WPKH" and "P2WSH", it also designs a new transaction verification mode for these two scripts:
In traditional Bitcoin scripts, the data used to verify the procedure defined by the script public key (such as a digital signature) will be placed in the transaction (the scriptSignature
field); this brings about the so-called "transaction melting" problem[7], which hinders us from using Bitcoin scripts to program multi-party applications, and may even make wallets completely unable to track transactions.
The transaction verification mode of Segregated Witness will put this part of data outside the transaction (witness
field); moreover, Segregated Witness introduces a new unit of volume measurement ("virtual byte (vByte)"), and the data placed in the witness field will be discounted when measuring the volume (this is an intentional design, in order to make Segregated Witness transactions more economical than traditional transactions).
The final result is that Segregated Witness type scripts P2WPKH and P2WSH have significantly better economics than traditional scripts P2PKH and P2SH: on the one hand, the script public key of the Segregated Witness script is more concise; on the other hand, the signature of the traditional script is placed in the transaction, and the signature of the Segregated Witness script is placed outside the transaction. Even if the data volume is the same, the vByte of the latter is smaller.
Here is a table that shows how much volume different types of scripts will occupy when used as inputs and outputs of transactions.
- Picture from: Optech Limited Weekly·Waiting for Confirmation -
Then, there is also a transaction volume calculator that can tell you how much volume of transactions will be caused by different amounts of a certain type of script.
Note: When considering economics, you cannot only compare the size of the script as an input, because Bitcoin transactions generally have "change outputs" (the amount of funds you provide for the transaction is often greater than the payment amount, so some money is transferred back to yourself). Change outputs usually use the same type of script as the wallet receiving address.
Address Types
This section will introduce the characteristics and economics of different types of addresses that users may encounter.
P2PKH
Uses Base58 encoding. Starts with the number "1" and is generally 34 characters long.
Used for single-signature wallets.
Poor economic performance.
Example (same as above): 18p3G8gQ3oKy4U9EqnWs7UZswdqAMhE3r8
P2SH
Use Base58 encoding. Starts with the number "3" and is generally 34 characters long.
The P2SH address that users are most often exposed to is actually the address of a script called "Nested SegWit (P2SH)", which means "P2SH script encapsulated with a segregated witness script".
The ability to achieve this encapsulation is the ability of P2SH itself, but the fundamental purpose of defining this encapsulation is to deal with the compatibility issues of wallet software. Since the address of the segregated witness uses a completely new encoding method, wallet software that does not implement the new method will recognize the segregated witness address as an incorrect input and cannot recover a valid Bitcoin script from it. The Nested SegWit P2SH script provides an appropriate compromise: the payer's wallet (whether upgraded or not) will understand such an address as a normal P2SH address, and then restore a P2SH script and correctly construct the transaction; when the recipient spends the funds later, he can get some of the benefits brought by the segregated witness (with the help of wallet software that supports segregated witness).
When it is a single-signature wallet, the economy is better than P2PKH.
It can be used for multi-signature wallets (regardless of whether the segregated witness feature is used).
Example: 38Y2PBD1mihxtoVncaSz3oC2vRrjNF8sA2
(This P2SH script wraps the same P2PKH script as above, although this doesn’t do any good)
P2WPKH
Native SegWit script. Uses Bech32 encoding, starts with the numbers and letters “bc1q”, and is 42 characters long.
Used for single-signature wallets.
The economic performance is significantly better than P2PKH and Nested SegWit P2SH.
Example (same as above): bc1q2kh9z6zvgdp4mf634jxjzuajv5htvsg9ulykp8
P2WSH
Native segregated witness script. Uses Bech32 encoding, starts with numbers and letters "bc1q", and is 62 characters long.
Usually used in multi-signature wallets.
As a multi-signature wallet, its economic efficiency is significantly better than P2SH.
Example: bc1q56cuwyqlmq64aq0y3c8swd8a9gefe4wf7faxe2uyatyahfrly5aq0e6mfc
(this P2WSH script wraps the same P2PKH script as above, although that doesn’t do it any good)
P2TR
Native SegWit script (Taproot is “SegWit v1”). It uses Bech32m encoding, starts with "bc1p", and is 62 characters long.
It can be used for both single-signature and multi-signature wallets.
As a single-signature wallet, the economics are slightly better than P2WPKH, but almost indistinguishable (assuming one input and one change output as the inherent overhead of the transaction; the more inputs used, the greater the advantage of P2TR).
As a multi-signature wallet, the economics can be even better than P2WSH with the help of some Schnorr signature aggregation algorithms. However, at the time of this writing (November 2024), wallet software rarely implements such aggregation algorithms due to the complexity of their interactions.
The major difference between P2TR and the previous Bitcoin standard script is that the original script distinguishes between single-signature wallet users and users of advanced script functions ("smart contracts"), the former using public key hash scripts, and the latter (including advanced devices such as multi-signature devices and lightning channels) using redeem script hash scripts; P2TR unifies the two for the first time, making it impossible to directly infer the purpose of the script/address from its external form. Therefore, in the long run, P2TR will have better privacy.
To date, not all wallets support P2TR addresses (but almost all wallets support P2WPKH and P2WSH). Users' choices and migration capabilities are relatively limited. In addition, support for multi-signature devices based on P2TR is even rarer.
Example (randomly selected): bc1pxy5r3slcqc2nhc0r5698gmsqwruenj9c8pzmsy5cedp3649wyktstc6z3c
Conclusion
An address represents a specific Bitcoin script; such a Bitcoin script is standardized and can be fully restored based on the information in the address. Using a special encoding method, the address becomes more compact and has the function of checking transcription errors. The economics of different address types come from the economics of the standardized Bitcoin scripts behind them.
Appendix A. Descriptors
In the "Concept of Address" section, we have mentioned that in two scenarios, users may need a compact and reliable script record: payment (transfer) scenario and long-term custody scenario.
In the "Encoding Method" section, we can see that the design of these encoding methods is mainly based on the transmission process, not the long-term custody scenario. So, in the custody scenario, how should the address be saved?
Fortunately, we now have a proper way to represent a group of addresses (rather than just one), which is the "output (address) descriptor".
Since the birth of Bitcoin and the concept of addresses, the technology and security practices of self-custody have improved a lot. One major advancement is the so-called "hierarchical deterministic (HD) wallet", whose idea is to use a piece of secret material to derive many private keys according to a deterministic random algorithm, and then derive many addresses, so as to meet the security practice of "not reusing addresses" on the one hand, and minimize the burden of backing up private keys as much as possible.
The descriptor is also based on this concept. Its approach is to express the type of address and the steps to generate this group of addresses in plain text, plus a checksum. For example:
wpkh([8b47f816/84h/0h/0h]xpub6C8vwWQ[...]NgW2SnfL/<0;1>/*)#c38kz2nr
From the above text, we can see that it represents a set of P2WPKH addresses, and the public keys used in this set of addresses are from a master public key with a fingerprint of 8b47f816
according to 84h/0h/0h
BIP32 The derivation path is derived from the derivation path; and the derivation paths of 0
and 1
are used to distinguish the receiving address from the change address. Finally, c38kz2nr
is the checksum, which can be used to check whether there are any transcription errors.
Such a string is very suitable for long-term storage and wallet migration because it has completely described the process of generating this set of addresses.
Footnotes
1. https://en.bitcoin.it/wiki/Script#Script_examples ↩
2. https://learnmeabitcoin.com/technical/keys/base58/ ↩
3. https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki ↩
4. https://en.wikipedia.org/wiki/BCH_code ↩
5. https://github.com/satoshilabs/slips/blob/master/slip-0173.md ↩
6. https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki ↩
7. ht tps://www.btcstudy.org/2022/10/07/segregated-witness-benefits/#%E4%BF%AE%E5%A4%8D%E7%86%94%E8%9E%8D%E6%80%A7%E9%97%AE%E9%A2%98 ↩