TeachMeBitcoin

Allow spending only after 144 blocks (≈1 day) from UTXO confirmation

From TeachMeBitcoin, the free encyclopedia Reading time: 3 min

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.

☕ Help support TeachMeBitcoin

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:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!