What is scriptSig (Unlocking Scripts and Execution)
What is scriptSig? (Unlocking Scripts and Execution)
If the scriptPubKey is the lock, the scriptSig is the key. Inside every transaction input is a scriptSig field containing the cryptographic proof—signatures and public keys—required to unlock and spend the referenced UTXO.
️ How Nodes Execute Validation Scripts
To confirm that Alice is authorized to spend her coins, a validating full node must run Alice's unlocking script against the output's locking script.
The Historical Vulnerability: Concatenation
In early versions of Bitcoin, nodes validated transactions by physically concatenating the two scripts together:
$$\text{Combined Script} = \text{scriptSig} + \text{scriptPubKey}$$
The node then ran this single combined string from left to right. However, this introduced a severe security flaw: a malicious spender could craft a scriptSig containing custom opcodes (such as a premature execution bypass) that manipulated the trailing scriptPubKey behavior.
️ The Modern Fix: Isolated Execution
To close this security hole, modern nodes validate scripts in two isolated phases:
┌────────────────────────────────────────────────────────┐
│ PHASE 1: scriptSig EXECUTION │
├────────────────────────────────────────────────────────┤
│ • Node executes scriptSig on an empty Stack. │
│ • Pushes Signatures and Public Keys onto the Stack. │
└───────────────────────────┬────────────────────────────┘
│
▼ (Passes State)
┌────────────────────────────────────────────────────────┐
│ PHASE 2: scriptPubKey EXECUTION │
├────────────────────────────────────────────────────────┤
│ • Node executes scriptPubKey using the Phase 1 Stack. │
│ • Runs cryptographic operations on the pushed keys. │
└───────────────────────────┬────────────────────────────┘
│
▼ (Evaluates Final State)
Is Top Item = 1?
[YES] ──► Spend Approved (Valid)
[NO] ──► Transaction Rejected (Invalid)
Step-by-Step Stack Trace of P2PKH Validation
Let's watch a node evaluate a standard legacy payment (P2PKH).
-
Alice's
scriptSig(Unlocking Script):<Alice_Sig> <Alice_PubKey> -
Previous
scriptPubKey(Locking Script):OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Below is the cycle-by-cycle trace of the virtual machine's RAM Stack during validation:
| Cycle | Script Instruction | Action Taken | Stack State (Bottom $\rightarrow$ Top) |
|---|---|---|---|
| 0 | — | Initial Empty Stack | [] (Empty) |
| 1 | <Alice_Sig> |
Push Alice's signature | [Alice_Sig] |
| 2 | <Alice_PubKey> |
Push Alice's public key | [Alice_Sig, Alice_PubKey] |
| 3 | OP_DUP |
Duplicates top item | [Alice_Sig, Alice_PubKey, Alice_PubKey] |
| 4 | OP_HASH160 |
Hashes top item | [Alice_Sig, Alice_PubKey, Alice_PubKeyHash] |
| 5 | <PubKeyHash> |
Pushes the locking target hash | [Alice_Sig, Alice_PubKey, Alice_PubKeyHash, Target_PubKeyHash] |
| 6 | OP_EQUALVERIFY |
Compares top two; pops both if equal; aborts if unequal | [Alice_Sig, Alice_PubKey] |
| 7 | OP_CHECKSIG |
Verifies the signature matches the public key | [1] (TRUE) |
The Final Result:
The execution terminates with exactly 1 (TRUE) on top of the stack. Because the top item is non-zero, the validation checks out, and Alice's transaction is verified as mathematically authentic!
TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation: