How I Demystified Bitcoin Scripting: A Quick Learning Journal


When I first revisited how scripting works on Bitcoin, my aim was to understand what happens “under the hood” when BTC moves from one address to another, and why scripting is even needed for this.
My journey started with Taproot—the latest upgrade. I learned Taproot brings Schnorr signatures (for aggregated and cheaper signatures), MAST (for keeping unused scripts private), and Pay-to-Taproot (where outputs can be spent via key or script path). In simple terms, Taproot boosts privacy, efficiency, and opens up smart contract possibilities on Bitcoin by letting complex transactions look like any other[conversation history].
But the basics matter, so I zoomed out: What is Bitcoin scripting, really?
It’s a simple, stack-based language that lets you attach "locks" (rules in code) to coins.
To spend those coins, you must "unlock" them with the correct "key"—but the “key” is not just your private key; it’s script data (like public key plus signature) that proves you satisfy the original locking rule.
To get hands-on, I broke down real script examples. Before I explain those scripts, here are popular examples:
Pay-to-Public-Key-Hash (P2PKH):
The standard "send to address" transaction.
Locking script (
scriptPubKey
):textOP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Unlocking script (
scriptSig
):text<signature> <public key>
Explanation: The locking script says, "To spend, provide a public key that matches the address hash and a valid signature." The unlocking script supplies these
Breakdown of P2PKH Bitcoin Script:
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
1. OP_DUP
Duplicates the top item on the stack.
Purpose: Takes the public key provided by the spender and creates a copy, so one copy can be checked against the address hash, while the other is used to verify the signature.
2. OP_HASH160
Hashes the top item with SHA-256, then RIPEMD-160 (two hash functions).
Purpose: Turns the public key into a 20-byte hash (the format used by Bitcoin addresses).
3. <PubKeyHash>
This is not an opcode but a value: the recipient’s public key hash, embedded in the locking script. This is hardcoded in the script when a transaction happens.
Purpose: Sets the expected address hash that the spender must prove ownership over.
4. OP_EQUALVERIFY
Checks that the two top items on the stack are equal. If not, script execution fails.
Purpose: Ensures the provided public key matches the intended recipient’s hash (i.e., you’re trying to spend from your own address).
5. OP_CHECKSIG
Verifies the provided signature matches the public key and transaction data.
Purpose: Proves that the spender knows the private key and authorizes the spend.
Script Flow
The unlocking script (from the spender) provides:
<signature> <public key>
Together with the locking script, the full script run is:
<signature> <public key> OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Step-by-Step Example
On running each command, the following changes happen to the stack.
Stack:
<signature> <public key>
OP_DUP
:<signature> <public key> <public key>
OP_HASH160
:<signature> <public key> <PubKeyHashGenerated>
<PubKeyHash>
:<signature> <public key> <PubKeyHashGenerated> <PubKeyHash>
OP_EQUALVERIFY
: Fails if<PubKeyHashGenerated>
≠<PubKeyHash>
. Removes both if equal.OP_CHECKSIG
: Checks<signature>
is valid for<public key>
, authorizing the spend.
Short version:
Each part ensures you’re spending from your own address (matching public key hash) and have the right private key (signature verification). This is the bedrock of basic Bitcoin security.
Pay-to-Script-Hash (P2SH):
Supports things like multisig.
Locking script:
textOP_HASH160 <script hash> OP_EQUAL
Unlocking script:
text<signatures> <redeem script>
Explanation: To unlock, you supply signatures and the full redeem script that matches the hash.
P2SH turns even complex spending conditions (like 2-out-of-3 multisig) into short addresses by putting only their hash on-chain:
OP_HASH160 <script hash> OP_EQUAL
Example redeem script:
OP_2 <pubkey 1> <pubkey 2> <pubkey 3> OP_3 OP_CHECKMULTISIG
When spending, the full script (e.g., the actual multisig rules) only needs to be revealed once—at the time of spend, not when received. This means more privacy and flexibility.
Key insights I gathered:
Bitcoin scripts make transactions programmable, but intentionally simple for security. They are not Turing complete.
“Unlocking script” means more than just a private key—it’s a bundle of data or code that satisfies whatever locking rules were set, giving massive flexibility for innovation (multisig wallets, time-locks, etc.).
All these building blocks—Taproot, P2PKH, P2SH—layer up to make Bitcoin a secure, flexible, and (with Taproot) increasingly private programmable money system.
Bottom line:
Bitcoin scripting defines who can spend coins and under what conditions—sometimes as simple as “prove you own this key,” sometimes as complex as “get approval from 2 of 3 people,” all enforced by a minimal, reliable scripting engine. Now, with Taproot and beyond, we’re witnessing the next leap in what’s possible on Bitcoin.
Subscribe to my newsletter
Read articles from Akira directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
