Allow spending only after 144 blocks (≈1 day) from UTXO confirmation
6. Relative Timelocks Using CSV in Real Scripts
Why Relative Timelocks Matter
Relative timelocks are the backbone of state channels and many advanced Bitcoin protocols. The critical difference from absolute timelocks is that they start counting from the moment a transaction is confirmed, not from a predetermined date. This allows protocols to be constructed without knowing in advance when they'll be activated.
Pattern 1: Basic Relative-Delayed Payment
# Allow spending only after 144 blocks (≈1 day) from UTXO confirmation
scriptPubKey (P2WSH witnessScript):
144 OP_CHECKSEQUENCEVERIFY OP_DROP
OP_DUP OP_HASH160 <RecipientPubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
# Spending witness:
<signature>
<pubKey>
<witnessScript>
# Spending transaction must set:
nVersion = 2
input.nSequence = 0x00000090 (144 in hex)
Pattern 2: Two-Path Script with Relative Timeout
This is fundamental to many Layer 2 protocols:
# Path 1: Bob spends immediately with his key (OP_IF branch)
# Path 2: Alice reclaims after 1008 blocks if Bob doesn't act
OP_IF
<BobPubKey> OP_CHECKSIG
OP_ELSE
1008 OP_CHECKSEQUENCEVERIFY OP_DROP
<AlicePubKey> OP_CHECKSIG
OP_ENDIF
# Bob takes the OP_IF path:
scriptSig/witness: <BobSignature> 1 <script>
# Alice takes the OP_ELSE path (after 1008 blocks):
scriptSig/witness: <AliceSignature> 0 <script>
+ nSequence must be >= 1008
Pattern 3: Revocable Payment Channel CSV
This is close to what Lightning actually uses:
# Output can be spent by:
# (a) Recipient immediately with both keys (cooperative close)
# (b) Sender after 2016 blocks (timeout recovery)
OP_IF
# Cooperative spend: requires both parties
2 <SenderPubKey> <RecipientPubKey> 2 OP_CHECKMULTISIG
OP_ELSE
# Timeout recovery: sender alone after 2016 blocks
2016 OP_CHECKSEQUENCEVERIFY OP_DROP
<SenderPubKey> OP_CHECKSIG
OP_ENDIF
Pattern 4: Time-Based CSV (Using Seconds)
# To create a CSV that locks for approximately 1 week using time:
WEEK_IN_SECONDS = 7 * 24 * 60 * 60 # 604800 seconds
CSV_TYPE_FLAG = 1 << 22
units = (WEEK_IN_SECONDS + 511) // 512 # = 1182 units
csv_value = CSV_TYPE_FLAG | units # = 0x0040049E
# This goes into the script as:
# <0x0040049E> OP_CHECKSEQUENCEVERIFY OP_DROP ...
# And nSequence must be >= 0x0040049E with the type bit set
print(hex(csv_value)) # 0x40049e
Pattern 5: Stacked CSV (Chained Relative Locks)
You can create a chain of UTXOs where each must be spent with a relative delay from the previous, effectively creating a timed unlock schedule.
# UTXO A: spendable by TX1 after 144 blocks
# TX1 creates UTXO B: spendable by TX2 after 144 blocks
# TX2 creates UTXO C: immediately spendable by recipient
# UTXO A locking script:
144 OP_CSV OP_DROP <RecipientPubKey> OP_CHECKSIG
# TX1 (spending A after 144 blocks) creates UTXO B with:
144 OP_CSV OP_DROP <RecipientPubKey> OP_CHECKSIG
# Total delay from UTXO A creation: ~288 blocks (~2 days)
Real-World Considerations
Fee Bumping with CSV: When using CSV, you cannot easily RBF (Replace-by-Fee) the spending transaction if it gets stuck in the mempool, because changing the fee would normally require a different transaction structure. CPFP (Child Pays for Parent) is the preferred fee-bumping strategy for CSV-encumbered transactions.
UTXO Confirmation Depth: The CSV clock doesn't start when the transaction is broadcast — it starts when the UTXO is confirmed. If you broadcast a funding transaction and it takes 10 blocks to confirm, your 144-block CSV timeout starts from block 10, not block 0.
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: