What are Bitcoin Scripts?
Introduction
Scripts are the heart of Bitcoin's transaction system. They define conditions that need to be satisfied to spend Bitcoin and are fundamental to understanding how transactions really work. This guide will explain what ScriptPubKey, ScriptSig, opcodes are, and how they combine to create valid Bitcoin transactions.
Important: This is an advanced level guide. We assume basic knowledge of Bitcoin transactions, UTXOs, and cryptography concepts. If you're a beginner, we recommend first understanding how transactions work before advancing to this technical content about scripts.
By the end of this guide, you'll understand how scripts work, how ScriptPubKey and ScriptSig combine, what opcodes are used, and how script structure defines who can spend Bitcoin.
What Are Scripts?
Basic Concept
Script is a simple, stack-based programming language used in Bitcoin to define spending conditions.
Main characteristics:
- Not Turing-complete: Cannot do infinite loops
- Stack-based: Operations work on a stack
- Deterministic: Always produces same result
- Limited: Few opcodes available
- Secure: Impossible to create malicious scripts that crash network
Why scripts exist?:
- Define who can spend Bitcoin
- Allow different types of transactions
- Foundation for advanced features (multisig, timelocks, etc.)
- Flexibility without excessive complexity
Simple analogy:
- Like a lock (ScriptPubKey) that needs correct key (ScriptSig)
- Script verifies if "key" opens "lock"
- If yes, transaction is valid
- If no, transaction is rejected
Script Structure in Transactions
In a Bitcoin transaction, scripts appear in two places:
1. ScriptPubKey (locking script):
- Defines conditions for spending output
- Stays in output of transaction
- Like a "lock"
2. ScriptSig (unlocking script):
- Provides data to satisfy ScriptPubKey
- Stays in input of transaction
- Like a "key"
Combination:
- ScriptSig + ScriptPubKey = complete script
- Complete script is executed to validate transaction
- If execution is successful, transaction is valid
ScriptPubKey: The Lock
What Is ScriptPubKey?
ScriptPubKey is the script that defines conditions for spending an output (UTXO).
Characteristics:
- Locks Bitcoin: Defines who can spend
- Stays on blockchain: Permanently recorded
- Can be simple or complex: From simple scripts to advanced multisig
- Cannot be changed: Once created, immutable
Where it is:
- In output of transaction
- Part of UTXO until spent
- Visible on blockchain forever
Common Types of ScriptPubKey
1. P2PKH (Pay to Public Key Hash):
ScriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
What it does:
- Verifies signature with public key
- Verifies hash of public key
- Most common format in simple transactions
2. P2SH (Pay to Script Hash):
ScriptPubKey: OP_HASH160 <scriptHash> OP_EQUAL
What it does:
- Allows more complex scripts
- Hash of script, not full script
- More flexible
3. P2WPKH (Pay to Witness Public Key Hash - SegWit):
ScriptPubKey: OP_0 <witnessPubKeyHash>
What it does:
- SegWit version of P2PKH
- Witness data separated
- Lower fees
4. P2WSH (Pay to Witness Script Hash - SegWit):
ScriptPubKey: OP_0 <witnessScriptHash>
What it does:
- SegWit version of P2SH
- Complex scripts with separated witness
- Lower fees
Simplified ScriptPubKey Example
Simple P2PKH ScriptPubKey:
OP_DUP
OP_HASH160
<20 bytes: public key hash>
OP_EQUALVERIFY
OP_CHECKSIG
What each part does:
OP_DUP: Duplicates item on top of stackOP_HASH160: Does SHA-256 followed by RIPEMD-160<20 bytes>: Hash of recipient's public keyOP_EQUALVERIFY: Verifies if two items are equalOP_CHECKSIG: Verifies signature
Meaning:
- "To spend this Bitcoin, you need to provide public key with this hash AND valid signature"
ScriptSig: The Key
What Is ScriptSig?
ScriptSig is the script that provides data to satisfy ScriptPubKey conditions.
Characteristics:
- Unlocks Bitcoin: Provides necessary data
- Spent after use: Doesn't stay on blockchain permanently (except in special cases)
- Must match: Must satisfy ScriptPubKey conditions
- Contains signature: Usually contains digital signature
Where it is:
- In input of transaction
- Provided when spending UTXO
- Removed after validation (in SegWit)
ScriptSig Structure
Typical ScriptSig for P2PKH:
<scriptSig> = <signature> <publicKey>
Components:
- Signature: Digital signature of transaction
- Public key: Public key corresponding to private key that signed
Simplified example:
<71 bytes: signature>
<33 bytes: public key>
How ScriptSig Satisfies ScriptPubKey
Validation process:
1. ScriptSig is executed first:
- Places signature and public key on stack
2. ScriptPubKey is executed after:
- Uses data left by ScriptSig
- Verifies conditions
- Returns true or false
3. If everything passes:
- Transaction is valid
- Output can be spent
If something fails:
- Transaction is rejected
- Output cannot be spent
Opcodes: The Language of Scripts
What Are Opcodes?
Opcodes are the instructions of Bitcoin script language.
Types of opcodes:
1. Constants:
- Place data on stack
- Example:
<0x41>places byte 0x41 on stack
2. Stack Operations:
- Manipulate stack
- Examples: OP_DUP, OP_DROP, OP_SWAP
3. Arithmetic Operations:
- Mathematical operations
- Examples: OP_ADD, OP_SUB, OP_MUL
4. Logical Operations:
- Boolean operations
- Examples: OP_EQUAL, OP_VERIFY, OP_NOT
5. Cryptographic Operations:
- Cryptographic verifications
- Examples: OP_CHECKSIG, OP_HASH160, OP_CHECKMULTISIG
6. Control Operations:
- Flow control
- Examples: OP_IF, OP_ELSE, OP_ENDIF
Most Important Opcodes
OP_DUP:
- Duplicates item on top of stack
- Useful for verifying public keys
OP_HASH160:
- Does SHA-256 followed by RIPEMD-160
- Used for public key hashes
OP_EQUALVERIFY:
- Verifies if two items are equal
- Removes items if equal
- Fails if not equal
OP_CHECKSIG:
- Verifies digital signature
- Crucial for security
- Verifies if signature corresponds to public key
OP_CHECKMULTISIG:
- Verifies multiple signatures
- Used in multisig
- Allows transactions needing multiple signatures
OP_RETURN:
- Marks output as unspendable
- Used for optional data
- Output is burned (cannot be spent)
Limits and Rules
Script limits:
- Maximum size: 10,000 bytes for complete script
- Stack size: Maximum 1,000 items
- Maximum item size: 520 bytes
Execution rules:
- Script must end with true value on top
- Cannot have infinite loops
- Must be deterministic
- Cannot access external data
Stack: How Scripts Work
What Is Stack?
Stack is data structure where scripts operate.
LIFO principle:
- Last In, First Out
- Last item in is first out
- Like stack of plates
Basic operations:
- PUSH: Adds item on top
- POP: Removes item from top
- PEEK: Looks at item on top without removing
Stack Execution Example
Simple script: verify if number is even:
5
OP_DUP
2
OP_MOD
0
OP_EQUAL
Step-by-step execution:
Initial stack: []
Step 1: PUSH 5:
Stack: [5]
Step 2: OP_DUP (duplicates 5):
Stack: [5, 5]
Step 3: PUSH 2:
Stack: [5, 5, 2]
Step 4: OP_MOD (5 mod 2 = 1):
Stack: [5, 1]
Step 5: PUSH 0:
Stack: [5, 1, 0]
Step 6: OP_EQUAL (1 == 0? No, so 0):
Stack: [5, 0]
Result: 0 (false) on top = script fails
Complete Script Execution
Example: P2PKH validation:
ScriptSig:
<signature>
<publicKey>
ScriptPubKey:
OP_DUP
OP_HASH160
<pubKeyHash>
OP_EQUALVERIFY
OP_CHECKSIG
Combined execution:
1. Execute ScriptSig:
Stack: [signature, publicKey]
2. Execute OP_DUP:
Stack: [signature, publicKey, publicKey]
3. Execute OP_HASH160:
Stack: [signature, publicKey, hash(publicKey)]
4. Execute PUSH pubKeyHash:
Stack: [signature, publicKey, hash(publicKey), pubKeyHash]
5. Execute OP_EQUALVERIFY:
- Verifies if hash(publicKey) == pubKeyHash
- If yes, removes both
- If no, script fails
Stack after OP_EQUALVERIFY (if passed):
Stack: [signature, publicKey]
6. Execute OP_CHECKSIG:
- Verifies if signature corresponds to publicKey
- If yes, places 1 (true) on stack
- If no, places 0 (false)
Final stack (if passed):
Stack: [1]
Result: Script passes (1 = true on top)
Common Types of Scripts
1. P2PKH (Pay to Public Key Hash)
Structure:
ScriptPubKey:
OP_DUP OP_HASH160 <20 bytes: pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
ScriptSig:
<signature> <publicKey>
Use: Simple transactions to one recipient
Simplified example:
ScriptPubKey: OP_DUP OP_HASH160 abc123... OP_EQUALVERIFY OP_CHECKSIG
ScriptSig: sig123... pubkey456...
2. P2SH (Pay to Script Hash)
Structure:
ScriptPubKey:
OP_HASH160 <20 bytes: scriptHash> OP_EQUAL
ScriptSig:
<redeemScript> <signatures...>
Use: Allows more complex scripts (multisig, etc.)
Advantage: Hash is smaller than complete script
Simplified example:
ScriptPubKey: OP_HASH160 hash789... OP_EQUAL
ScriptSig: redeemScript sig1 sig2
3. Multisig
Structure:
Redeem Script (inside P2SH):
<m> <pubKey1> <pubKey2> ... <pubKeyn> <n> OP_CHECKMULTISIG
Meaning:
- Needs
msignatures fromnkeys - Example: 2 of 3 (2 signatures from 3 keys)
Use: Shared wallets, additional security
Simplified example (2 of 3):
2 pubKey1 pubKey2 pubKey3 3 OP_CHECKMULTISIG
4. Timelocks
Structure:
OP_CHECKLOCKTIMEVERIFY:
- Verifies if time/block was reached
- Allows transactions with temporal lock
Use: Transactions that can only be spent after date
Simplified example:
<timestamp>
OP_CHECKLOCKTIMEVERIFY
OP_DROP
OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
5. OP_RETURN
Structure:
ScriptPubKey:
OP_RETURN <optional data>
What it does:
- Marks output as unspendable
- Used to store data on blockchain
- Bitcoin in this output is "burned"
Use: Metadata, proof of existence, etc.
Simplified example:
OP_RETURN Hello World
Simplified Real Examples
Example 1: Simple P2PKH Transaction
Scenario: Alice sends Bitcoin to Bob
Output from previous transaction (Bob will spend):
ScriptPubKey: OP_DUP OP_HASH160 <Bob's public key hash> OP_EQUALVERIFY OP_CHECKSIG
Input of current transaction (Bob spends):
ScriptSig: <Bob's signature> <Bob's public key>
Validation:
- ScriptSig places signature and public key on stack
- ScriptPubKey verifies if public key hash corresponds
- ScriptPubKey verifies if signature is valid
- If both pass, transaction is valid
Example 2: Multisig Transaction (2 of 3)
Scenario: Company with 3 directors, needs 2 signatures
Redeem Script (inside P2SH):
2
<pubKey director1>
<pubKey director2>
<pubKey director3>
3
OP_CHECKMULTISIG
ScriptPubKey (P2SH):
OP_HASH160 <hash of redeem script above> OP_EQUAL
ScriptSig (when spending):
<redeem script>
<signature director1>
<signature director2>
<empty> (OP_CHECKMULTISIG has bug that needs extra element)
Validation:
- Verifies hash of redeem script
- Executes redeem script with signatures
- Verifies if 2 signatures from 3 are valid
- If yes, transaction is valid
Example 3: Timelock
Scenario: Bitcoin can only be spent after January 1, 2026
ScriptPubKey:
<timestamp: 1735689600> (Jan 1 2026)
OP_CHECKLOCKTIMEVERIFY
OP_DROP
OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Validation:
- Verifies if current time >= timestamp
- If no, script fails
- If yes, continues normal signature verification
Script Security
Why Are Scripts Secure?
Security limitations:
1. Not Turing-complete:
- Cannot do infinite loops
- Always terminates
- Cannot crash network
2. Deterministic:
- Always produces same result
- No randomness
- Predictable
3. No external access:
- Cannot access internet
- Cannot access files
- Isolated
4. Resource limits:
- Maximum script size
- Maximum stack size
- Maximum execution time
Impossible Attacks
What scripts CANNOT do:
1. Infinite Loops:
- No loops, cannot hang
- Always terminates
2. Access External Data:
- Cannot make HTTP requests
- Cannot access other blockchains
- Isolated
3. Create Bitcoin:
- Cannot create Bitcoin from nothing
- Economic rules validated separately
4. Alter Blockchain:
- Scripts only validate
- Don't modify existing blockchain
Transaction Structure
Where Are Scripts?
Simplified transaction structure:
Transaction:
- Version
- Inputs:
- Previous transaction hash
- Output index
- ScriptSig (unlocking script)
- Sequence
- Outputs:
- Value (in satoshis)
- ScriptPubKey (locking script)
- Locktime
ScriptSig:
- In each input
- Provides data to spend UTXO
- Removed after validation (SegWit)
ScriptPubKey:
- In each output
- Defines spending conditions
- Stays on blockchain
SegWit and Scripts
What SegWit changed:
Before (legacy):
- ScriptSig stayed in inputs
- Data stayed on blockchain permanently
- Higher fees
After (SegWit):
- ScriptSig (witness) separated
- Doesn't count in base transaction size
- Lower fees
- Simplified ScriptPubKey
SegWit advantage:
- Smaller transactions
- Lower fees
- More space for transactions in block
Frequently Asked Questions
Can scripts be changed after creation?
No. ScriptPubKey stays permanently on blockchain and cannot be changed. You can only spend output by providing correct ScriptSig.
Can I create my own script type?
Technically yes, but you're limited to available opcodes. Custom scripts need to follow consensus rules.
Are scripts complete programs?
No. Scripts are very limited. Cannot do loops, cannot access external data, and must always terminate. They're more like formulas than complete programs.
Why aren't scripts Turing-complete?
For security. If they were Turing-complete, they could have infinite loops and crash network. Limitations ensure scripts always terminate.
Do scripts affect privacy?
Yes, they can. Complex scripts can be identified on blockchain. Multisig, timelocks, etc. can leak information about how Bitcoin is used.
Can I see scripts in real transactions?
Yes. You can explore blockchain and see ScriptPubKey of any output. ScriptSig usually isn't visible (except in legacy non-SegWit transactions).
Conclusion
Scripts are fundamental to understanding how Bitcoin transactions really work. They define spending conditions through ScriptPubKey and ScriptSig, using opcodes to execute verifications on the stack.
The main points you need to understand are:
- ScriptPubKey defines conditions - Like a "lock" that locks Bitcoin
- ScriptSig satisfies conditions - Like a "key" that unlocks Bitcoin
- Opcodes are instructions - Simple commands that scripts execute
- Stack is where it operates - Stack where data is manipulated
- Scripts are limited - Not Turing-complete for security
- Common types exist - P2PKH, P2SH, multisig, timelocks, etc.
Scripts are one of the most interesting and fundamental parts of Bitcoin. They allow flexibility without excessive complexity, security without risks of infinite loops, and advanced features like multisig and timelocks.
Understanding scripts is understanding the true structure of Bitcoin transactions. Every transaction you make uses scripts, even if you don't see them directly. Scripts define who can spend each Bitcoin and how.
If you want to deeply understand how Bitcoin works, understanding scripts is essential. It's advanced technical knowledge that opens doors to understand more complex Bitcoin features, like Lightning Network, simple smart contracts, and other technologies built on scripts.