What is scriptSig
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: