As a Rust blockchain developer on a mission to build secure, low-level systems, I recently took a deep dive into the core mechanics of Bitcoin transactions. This blog post breaks down what I learned into clear, precise steps with a developer's eye — ideal for engineers, or anyone serious about understanding how real digital money moves.
🔊 TL;DR (But Detailed)
Bitcoin transactions follow a strict sequence: they are created, signed, verified, broadcast, and finally, confirmed into blocks. Each transaction uses two key components:
-
scriptSig
: the unlocking script (included by the sender) -
scriptPubKey
: the locking script (included in the output by the sender, meant for the recipient)
⛓️ Step-by-Step Bitcoin Transaction Lifecycle
1️⃣ Sender Creates a Transaction
- Selects UTXOs to spend (inputs)
- Signs each input using their private key
- Includes their public key in the
scriptSig
- Creates a new output (
scriptPubKey
) locked to the recipient’s public key hash (address)
scriptSig =
scriptPubKey = OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG
2️⃣ Nodes Validate the Transaction
- All Bitcoin full nodes independently verify:
- Is the signature valid for the transaction?
- Does the public key hash match the one in the locking script?
- The signature is verified using ECDSA math, not decryption
If all checks pass → ✅ added to mempool and possibly mined into a block
3️⃣ Recipient’s Wallet Detects the UTXO
- Monitors blockchain or queries a full node
- Matches
scriptPubKey
(locking script) against recipient’s address - If matched, adds the UTXO to recipient’s spendable balance
4️⃣ Recipient Sends Bitcoin to Another Person
- Uses wallet to:
- Select UTXOs
- Sign them with private key
- Include public key in new
scriptSig
- Lock outputs to new recipient’s public key hash
Repeat the cycle ♻️
🔐 scriptSig
vs. scriptPubKey
Script | Purpose | Location |
---|---|---|
scriptSig |
Unlock the previous UTXO | Transaction input |
scriptPubKey |
Lock the Bitcoin to a new address | Transaction output |
Example (Pay-to-PubKey-Hash):
scriptPubKey:
OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG
scriptSig:
⚖️ What Is P2SH (Pay-to-Script-Hash)?
P2SH enhances Bitcoin's flexibility:
- Instead of locking to a pubkey hash, you lock to a script hash
- Recipient provides the redeem script and required data during spending
Example:
scriptPubKey (P2SH):
OP_HASH160 OP_EQUAL
scriptSig:
Used for:
- Multi-signature wallets
- Escrow contracts
- Timelocked transactions
✅ Final Words
I aim to become protocol-native architect, and this journey into Bitcoin scripting is just the beginning.
Stay tuned for upcoming posts, where I’ll explore:
- How to build a Bitcoin wallet UTXO scanner in Rust
- Simulating script execution using Rust enums
- Comparing UTXO-based vs. account-based models
Thanks for reading! If you found this helpful, feel free to connect or collaborate. Let’s build trustless systems, together.