BIP65 - OP_CHECKLOCKTIMEVERIFY¶
BIP65 (Bitcoin Improvement Proposal 65) is one of the Bitcoin improvement proposals, put forward by Peter Todd in 2014. It introduced the OP_CHECKLOCKTIMEVERIFY (abbreviated OP_CLTV) opcode. This new opcode allows creating Bitcoin outputs that cannot be spent before a specific time or block height, bringing powerful time-lock functionality to Bitcoin and enabling complex applications such as inheritance planning, escrow services, and two-way pegging.
Core Concept¶
Before BIP65, Bitcoin's nLockTime field could delay a transaction's confirmation time, but had a major flaw: before the transaction was confirmed, the sender could create a new transaction without the nLockTime restriction to replace the original transaction, thereby bypassing the time-lock. This made nLockTime unusable for scenarios requiring mandatory time-locks.
BIP65 addresses this by introducing the OP_CHECKLOCKTIMEVERIFY opcode, which embeds the time-lock directly into the script, making it part of the output conditions. Once funds are sent to a script address containing OP_CLTV, nobody (including the sender) can spend those funds before the specified time, achieving true mandatory time-locking.
Problem Background¶
Limitations of nLockTime¶
Time-lock mechanisms before BIP65:
nLockTime Field: - Every transaction has an nLockTime field (4 bytes) - Specifies the earliest time/height at which a transaction can be included in a block - Value < 500,000,000: represents block height - Value >= 500,000,000: represents Unix timestamp
Fundamental Flaw:
Scenario: Alice creates a transaction for Bob
- nLockTime = 2025-12-31 (one year later)
- Output: 1 BTC to Bob
Problem:
1. Before the transaction is confirmed, Alice can create a new transaction
2. New transaction: nLockTime = 0 (immediately available)
3. New transaction output: 1 BTC to Alice herself
4. Miners will prioritize the new transaction (higher fee)
5. Bob's transaction is replaced, time-lock defeated
Result: nLockTime is not mandatory; it relies on the sender's honesty
Practical Needs¶
Many applications require mandatory time-locks:
- Inheritance Planning:
- Funds automatically transfer to heirs after the holder's death
-
The holder needs to ensure heirs cannot withdraw early
-
Escrow Services:
- Funds locked between buyer and seller, automatic refund after dispute resolution period
-
Requires guaranteed time certainty for the refund path
-
Cross-Chain Atomic Swaps:
- HTLCs (Hash Time-Locked Contracts) need reliable time-locks
-
Prevent one party from cheating within the time window
-
Two-Way Pegging:
- Fund locking mechanism between sidechains and the main chain
- Requires a mandatory waiting period
OP_CHECKLOCKTIMEVERIFY¶
Opcode Definition¶
OP_CHECKLOCKTIMEVERIFY (opcode: 0xb1)
Original name: OP_NOP2 (redefined NOP opcode)
Function: Verifies the relationship between the top stack element and the transaction's nLockTime
Execution Logic¶
Stack state during execution:
Top of stack: locktime (time-lock value)
...
Verification steps:
1. Check if stack is empty
2. Read top of stack element (without popping)
3. Verify locktime >= 0
4. Verify locktime type matches nLockTime (block height or timestamp)
5. Verify locktime <= nLockTime
6. Verify current input's nSequence != 0xFFFFFFFF
7. If all checks pass, continue execution; otherwise the script fails
Note: OP_CLTV does not pop the top element; typically followed by OP_DROP
Standard Usage Pattern¶
Script template:
<locktime> OP_CHECKLOCKTIMEVERIFY OP_DROP <normal spending conditions>
Example 1: Absolute time-lock
1514764800 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Explanation:
- 1514764800 = 2018-01-01 00:00:00 UTC
- Before this time, script verification fails
- After this time, normal P2PKH verification
Example 2: Block height lock
500000 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Explanation:
- Cannot be spent before block height 500,000
- After that, normal P2PKH verification
Technical Details¶
Time Type Determination¶
OP_CLTV supports two time representations:
Block Height (< 500,000,000):
Unix Timestamp (>= 500,000,000):
Type Matching Rules:
if (locktime < 500,000,000 && nLockTime < 500,000,000) {
// Both are block heights, can compare
} else if (locktime >= 500,000,000 && nLockTime >= 500,000,000) {
// Both are timestamps, can compare
} else {
// Type mismatch, script fails
}
nSequence Check¶
OP_CLTV requires the input's nSequence to not be 0xFFFFFFFF:
Reason: nSequence = 0xFFFFFFFF disables the transaction's nLockTime, rendering the time-lock ineffective.
Verification Algorithm¶
def op_checklocktimeverify(stack, tx_locktime, input_sequence):
"""Execute OP_CHECKLOCKTIMEVERIFY"""
# 1. Check stack
if len(stack) < 1:
return False
# 2. Read top of stack (without popping)
locktime = stack[-1]
# 3. Verify locktime >= 0
if locktime < 0:
return False
# 4. Verify nSequence
if input_sequence == 0xFFFFFFFF:
return False
# 5. Type matching check
if (locktime < 500000000) != (tx_locktime < 500000000):
return False # Type mismatch
# 6. Time comparison (uses MTP after BIP113)
if locktime > tx_locktime:
return False # Not yet unlocked
return True
Technical Advantages¶
1. Mandatory Time-Lock¶
An unbypassable time constraint: - Once funds are sent to an OP_CLTV script - Nobody can spend them before the specified time - Even the original sender cannot reverse it
2. Trustlessness¶
Eliminates dependency on third parties: - No need to trust an escrow agent - Time-lock is enforced by the blockchain - Completely transparent and verifiable
3. Composability¶
Can be combined with other script conditions: - Can be combined with multisignature - Can be combined with hash locks (HTLC) - Can create complex spending conditions
4. Backward Compatibility¶
Implemented as a soft fork: - Redefines OP_NOP2 - Old nodes treat it as a no-op - No chain split occurs
Practical Applications¶
1. Inheritance Planning¶
Time-locked inheritance arrangements:
Scenario:
- Holder: Alice
- Heir: Bob
- Time-lock: 1 year later
Script:
OP_IF
# Normal path: Alice uses
<Alice's pubKey> OP_CHECKSIG
OP_ELSE
# Backup path: Bob can use after 1 year
<1 year later timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP
<Bob's pubKey> OP_CHECKSIG
OP_ENDIF
Operation:
- Normal case: Alice can spend at any time (IF branch)
- Emergency case: After 1 year, Bob can inherit (ELSE branch)
- If Alice is inactive for a long time, Bob automatically inherits
2. Escrow Services¶
Time-limited fund escrow:
Scenario:
- Buyer: Alice
- Seller: Bob
- Escrow agent: Charlie
- Refund deadline: 30 days
Script:
OP_IF
# Normal transaction: 2-of-3 multisig
2 <Alice's pubKey> <Bob's pubKey> <Charlie's pubKey> 3 OP_CHECKMULTISIG
OP_ELSE
# Automatic refund to Alice after 30 days
<30 days later timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP
<Alice's pubKey> OP_CHECKSIG
OP_ENDIF
Flow:
1. Alice pays to the escrow address
2. If the transaction goes smoothly: Alice + Bob or Charlie signs to release to Bob
3. If there is a dispute: Charlie intervenes to arbitrate
4. If nobody acts within 30 days: Alice gets an automatic refund
3. HTLC (Hash Time-Locked Contracts)¶
The foundation of cross-chain atomic swaps:
Scenario: Alice (Bitcoin) <-> Bob (Litecoin)
Bitcoin-side HTLC:
OP_IF
# Bob reveals secret S to claim Bitcoin
OP_SHA256 <H(S)> OP_EQUALVERIFY
<Bob's pubKey> OP_CHECKSIG
OP_ELSE
# Alice can get a refund after 24 hours
<24 hours later timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP
<Alice's pubKey> OP_CHECKSIG
OP_ENDIF
Litecoin side is similar, but time-lock is 12 hours
Flow:
1. Alice creates a Bitcoin HTLC (24-hour lock)
2. Bob creates a Litecoin HTLC (12-hour lock)
3. Alice reveals secret S, claims Litecoin
4. Bob uses the same secret S, claims Bitcoin
5. If the swap fails midway, both parties get refunds after their respective time windows
4. Lightning Network¶
Channel timeout mechanism:
Lightning channel commitment transaction:
- Output 1: Counterparty can use immediately
- Output 2: Self-delayed (to prevent fraud)
Output 2 script:
OP_IF
# Counterparty reveals cheating evidence, penalty
<revocation_pubKey> OP_CHECKSIG
OP_ELSE
# After 144 blocks, self can reclaim
144 OP_CHECKLOCKTIMEVERIFY OP_DROP
<self_delayed_pubKey> OP_CHECKSIG
OP_ENDIF
Purpose:
- Gives the counterparty time to detect fraudulent behavior
- If an old state is published on-chain, it can be penalized
- If there is no fraud, normal reclaim after 144 blocks
5. Periodic Payments¶
Time-based fund release:
Scenario: A company pays employees in installments
Script (simplified example):
OP_IF
# Released after month 1
<month 1 timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP
<employee pubKey> OP_CHECKSIG
OP_ELSE
OP_IF
# Released after month 2
<month 2 timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP
<employee pubKey> OP_CHECKSIG
OP_ELSE
# Released after month 3
<month 3 timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP
<employee pubKey> OP_CHECKSIG
OP_ENDIF
OP_ENDIF
In practice, multiple UTXOs would be used rather than nested IFs
6. Two-Way Pegging (Sidechains)¶
Fund locking between main chain and sidechain:
Locking script on Bitcoin main chain:
<sidechain block confirmation time> OP_CHECKLOCKTIMEVERIFY OP_DROP
<multisig script>
Flow:
1. User locks Bitcoin on the main chain
2. Wait for confirmation period (e.g., 100 blocks)
3. Sidechain verifies main chain lock, issues sidechain tokens
4. User transacts on the sidechain
5. When returning, sidechain burns tokens, main chain releases funds
OP_CLTV ensures nobody can access the funds during the lock period
Relationship with Other BIPs¶
BIP113 (Median Time-Past)¶
BIP113 improved OP_CLTV's time verification:
BIP65 Original Rule:
After BIP113 Improvement:
if (locktime > MTP) {
return false; // Uses Median Time-Past
}
MTP = Median(timestamps of past 11 blocks)
Advantages: - Reduces miners' ability to manipulate time - Improves predictability of time-locks - Protects the security of OP_CLTV applications
BIP68 and BIP112 (Relative Time-Locks)¶
BIP65 provides absolute time-locks; BIP68/112 provide relative time-locks:
BIP65 (OP_CLTV): - Absolute time: "after 2025-01-01" - Absolute block: "after block 800,000"
BIP112 (OP_CSV): - Relative time: "30 days after UTXO creation" - Relative block: "144 blocks after UTXO confirmation"
Used Together:
Complex time-lock script:
<absolute time> OP_CHECKLOCKTIMEVERIFY OP_DROP
<relative blocks> OP_CHECKSEQUENCEVERIFY OP_DROP
<spending conditions>
Meaning:
- Must be after the absolute time
- AND must wait relative blocks after UTXO confirmation
- Both conditions must be met to spend
BIP341 (Taproot)¶
OP_CLTV in Taproot:
Taproot script tree can contain time-locked branches:
Script tree:
+-- Key path: Normal spending (no time-lock)
+-- Script path:
+-- Time-locked branch 1
+-- Time-locked branch 2
Example:
Internal public key: Holder's public key
Script branch 1: <1 year> OP_CLTV OP_DROP <Heir 1> OP_CHECKSIG
Script branch 2: <2 years> OP_CLTV OP_DROP <Heir 2> OP_CHECKSIG
Advantages:
- During normal use, only key path signature, completely private
- In inheritance scenarios, only the relevant script branch is revealed
- Unused time-locked branches remain private
Activation and Deployment¶
Soft Fork Activation¶
BIP65 was activated in December 2015:
- Activation method: IsSuperMajority (75% miner support)
- Version number: Block version 4
- Lock-in block: 388,381 (November 25, 2015)
- Activation block: 388,381 (version 4 blocks reached 75%)
- Enforcement: 419,328 (after 95% threshold)
Activation Timeline¶
- October 2015: BIP65 code merged into Bitcoin Core 0.11.2
- November 2015: Miners began signaling support (version 4 blocks)
- December 8, 2015: Reached 75% threshold, enforcement began
- First use: Transactions using OP_CLTV appeared immediately after activation
Activation Controversy¶
BIP66 Conflict Incident: - In July 2015, BIP66 (strict DER signatures) was activated - Some miners did not upgrade and mined invalid blocks - This resulted in a temporary fork of 6 blocks - Served as a warning for BIP65 activation
BIP65 Activation Lessons: - Stricter upgrade notifications - Longer preparation periods - Clearer version signaling - Ultimately activated smoothly without fork incidents
Compatibility¶
Backward Compatible (soft fork): - Old nodes treat OP_CLTV (0xb1) as OP_NOP2 - Old nodes accept transactions containing OP_CLTV - Old nodes consider these transactions always valid
Forward Compatible: - New nodes fully verify OP_CLTV rules - Reject transactions that violate time-locks - Maintain consensus consistency
Security Considerations¶
1. Time Precision¶
Precision limitations of OP_CLTV:
Block Height Mode: - Precision: ~10 minutes (1 block) - Uncertainty: ± 30 minutes (network fluctuations)
Timestamp Mode: - Precision: ~10 minutes (with BIP113 MTP) - Note: Actual time may differ from expectations
Recommendations: - Allow ample time buffer (at least several hours or blocks) - Do not use for applications requiring second-level precision - Block height is more reliable for critical time points
2. Key Management¶
Key risks for long-term locks:
Problem: - Inheritance planning may lock for years or decades - Heir's keys may be lost or stolen - Quantum computing may threaten ECDSA in the future
Recommendations: - Use multisignature for redundancy - Regularly test backup and recovery procedures - Consider staged time-locks (multiple time points) - Maintain emergency access paths
3. nSequence Setting¶
OP_CLTV requires nSequence != 0xFFFFFFFF:
Correct Setting:
# When creating an OP_CLTV transaction
tx.vin[0].nSequence = 0xFFFFFFFE # Enables nLockTime
# Or
tx.vin[0].nSequence = 0 # Also works
# Wrong!
tx.vin[0].nSequence = 0xFFFFFFFF # Disables nLockTime, OP_CLTV fails
4. Time Type Matching¶
The locktime in the script must match the transaction nLockTime type:
Incorrect Example:
Script: 500000 OP_CHECKLOCKTIMEVERIFY OP_DROP ...
Transaction: nLockTime = 1609459200 (timestamp)
Result: Type mismatch, verification fails
Correct Example:
Script: 500000 OP_CHECKLOCKTIMEVERIFY OP_DROP ...
Transaction: nLockTime = 600000 (block height)
Or
Script: 1609459200 OP_CHECKLOCKTIMEVERIFY OP_DROP ...
Transaction: nLockTime = 1709459200 (later timestamp)
5. Script Design¶
Considerations when designing OP_CLTV scripts:
Necessity of OP_DROP:
# Correct: OP_CLTV followed by OP_DROP
<locktime> OP_CHECKLOCKTIMEVERIFY OP_DROP <pubKey> OP_CHECKSIG
# Incorrect: Forgetting OP_DROP
<locktime> OP_CHECKLOCKTIMEVERIFY <pubKey> OP_CHECKSIG
# Result: Top of stack is locktime, OP_CHECKSIG will fail
Multi-Path Scripts:
# Recommended: Use OP_IF/OP_ELSE branches
OP_IF
<normal path>
OP_ELSE
<locktime> OP_CLTV OP_DROP <backup path>
OP_ENDIF
# Avoid: All paths with different time-locks
# This makes scripts complex and difficult to test
Comparison: Before and After BIP65¶
| Feature | Before BIP65 | After BIP65 |
|---|---|---|
| Time-Lock Method | nLockTime (weak) | OP_CHECKLOCKTIMEVERIFY (strong) |
| Can Be Bypassed | Yes (sender can replace) | No (script-enforced) |
| Trust Requirement | Must trust the sender | Trust no one |
| Inheritance Planning | Unreliable | Reliably achievable |
| HTLC | Unsafe | Safe and usable |
| Lightning Network | Not possible | Became possible |
| Escrow Services | Requires third party | Can be trustless |
| Script Flexibility | Limited | Highly flexible |
Practical Impact¶
Impact on Users¶
New Features Available: - Reliable inheritance planning tools - Trustless escrow services - Time-locked savings accounts
Enhanced Security: - Prevents early withdrawal - Protects long-term investments - Strengthens fund security
Impact on Developers¶
New Application Scenarios: - Lightning Network became possible - Cross-chain atomic swaps became feasible - Complex smart contracts became implementable
Technical Foundation: - OP_CLTV became a standard tool - Time-locking became a basic capability - Paved the way for subsequent BIPs (68, 112, 341)
Impact on the Ecosystem¶
Layer 2 Development: - Lightning Network depends on OP_CLTV - Sidechain two-way pegging became possible - State channels can operate securely
Smart Contract Capabilities: - Bitcoin scripting capabilities significantly enhanced - Approaches the level of early Ethereum smart contracts - Extends functionality while maintaining Bitcoin's simplicity
Future Development¶
Combination with Taproot¶
Taproot enhances OP_CLTV's privacy: - Time-lock scripts can be hidden in the script tree - During normal use, time-lock conditions are never exposed - Only revealed when the time-lock path is triggered
More Complex Time Contracts¶
Advanced applications based on OP_CLTV: - Multi-stage release (installment payments) - Conditional time-locks (event trigger + time) - Time-decaying voting rights - Time-based auction mechanisms
Cross-Chain Standardization¶
OP_CLTV's influence on other blockchains: - Litecoin, Dogecoin, and others have all implemented OP_CLTV - Cross-chain HTLCs have a unified standard - Atomic swap protocol standardization
Summary¶
BIP65, through the introduction of OP_CHECKLOCKTIMEVERIFY, brought mandatory time-lock capability to Bitcoin -- an important extension of protocol functionality:
Core Contributions: - Mandatory: Time-locks are unbypassable, guaranteed by the consensus layer - Trustless: No third-party dependency, pure cryptographic guarantee - Flexible: Supports both block height and timestamp modes - Compatible: Soft fork implementation, no chain split risk
Practical Value: - Made Layer 2 solutions like the Lightning Network possible - Provided the foundation for HTLCs and atomic swaps - Supports practical applications such as inheritance planning and escrow - Significantly enhanced Bitcoin scripting capabilities
Historical Significance: - Bitcoin's first time-lock opcode - Proved that Bitcoin can safely extend its functionality - Laid the groundwork for subsequent BIPs (68, 112, 341) - Demonstrated the effectiveness of soft forks as an upgrade mechanism
BIP65 introduced only a simple opcode, but its impact has been far-reaching. It not only fixed the fundamental flaw of nLockTime but also opened entirely new application possibilities for Bitcoin. From the Lightning Network to cross-chain swaps, from inheritance planning to escrow services, OP_CHECKLOCKTIMEVERIFY has become an indispensable foundational component of Bitcoin smart contracts.