Author: Anony
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 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 Bitcoins." However, this understanding may still confuse you in some situations when using a wallet. For example, when you first use a Bitcoin software wallet, it may ask you to select 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; what should you do at this time?
This article is to provide a slightly more in-depth explanation of the concept and types of Bitcoin addresses, 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 encounter; if you are not interested in the technical details at all, or just want to quickly verify the information, you can skip to the last chapter; but if you want to plan a self-custody method, it is recommended that you read from the beginning.
In short, the Bitcoin address is actually the result of special encoding (translation) of the key data used in the standardized Bitcoin script ; the special encoding method makes it more suitable for transmission and provides the ability to alert errors; and the difference in its economic efficiency comes from the difference in the economic efficiency of its underlying Bitcoin script.
Standardized Bitcoin Script
As we all know, Bitcoin is an electronic currency that runs on 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 independent checks. These "checks" record two key information: the denomination of the funds (in "sat"); the script public key (scriptPubkey), which is used to define under what circumstances the money can be spent. The script public key is like a lock that requires a specific key to open.
Satoshi Nakamoto realized that if we can customize clever locks, Bitcoin can 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 based on 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 the 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 transmitted unimpeded 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 spread of transactions that may cause security issues in the network and cause node crashes.
There were two earliest standardized Bitcoin scripts implemented: "P2PKH" and "P2PK"; as the names suggest, they place a public key (or a hash of a public key) in the script public key and require transactions that spend funds to provide a signature of that 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 functionality (individuals can keep Bitcoins by holding private keys and initiate electronic currency payments to others). However, it is still a type of data designed for computers - the subject that needs to understand these strings is the 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/she requires is that the other party send a sum of Bitcoin funds to a Bitcoin script that he/she controls (or that he/she can successfully unlock); in addition, when he/she wants to keep his/her funds for a long time, he/she may need to back up his/her own 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 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, the only difference is the different public key hash values recorded. Therefore, when receiving money, we only need to provide this hash value and the type of script (it is a P2PKH script). The payer (software) will restore the complete Bitcoin script based on this information, so that the Bitcoin will be sent to the right place in the transaction.
And (Satoshi, being an engineering savvy, realized) instead of passing around the hexadecimal form of this hash ( 55ae51684c43435da751ac8d2173b2652eb64105
, 40 characters), we can use a specially designed encoding to convert it into something shorter and more easily legible.
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] is an encoding method invented by Satoshi Nakamoto, which is modified from a famous encoding method called Base64. The character set of Base64 includes all numbers and uppercase and lowercase letters, as well as two symbols ("+" and "/"); a total of 64 characters. Satoshi Nakamoto deleted the number 0, uppercase letters I and O, lowercase letters l, and symbols from it, and it became Base58.
This deletion was considered. 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.
- It is not easy for people to accept characters other than letters and numbers in account numbers.
- Without punctuation, emails are usually not interrupted by line breaks.
- Double-clicking will select the entire string since it only contains letters and numbers.
– Satoshi Nakamoto, Bitcoin v0.1 (base58.h)
The address is to be restored to Bitcoin script, so as long as one character is wrong, the funds may be sent to a completely different Bitcoin script (which may be completely unblockable!), resulting in the loss of funds; even more, 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 add the type code as a prefix to the key data (such as the hash value in the above P2PKH script) 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 explain 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 acts as a checksum: if you enter an address with a typographical error 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:
类型码+ 关键数据+ SHA256(SHA256(类型码+ 关键数据))[0:4](这里的“+” 是字符串拼接的意思)
Taking the P2PKH script above as an example, we first add the prefix 00
to the key data ( 55ae51684c43435da751ac8d2173b2652eb64105
); then run two consecutive SHA256 calculations on this data, take the first 4 bytes (8 characters in hexadecimal, 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 into 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 the encoding defined by BIP 0173 [3] , whose co-authors are Pieter Wuille and Greg Maxwell. However, this encoding has its own origins: "Bech" refers to "BCH" [4] , a cyclic error-correcting coding algorithm invented by three mathematicians in 1959 and 1960 (the name BCH comes from the surnames of these three mathematicians). The "32" refers to the character set of this encoding method, which only has 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 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 point out the undesirability of Base58:
- Base58 uses both uppercase and lowercase English letters, which means that when its data is drawn into a QR code, it is impossible to use the smaller "numeric alphabet" mode and can only use the larger "byte data" mode.
- The use of both uppercase and lowercase letters also makes it difficult to copy, type on a cell phone keyboard, or read aloud.
- The checksum requires two consecutive SHA256 operations, which is slow and has no function for locating errors.
- Most encoding methods that can locate errors only work 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 characters you copied incorrectly, but also point out what characters 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 the user trusts the software's error correction ability too much, then 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 recipient or even by anyone. This is extremely dangerous. Therefore, BIP 0173 carefully reminds: "In addition to reminding users which characters may have copied incorrectly, the software should not implement error correction capabilities (give correction suggestions)."
In addition, Bech32 follows the pattern in Base58 encoding:
- There will be a section of "meaningful data (hrp)" at the beginning of Bech32 data, which is similar to the prefix in Base58, which can explain what kind of data it is.
- The characters that hrp can use are far more than 32; therefore, Bech32 also uses the number "1" as a separator to separate hrp and the data that is actually to be decoded.
- In addition to Bitcoin, many other projects have adopted Bech32; data from different projects is distinguished by hrp. Here is a list of registered hrp, which is quite interesting (but only interesting) [5] .
- Bech32 also has a checksum that occupies the last 6 characters of the encoded data.
Assuming we use exactly the same public key hash value as in the previous 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 an encoding method defined by BIP 0350 [6] . It was proposed because developers discovered a vulnerability in the Bech32 encoding:
When the last character is "p", inserting or deleting any number of "q" before the character will not cause a checksum error, so the checksum mechanism is completely useless.
If no more standardized Bitcoin scripts are added, this problem can be easily solved: P2WPKH addresses and P2WSH addresses have a certain length, and length verification can be added. 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 routine.
Currently, Bech32m is only used to encode the addresses of the "P2TR" script added with the "Taproot" upgrade. It may be used in the address encoding of other standardized scripts in the future.
Economical
Once we understand that an address is a special form of a standardized Bitcoin script and that the address type 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 — becomes clear. 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 economic advantages.
In this regard, the biggest change was the "Segregated Witness (SegWit)" soft fork activated in 2017. While Segregated Witness brought two new standardized scripts "P2WPKH" and "P2WSH", it also designed a new transaction verification mode for these two scripts:
In legacy Bitcoin scripts, data used to verify the procedure defined by the script public key (such as a digital signature) is placed in the transaction ( scriptSignature
field); this introduces the so-called “transaction melting” problem [7] , which prevents us from using Bitcoin scripts to program multi-party applications, and can even make it impossible for wallets to track transactions.
The transaction verification mode of Segregated Witness places this data outside the transaction ( witness
field); moreover, Segregated Witness introduces a new unit of measurement for volume ("virtual byte (vByte)"), and the data placed in the witness field will be discounted when measuring volume (this is an intentional design to make Segregated Witness transactions more economical than traditional transactions).
The end result is that the Segregated Witness type scripts P2WPKH and P2WSH have significantly better economic performance than the 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, while the signature of the Segregated Witness script is placed outside the transaction. Even if the data size is the same, the vByte of the latter is smaller.
Here is a table that shows how much size different types of scripts take up when used as transaction inputs and outputs.
- Image from: Optech Weekly Limited Edition·Awaiting confirmation-
Then, there's also a transaction volume calculator that can tell you how large a transaction will be with different amounts of a certain type of script.
Note: When considering economics, you cannot just compare the size of the script as an input, because Bitcoin transactions generally have "change outputs" (the amount of money 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 Type
This section describes the characteristics and economics of different types of addresses that users may come into contact with.
P2PKH
- Use Base58 encoding. Start with the number "1" and the length is usually 34 characters.
- For use with single-signature wallets.
- The economic efficiency is poor.
- Example (same as above):
18p3G8gQ3oKy4U9EqnWs7UZswdqAMhE3r8
P2SH
- Use Base58 encoding. Start with the number "3" and the length is usually 34 characters.
- The P2SH address that users are most familiar with is actually the address of a script called "Nested SegWit (P2SH)". The name means "P2SH script encapsulating the segregated witness script."
- Being able 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 new encoding method, wallet software that does not implement the new method will identify 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 recover a P2SH script and correctly construct the transaction; when the recipient spends the funds later, he can (with the help of wallet software that supports segregated witness) obtain some of the benefits brought by segregated witness.
- When using the same single-signature wallet, it is more economical than P2PKH.
- Can be used with multi-signature wallets (with or without the SegWit feature).
- Example:
38Y2PBD1mihxtoVncaSz3oC2vRrjNF8sA2
(This P2SH script wraps the same P2PKH script as above, although this does not do any good)
P2WP
- The original isolated witness script uses Bech32 encoding, starts with numbers and letters "bc1q", and is 42 characters long.
- For use with single-signature wallets.
- The economic performance is significantly better than P2PKH and Nested SegWit P2SH.
- Example (same as above):
bc1q2kh9z6zvgdp4mf634jxjzuajv5htvsg9ulykp8
P2W
- Native segregated witness script. Use Bech32 encoding, start with numbers and letters "bc1q", and have a length of 62 characters.
- Typically 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 this does not do any good)
P2TR
- The original Segregated Witness script (Taproot is "Segregated Witness v1"). It uses Bech32m encoding, starts with "bc1p", and is 62 characters long.
- It can be used for both single-signature wallets and multi-signature wallets.
- As a single-signature wallet, the economics are slightly better than P2WPKH, but almost indistinguishable (this assumes 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, with the help of some Schnorr signature aggregation algorithms, the economics can be better than P2WSH. However, at the time of writing this article (November 2024), wallet software rarely implements such aggregation algorithms due to the complexity of these algorithms in interaction.
- 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 uses public key hash scripts, and the latter (including advanced devices such as multi-signature devices and lightning channels) use redemption script hash scripts; P2TR unifies the two for the first time, making it impossible for us to directly infer the purpose of the script/address from its external form. Therefore, in the long run, P2TR will have better privacy.
- Currently, not all wallets support P2TR addresses (although almost all wallets support P2WPKH and P2WSH). Users are limited in their choice and migration capabilities. 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 Bitcoin scripts are standardized and can be fully restored based on the information in the address. Special encoding methods are used to make the address more compact and have the function of checking transcription errors. The economic efficiency of different address types comes from the economic efficiency of the standardized Bitcoin script 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 rather than 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 habits of self-custody have improved a lot. A major advancement is the so-called "hierarchical deterministic (HD) wallet", the idea of which 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 habit of "not reusing addresses" on the one hand, and reduce the burden of backing up private keys as much as possible.
The descriptor is also based on this concept. It expresses the address type and the steps to generate this set 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 key used in this set of addresses is derived from a master public key with a fingerprint of 8b47f816
according to the 84h/0h/0h
BIP32 derivation path; and the derivation path of 0
and 1
is used to distinguish the receiving address and 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 fully describes the process of generating this set of addresses.
footnote
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. https://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 ↩