Every transaction we have studied so far answers the question who can spend. Signatures prove ownership; scripts encode spending conditions; multisig requires agreement among parties. But none of these mechanisms answers an equally important question: when can the funds be spent?
Bitcoin's timelock system answers this question through four complementary mechanisms, organized along two axes:
Absolute timelocks say "not before block \(X\)" or "not before time \(T\)." Relative timelocks say "not until \(n\) blocks (or \(t\) seconds) after the input was confirmed." Transaction-level locks are enforced by nodes checking header fields. Script-level locks are enforced by the Script interpreter during execution.
This chapter examines each mechanism in detail, building from the simplest (nLockTime, present since the Genesis block) to the most sophisticated (OP_CSV, which enables Lightning Network payment channels).
Every transaction has a 4-byte nLockTime field—the very last field in the transaction, in both legacy and SegWit serialization. We have encountered it in every specimen, always as 00 00 00 00—except in Chapter 12, where our Taproot specimen had:
ff d3 0a 00_nLockTime = 709,631 (little-endian)
This meant the transaction could not be included in any block with height \(<709,631\).
The nLockTime field has a dual interpretation based on its value:
| Value | Interpretation | Meaning |
|---|---|---|
| \(0\) | Disabled | Transaction valid immediately |
| \(1\)–\(499,999,999\) | Block height | Not valid until block \(\geq\) nLockTime |
| \(\geq 500,000,000\) | UNIX timestamp | Not valid until time \(\geq\) nLockTime |
The threshold 500,000,000 corresponds to November 5, 1985—well before Bitcoin's creation, ensuring no ambiguity between heights and timestamps for any real transaction.
When a node receives a transaction with \(\texttt{nLockTime} > 0\):
nLockTime alone provides weak guarantees. A transaction with \(\texttt{nLockTime} = 800,000\) cannot be mined before block 800,000—but nothing prevents the sender from creating a second transaction spending the same inputs with \(\texttt{nLockTime} = 0\), broadcasting it immediately, and invalidating the time-locked version. nLockTime constrains when a transaction can be mined, not when the underlying funds can be spent. For enforceable timelocks, you need script-level locks (CLTV or CSV).
There is a critical exception: nLockTime is only enforced if at least one input has \(\texttt{nSequence} < \texttt{0xFFFFFFFF}\). If every input's sequence number is 0xFFFFFFFF (the maximum), nLockTime is ignored entirely and the transaction is valid at any time.
This was Satoshi's original design: nSequence was intended for transaction "replacement"—parties could update a transaction by incrementing the sequence number, with the highest-sequence version being final. Once all sequences reached the maximum, no more updates were possible, and nLockTime became irrelevant.
In practice, this replacement mechanism was never used (it was a denial-of-service vector). But the nSequence/nLockTime interaction remains in consensus and has been repurposed by BIP 68 (relative timelocks) and BIP 125 (Replace-by-Fee).
Modern wallets set nLockTime to the current block height as an anti-fee-sniping measure. Fee sniping is a theoretical attack where a miner re-mines a previous block to steal its fees. By setting nLockTime to the current height, the transaction cannot be included in any earlier block—making fee sniping slightly harder.
Our Chapter 12 specimen's \(\texttt{nLockTime} = 709,631\) is exactly this: the transaction was created when the chain tip was block 709,631, ensuring it could only be mined in block 709,632 or later. The corresponding \(\texttt{nSequence} = \texttt{0xFFFFFFFD}\) enables both nLockTime enforcement and RBF signaling.
nLockTime constrains the transaction. But what if you want to constrain the output—ensuring that no transaction, regardless of who creates it, can spend the funds before a certain time? This requires a script-level lock.
BIP 65† introduced OP_CHECKLOCKTIMEVERIFY (CLTV, opcode 0xb1)—a Script opcode that verifies the spending transaction's nLockTime against a value on the stack.
A CLTV-locked output uses this script:
<expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP <pubkey> OP_CHECKSIG
For example, to lock funds until block 900,000:
03 a0 bb 0d OP_CLTV OP_DROP <pubkey> OP_CHECKSIG
where 03 a0 bb 0d pushes the 3-byte little-endian encoding of 900,000 (\(= \texttt{0x0DBBA0}\)).
When the Script interpreter encounters OP_CHECKLOCKTIMEVERIFY:
0xFFFFFFFF (ensuring nLockTime is actually enforced).The OP_DROP after CLTV removes the lock-time value from the stack (CLTV doesn't pop it), leaving the stack clean for OP_CHECKSIG.
CLTV solves nLockTime's fundamental weakness. Without CLTV, the sender can always bypass nLockTime by creating a competing transaction with \(\texttt{nLockTime} = 0\). With CLTV, the lock is embedded in the output script—the funds literally cannot be spent until the time has passed, regardless of who creates the spending transaction. The lock is on the coins, not the transaction.
The 4-byte nSequence field on each input is the most overloaded field in Bitcoin. It serves three distinct purposes depending on its value:
| Value | Meaning | BIP |
|---|---|---|
0xFFFFFFFF | Final (disables nLockTime) | Original |
0xFFFFFFFE | Final (nLockTime enabled, no RBF) | — |
\(<\) 0xFFFFFFFE, bit 31 set | RBF signal only | BIP 125 |
\(<\) 0xFFFFFFFE, bit 31 clear | Relative timelock + RBF | BIP 68 |
When bit 31 is clear (0), the nSequence value encodes a relative timelock per BIP 68†:
| nSequence | Encoding | Meaning |
|---|---|---|
0x00000001 | 1 block, block-based | Not before 1 confirmation |
0x00000090 | 144 blocks, block-based | Not before 1 day |
0x004000A9 | 169 units \(\times\) 512s, time-based | Not before 24 hours |
0xFFFFFFFF | BIP 68 disabled | No relative timelock |
0xFFFFFFFD | BIP 68 disabled (bit 31 set) | RBF signal only |
The relative timelock is measured from the block in which the referenced output was confirmed. If the input spends an output confirmed in block 800,000, and nSequence encodes 144 blocks, the spending transaction cannot be mined before block 800,144.
Just as CLTV enforces nLockTime at the script level, OP_CHECKSEQUENCEVERIFY (CSV, opcode 0xb2) enforces BIP 68 relative timelocks at the script level.
BIP 112† allows a script to require that the spending input's nSequence meets a minimum relative delay.
<delay> OP_CHECKSEQUENCEVERIFY OP_DROP <pubkey> OP_CHECKSIG
For example, to require 144 confirmations (\(\approx\)1 day):
02 90 00 OP_CSV OP_DROP <pubkey> OP_CHECKSIG
where 02 90 00 pushes the 2-byte little-endian encoding of 144 (\(= \texttt{0x0090}\)).
When the Script interpreter encounters OP_CHECKSEQUENCEVERIFY:
CSV is the critical building block for the Lightning Network. In a Lightning commitment transaction, the to_local output (the channel partner's own funds) is locked with a CSV delay—typically 144 blocks (1 day) to 2,016 blocks (2 weeks). This delay gives the counterparty time to detect a revoked commitment and broadcast a penalty transaction. Without CSV, Lightning's security model would not work.
The distinction between absolute and relative timelocks is fundamental:
| CLTV (Absolute) | CSV (Relative) | |
|---|---|---|
| Question | "After what block/time?" | "How long after confirmation?" |
| Reference | Global (block height or UTC) | Local (confirmation of the input) |
| Script opcode | OP_CHECKLOCKTIMEVERIFY (0xb1) | OP_CHECKSEQUENCEVERIFY (0xb2) |
| Tx field | nLockTime | nSequence |
| Activation | Block 388,381 (Dec 2015) | Block 419,328 (Jul 2016) |
| BIP | 65 | 68, 112, 113 |
| Use case | HODL, escrow timeout | Lightning, vault recovery |
CLTV answers: "These coins cannot be spent before January 1, 2030." CSV answers: "These coins cannot be spent until 144 blocks after they were confirmed." Both can appear in the same script—enabling complex conditions like "Alice can spend after 1,000 blocks from confirmation, OR Bob can spend after January 2030."
The most powerful timelock pattern combines hash locks with time locks, creating a Hash Time-Locked Contract (HTLC):
OP_IF
OP_HASH160 <hash> OP_EQUALVERIFY
OP_ELSE
OP_ENDIF
This script has two spending paths:
HTLCs are the atomic building block of the Lightning Network (Chapter 18). They enable trustless multi-hop payments: each hop in a Lightning payment is secured by an HTLC that ensures either the payment completes across all hops, or every participant gets refunded.
Timelocks are about when funds can move. Chapter 17 explores how transactions compete: Replace-by-Fee (RBF) and Child-Pays-for-Parent (CPFP)—the tools for navigating Bitcoin's fee market. Both rely on nSequence, the same field we studied here.
*Exercises
OP_DROP always follow OP_CHECKLOCKTIMEVERIFY in practice?to_local output uses CSV with a 144-block delay. Explain why this delay is necessary for security. What attack does it prevent?OP_IF/OP_ELSE with CLTV.0xFFFFFFFE as a signal. How does RBF signaling interact with BIP 68 relative timelocks? Can a transaction signal RBF and enforce a relative timelock simultaneously?*Solutions
L1. nLockTime values \(< 500,000,000\) are interpreted as block heights: the transaction is invalid before that block. Values \(\geq 500,000,000\) are interpreted as UNIX timestamps: the transaction is invalid before that time. The threshold is \(500,000,000\) (corresponding to November 5, 1985—well before Bitcoin's creation).
L2. If every input has \(\texttt{nSequence} = \texttt{0xFFFFFFFF}\), nLockTime is disabled: the transaction is valid immediately regardless of the nLockTime value. This is the original behavior from Satoshi's design.
L3. OP_CHECKLOCKTIMEVERIFY (CLTV) = 0xb1. OP_CHECKSEQUENCEVERIFY (CSV) = 0xb2.
L4. Because CLTV does not pop the lock-time value from the stack—it only reads it. The value would remain on the stack and interfere with subsequent opcodes (like OP_CHECKSIG). OP_DROP removes it, leaving the stack clean.
L5. Bit 22 is the type flag: if clear (0), the value in bits 0–15 represents blocks; if set (1), the value represents time in 512-second units.
H1. \(900,000 = \texttt{0x0DBBA0}\). In 4-byte little-endian: a0 bb 0d 00.
H2. \(1,008\) blocks, block-based (bit 22 = 0): nSequence = \(1,008 = \texttt{0x03F0}\). Full 4-byte value: 0x000003F0. In little-endian bytes: f0 03 00 00. Bit 31 must be 0 (BIP 68 enabled).
H3. 48 hours = \(48 \times 3,600 = 172,800\) seconds. Each unit = 512 seconds: \(172,800 / 512 = 337.5\), round to 338 units. Time-based: set bit 22. nSequence = \((1 \ll 22) \,|\, 338 = \texttt{0x00400152}\). Verify: \(338 \times 512 = 173,056\) seconds \(= 48.07\) hours.
H4. \(\texttt{nSequence} = \texttt{0xFFFFFFFD}\):
Summary: nLockTime active, RBF active, no relative timelock.
P1. Suppose Alice creates a transaction paying Bob with \(\texttt{nLockTime} = 850,000\) (block 850,000 is one month away). Before block 850,000, Alice can create a new transaction spending the same inputs with \(\texttt{nLockTime} = 0\), broadcast it, and get it mined immediately. Bob's time-locked transaction becomes invalid (double-spend).
CLTV prevents this by embedding the lock in the output script. If Alice locks funds in a CLTV output, any spending transaction must have \(\texttt{nLockTime} \geq 850,000\). Alice cannot create a bypassing transaction because the script itself rejects it. The lock is on the coins, not the transaction.
P2. CLTV compares its stack value against nLockTime, and both must use the same type (heights or timestamps). If the script specifies block 900,000 (a height) but the transaction sets nLockTime to a UNIX timestamp, the comparison is meaningless—900,000 as a timestamp is January 11, 1970, which is always in the past. A malicious spender could bypass the intended lock by using the wrong type. BIP 65 prevents this: if the types don't match, the script fails immediately.
P3. In Lightning, each commitment transaction gives one party their funds immediately (the to_remote output) and the other party their funds after a CSV delay (the to_local output). The delay exists so that if a party broadcasts a revoked commitment (an old state that has been superseded), the counterparty has time to detect it and broadcast a penalty transaction that claims all funds. Without the delay, the cheating party could broadcast an old commitment and immediately spend their output, leaving no window for the penalty. The 144-block (1 day) delay is a security parameter: it must be long enough for the honest party's watchtower to detect the breach and respond.
C1. The 5th halving occurs at block 1,050,000. The CLTV locking script:
03 90 05 10 OP_CLTV OP_DROP <pubkey> OP_CHECKSIG
where 03 90 05 10 pushes the 3-byte little-endian encoding of 1,050,000 (\(= \texttt{0x100590}\)). The spending transaction must have \(\texttt{nLockTime} \geq 1,050,000\) and at least one input with \(\texttt{nSequence} < \texttt{0xFFFFFFFF}\) (to enable nLockTime enforcement).
C2. The two-path escrow script:
OP_IF
OP_2
OP_ELSE
<900000> OP_CHECKLOCKTIMEVERIFY OP_DROP
OP_ENDIF
Path 1 (cooperative): Alice and Bob both sign, supplying OP_TRUE to take the OP_IF branch. No timelock. Path 2 (timeout): After block 900,000, Alice provides her signature with OP_FALSE to take the OP_ELSE branch. The spending transaction must have \(\texttt{nLockTime} \geq 900,000\) and at least one input with \(\texttt{nSequence} < \texttt{0xFFFFFFFF}\). Note: CLTV uses absolute heights. For a relative delay (e.g., "30 days after the output is created"), use CSV instead.
B1. Yes, a transaction can signal RBF and enforce a BIP 68 relative timelock simultaneously. Any nSequence with bit 31 clear and value \(<\) 0xFFFFFFFE satisfies both: bit 31 = 0 activates BIP 68, and the sub-maximum value signals RBF per BIP 125. For example, \(\texttt{nSequence} = \texttt{0x00000090}\) (144-block relative lock) also signals RBF because \(\texttt{0x00000090} < \texttt{0xFFFFFFFE}\).
B2. In a Lightning multi-hop payment, each intermediate node creates an HTLC with two paths: (1) the recipient reveals a hash preimage to claim the funds (the "success" path), or (2) the sender reclaims the funds after a CLTV timeout (the "refund" path). The timeouts decrease along the route: if the payment is A B C, the HTLC from A to B might timeout at block \(n+20\), while B to C times out at block \(n+10\). This ensures that if C claims the preimage from B, B has time to claim from A before A's timeout. The hash preimage propagates backward (C B A), and the timelocks ensure every hop can claim or refund. The atomicity guarantee: either all hops complete (preimage revealed), or all hops refund (timeouts expire).