← Back to list

4 ways Bitcoin UTXO locking and unlocking scripts work

In Bitcoin, ownership of value is determined by the UTXO model (Unspent Transaction Outputs).

Daniel Adesubomi Oniya · 2023-02-09 11:26 · 5 claps · 5.7 min read
#bitcoin #utxo-model #script #witness #scriptsig
Open on Medium ↗
Wiki topics: CRY · Crypto & Web3

4 ways Bitcoin UTXO locking and unlocking scripts work

In Bitcoin, ownership of value is determined by the UTXO model (Unspent Transaction Outputs).

Let’s say you have 3,000 sats in your wallet, it means that these sats are locked to one or more UTXOs. To spend this value, you have to provide proof of ownership of the UTXO by unlocking it. Then, the value is locked to a new UTXO controlled by the recipient, so only they can spend it.

This is all made possible with Bitcoin SCRIPT.

SCRIPT makes Bitcoin programmable, allowing for flexibility and customization. If you have a programming background, you can understand the potential this offers.

Under the hood of a transaction, SCRIPT is used to define the conditions for releasing and locking the funds stored in UTXOs. These conditions are defined as a set of instructions written and stored in the ScriptPubKey field of a transaction output. When a user wants to spend a UTXO, they provide the corresponding ScriptSig, which is a set of instructions that satisfies the unlocking conditions set in the ScriptPubKey.

The script used to lock a UTXO is referred to as a locking script, while the information provided to unlock it is called a witness script. The witness script and locking script are combined and executed together. If the result is true, it means that the funds can be spent by whoever provided the signature.

For the sake of this article, I will be separating the witness script from the locking script using a comma (,). You wouldn’t be doing this in practise.

# Example
ScriptSig: {WITNESS_SCRIPT}, {LOCKING_SCRIPT}

In this article, we’ll take a look at the different types of Bitcoin SCRIPT locking mechanisms, and how they are used to lock and unlock UTXOs for the following:

  1. Pay-to-Public-Key (p2pk)
  2. Pay-to-Public-Key-Hash (p2pkh)
  3. Pay-to-Multi-Signature (p2ms)
  4. Pay-to-Script-Hash (p2sh)

1. Pay-to-Public-Key (p2pk)

In a p2pk script, the ScriptPubKey is simply a public key, and the ScriptSig is a valid digital signature made using the corresponding private key. When a user wants to spend a UTXO locked with a p2pk script, they must provide a ScriptSig that is a valid digital signature made using the private key corresponding to the public key in the ScriptPubKey.

# Locking script on the output (the UTXO you own)
Lock: <PUBKEY> CHECKSIG

# Unlock Script on the UTXO we want to use as input
Unlock: <SIGNATURE>, <PUBKEY> CHECKSIG

I must warn you, this mechanism is no longer used because it is rarely used in practice, as it provides no mechanism for addressing, so it is not possible to determine who the funds belong to.

2. Pay-to-Public-Key-Hash (p2pkh)

A public key hash is simply a hash of its public key. For example, here is a public key: “032faa3c69f1c2848826baaa129f67abf55bacb1599c03f291800bd1922c842a98”. And here is a hash of this public key: “171tkotFhPYDidC2qhwkrDdrHD287DmAQD”

Hashing a public key provides extra security because hashing algorithms are one-way. You can get the public key hash (address) from the public key through hashing, but it is not possible to get the public key from the hash. This makes it safer to share your address with others without the risk of revealing your public key.

The p2pkh script is more commonly used and provides a simple mechanism for addressing based on the aforementioned reason. The ScriptPubKey is a hash of the public key, and the ScriptSig is a combination of the original public key and a valid digital signature made using the corresponding private key.

When a user wants to spend a UTXO locked with a p2pkh script, they must provide a ScriptSig that includes the original public key and a valid digital signature. The digital signature is valid if it was generated using the private key corresponding to that public key.

# Locking script on the output (the UTXO you own)
Lock: DUP HASH160 <PUBKEY_HASH> EQUALVERIFY CHECKSIG

# Unlock Script on the UTXO we want to use as input
Unlock: <SIGNATURE> <PUBKEY>, DUP HASH160 <PUBKEY_HASH> EQUALVERIFY CHECKSIG

The ScriptPubKey is used to confirm that the public key and signature are correct, and to ensure that the funds belong to the user who provided the ScriptSig.

3. Pay-to-Multi-Signature (p2ms)

The p2ms script allows for multiple signatures to be required before a UTXO can be spent. The ScriptPubKey is a combination of the number of signatures required, the public keys of the signatories, and the hash of the redeem script. While the ScriptSig is a combination of the signatures and the redeem script.

# Locking script on the output (the UTXO you own)
Lock: [M] PUBKEY_1 PUBKEY_2 PUBKEY_3 [N] CHECKMULTISIG

The example lock script above describe the mechanism for locking funds to N number of parties wherewith the funds can be unlocked if M number of the parties provide signatures that match the PUBKEYs in the script (i.e. PUBKEY_1, PUBKEY_2, PUBKEY_3)

When a user wants to spend a UTXO locked with a p2ms script, they must provide a ScriptSig that includes the required number of signatures (in order) and the redeem script. The ScriptPubKey checks that the required number of signatures have been provided, and also confirms that the signatures and redeem script match correctly.

# Locking script on the output (the UTXO you own)
# This locks funds to a 2 or 3 multisig address.
Lock: [2] <PUBKEY_1> <PUBKEY_2> <PUBKEY_3> [3] CHECKMULTISIG

# Unlock Script on the UTXO we want to use as input

# Sample 1
Unlock: 0 <SIG_1> <SIG_2>, [2] <PUBKEY_1> <PUBKEY_2> <PUBKEY_3> [3] CHECKMULTISIG

# Sample 2
Unlock: 0 <SIG_1> <SIG_3>, [2] <PUBKEY_1> <PUBKEY_2> <PUBKEY_3> [3] CHECKMULTISIG

The essence of the multiple samples is to show that the order matters. You would also have noticed the zero (0) that was added to the script. This is a tiny caveat to this script that requires that you provide the same number of public keys as the number of signatures. Therefore, if the number of signatures required is less than the number of public keys, you would have to provide zero (0) in place of the absent signatories.

There is more to this p2ms and multi-signatures in Bitcoin, but that is beyond the scope of this material.

4. Pay-to-Script-Hash (p2sh)

The p2sh is an improvement made on the p2ms.

But why do we need to improve p2ms. Let me explain…

Imagine creating a 6-of-8 multi-signature locking script, which would require eight valid signatures to unlock the funds. As the script becomes longer and more complex, it requires more memory and bandwidth, which is unfavorable for miners on the network.

# Sample of a long p2ms unlocking script 😢
Unlock: 0 0 <SIG_1> <SIG_2> <SIG_3> <SIG_4> <SIG_5> <SIG_6>, 6 <PUBKEY_1> <PUBKEY_2> <PUBKEY_3> <PUBKEY_4> <PUBKEY_5> <PUBKEY_6> <PUBKEY_7> <PUBKEY_8> 8 CHECKMULTISIG

The problem of long and complex locking scripts is addressed in Bitcoin with the use of Pay to Script Hash (p2sh) transactions. In p2sh, the locking script is hashed and the hash is used in place of the actual script. This hash is then included in a special address format, called a p2sh address.

Instead of including the full locking script in a transaction, only the hash of the script is included. This greatly reduces the amount of memory and bandwidth required to process the transaction, making it more favorable for miners. To spend funds from a p2sh address, the spender must provide the full locking script, along with the signatures required to satisfy it, in a subsequent transaction.

In the case of a 6-of-8 multi-signature locking script, the hash of the script would be included in a p2sh address. When the funds at that address are spent, the full 6-of-8 script, along with the necessary six signatures, would be provided in the spending transaction. This way, the long and complex script is only processed when necessary, reducing the burden on the network and the party who locked the funds in the first place.

# Sample of a p2ms locking script [LOCK_SCRIPT]
2 PUBKEY_1 PUBKEY_2 PUBKEY_3 8

# Sample hash* of the unlocking script [SCRIPTHASH]
*2a129f67abf55 # NOT PRACTICAL, JUST AN EXAMPLE

# p2sh lock script
Lock: HASH160 [SCRIPTHASH] EQUAL

# pwsh unlock script
Unlock: [0] [SIG_1] [SIG_2] [2] [PUBKEY_1] [PUBKEY_2] [PUBKEY_3] 3 CHECKMULTISIG, HASH160 [SCRIPTHASH] EQUAL

As we can see, when a user wants to spend a UTXO locked with a p2sh script, they must provide a ScriptSig that includes the redeem script and the corresponding signatures. The ScriptPubKey is used to confirm that the redeem script and signatures are correct and that the redeem script has been executed successfully.

— — — — — — — — — — — — — — — —

Bitcoin is definitely the future of finance. And as we come along, Bitcoin will keep evolving, especially to cater to the needs of more complex and sophisticated transaction models. I can assure you that models will soon be developed. One such is the Shnorr & Taproot, which I will discuss later.

I hope you find this useful 💪🏽 Happy coding 🎉


메타데이터
post_id
e4ea70fae95d
slug
4-ways-bitcoin-utxo-locking-and-unlocking-scripts-work-e4ea70fae95d
url
https://medium.com/@Adesubomi/4-ways-bitcoin-utxo-locking-and-unlocking-scripts-work-e4ea70fae95d
canonical_url
https://medium.com/@Adesubomi/4-ways-bitcoin-utxo-locking-and-unlocking-scripts-work-e4ea70fae95d
author_url
https://medium.com/@Adesubomi
status
ok
fetched_at
2026-07-26 04:19:54