- The Role of Bitcoin Addresses in Scripts
- The different types of Bitcoin addresses
Receiving addresses are pieces of information embedded in scriptPubKey to lock newly created UTXOs. Simply put, an address serves to receive bitcoins. Let's explore their operation in connection with what we have studied in the previous chapters.
The Role of Bitcoin Addresses in Scripts
As explained earlier, a transaction's role is to transfer the ownership of bitcoins from inputs to outputs. This process involves consuming UTXOs as inputs while creating new UTXOs as outputs. These UTXOs are secured by scripts, which define the necessary conditions to unlock the funds.
When a user receives bitcoins, the sender creates a UTXO and locks it with a scriptPubKey. This script contains the rules to unlock the UTXO, typically specifying the signatures and public keys required. To spend this UTXO in a new transaction, the user must provide the requested information via a scriptSig. The execution of scriptSig in combination with scriptPubKey must return "true" or
1. If this condition is met, the UTXO can be spent to create a new UTXO, itself locked by a new scriptPubKey, and so on.It is precisely in the scriptPubKey that the receiving addresses are found. However, their use varies depending on the script standard adopted. Here is a summary table of the information contained in the scriptPubKey according to the standard used, as well as the information expected in the scriptSig to unlock the scriptPubKey.
| Standard | scriptPubKey | scriptSig | redeem script | witness |
| P2PK | <pubkey> OP_CHECKSIG | <signature> | ||
| P2PKH | OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG | <signature> <public key> | ||
| P2SH | OP_HASH160 <scriptHash> OP_EQUAL | <data pushes> <redeem script> | Arbitrary data | |
| P2WPKH | 0 <pubKeyHash> | <signature> <public key> | ||
| P2WSH | 0 <witnessScriptHash> | <data pushes> <witness script> | ||
| P2SH-P2WPKH | OP_HASH160 <redeemScriptHash> OP_EQUAL | <redeem script> | 0 <pubKeyHash> | <signature> <public key> |
| P2SH-P2WSH | OP_HASH160 <redeemScriptHash> OP_EQUAL | <redeem script> | 0 <scriptHash> | <data pushes> <witness script> |
| P2TR (key path) | 1 <public key> | <signature> | ||
| P2TR (script path) | 1 <public key> | <data pushes> <script> <control block> |
Source: Bitcoin Core PR review club of July 7, 2021 – Gloria Zhao
The opcodes used in a script are designed to manipulate information, and, if necessary, to compare or test it. Let's take the example of a P2PKH script, which is as follows:
OP_DUP OP_HASH160 OP_PUSHBYTES_20 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
As we will see in this chapter,
<pubKeyHash> actually represents the payload of the receiving address used to lock the UTXO. To unlock this scriptPubKey, it is necessary to provide a scriptSig containing:<signature> <public key>
In script language, the stack is a LIFO ("Last In, First Out") data structure used to temporarily store elements during script execution. Each script operation manipulates this stack, where elements can be added (push) or removed (pop). Scripts use the stack to evaluate expressions, store temporary variables, and manage conditions.
The execution of the script I just gave as an example follows this process:
- We have the scriptSig, the scriptPubKey, and the stack:
- The scriptSig is pushed onto the stack:
OP_DUPduplicates the public key provided in the scriptSig on the stack:
OP_HASH160returns the hash of the public key that was just duplicated:
OP_PUSHBYTES_20 <pubKeyHash>pushes the Bitcoin address contained in the scriptPubKey onto the stack:
OP_EQUALVERIFYverifies that the hashed public key matches the provided receiving address:
OP_CHECKSIG checks the signature contained in the scriptSig using the public key. This opcode essentially performs a signature verification as we described in part 3 of this training:- If
1remains on the stack, then the script is valid:
Therefore, to summarize, this script allows verifying, with the help of the digital signature, that the user claiming ownership of this UTXO and wishing to spend it indeed possesses the private key associated with the receiving address used during the creation of this UTXO.
The different types of Bitcoin addresses
Over the evolution of Bitcoin, several standard script models have been added. Each of them uses a distinct type of receiving address. Here is an overview of the main script models available to date:
P2PK (Pay-to-PubKey):
This script model was introduced in the first version of Bitcoin by Satoshi Nakamoto. The P2PK script locks bitcoins directly using a raw public key (thus, no receiving address is used with this model). Its structure is simple: it contains a public key and requires a corresponding digital signature to unlock the funds. This script is part of the "Legacy" standard.
P2PKH (Pay-to-PubKey-Hash):
Like P2PK, the P2PKH script was introduced at the launch of Bitcoin. Unlike its predecessor, it locks the bitcoins using the hash of the public key, rather than directly using the raw public key. The scriptSig must then provide the public key associated with the receiving address, as well as a valid signature. The addresses corresponding to this model start with
1 and are encoded in base58check. This script also belongs to the "Legacy" standard.P2SH (Pay-to-Script-Hash):
Introduced in 2012 with BIP16, the P2SH model allows using the hash of an arbitrary script in the scriptPubKey. This hashed script, called "redeemScript", contains the conditions for unlocking the funds. To spend a UTXO locked with P2SH, it is necessary to provide a scriptSig containing the original redeemScript as well as the necessary data to validate it. This model is notably used for old multisigs. The addresses associated with P2SH start with
3 and are encoded in base58check. This script also belongs to the "Legacy" standard.P2WPKH (Pay-to-Witness-PubKey-Hash):
This script is similar to P2PKH, as it also locks bitcoins using the hash of a public key. However, unlike P2PKH, the scriptSig is moved to a separate section called "Witness". This is sometimes referred to as "scriptWitness" to denote the set comprising the signature and the public key. Each SegWit input has its own scriptWitness, and the collection of scriptWitnesses constitutes the Witness field of the transaction. This movement of signature data is an innovation introduced by the SegWit update, aimed particularly at preventing the malleability of transactions due to ECDSA signatures.
P2WPKH addresses use bech32 encoding and always start with
bc1q. This type of script corresponds to version 0 SegWit outputs.P2WSH (Pay-to-Witness-Script-Hash):
The P2WSH model was also introduced with the SegWit update in August 2017. Similar to the P2SH model, it locks bitcoins using the hash of a script. The main difference lies in how signatures and scripts are incorporated into the transaction. To spend bitcoins locked with this type of script, the recipient must provide the original script, called witnessScript (equivalent to redeemScript in P2SH), along with the necessary data to validate this witnessScript. This mechanism allows for the implementation of more complex spending conditions, such as multisigs.
P2WSH addresses use bech32 encoding and always start with
bc1q. This script also corresponds to version 0 SegWit outputs.P2TR (Pay-to-Taproot):
The P2TR model was introduced with the implementation of Taproot in November 2021. It is based on the Schnorr protocol for cryptographic key aggregation, as well as on a Merkle tree for alternative scripts, called MAST (Merkelized Alternative Script Tree). Unlike other types of scripts, where spending conditions are publicly exposed (either at receipt or at spending), P2TR allows for the hiding of complex scripts behind a single, apparent public key.
Technically, a P2TR script locks bitcoins on a unique Schnorr public key, denoted as . This key is actually an aggregate of a public key and a public key , the latter being calculated from the Merkle root of a list of scriptPubKey. Bitcoins locked with this type of script can be spent in two ways:
- By publishing a signature for the public key
(key path). - By satisfying one of the scripts contained in the Merkle tree (script path).
P2TR thus offers great flexibility, as it allows locking bitcoins either with a unique public key, with several scripts of choice, or both simultaneously. The advantage of this Merkle tree structure is that only the spending script used is revealed during the transaction, but all other alternative scripts remain secret.
P2TR corresponds to version 1 SegWit outputs, which means that the signatures for P2TR inputs are stored in the transaction's Witness section, and not in the scriptSig. P2TR addresses use the bech32m encoding and start with which is simply formatted with metadata. It is, therefore, a script model close to P2PK.
bc1p, but they are quite unique because they do not use a hash function for their construction. Indeed, they directly represent the public key Now that we have covered the theory, let's move on to practice! In the following chapter, I propose deriving both a SegWit v0 address and a SegWit v1 address from a pair of keys.
Quiz
Quiz1/5
cyp2015.6
What is the main difference between P2PK and P2PKH?