MASTERING-BITCOIN ยท Unit 7 ยท Video 5
| Mechanism | Scope | What It Restricts | Enforced By |
|---|---|---|---|
nLockTime |
Transaction field | When the transaction can be mined | Miners (per-tx) |
OP_CLTV |
Output script (per UTXO) | Spending the UTXO before an absolute height/time | Full consensus |
OP_CSV |
Output script (per UTXO) | Spending the UTXO before N blocks/seconds since confirmation | Full consensus |
CLTV handshake: spending tx must have nLockTime โฅ CLTV value AND input sequence < 0xFFFFFFFF.
Block-time approximation: ~10 minutes/block, so 3 months โ 12,960 blocks.
nLockTime Alone FailsAlice creates a transaction Tx1 paying Bob with an nLockTime set 3 months in the future. Because the lock lives on the transaction, not on the coins, Alice can race a second transaction Tx2 that spends the same input back to herself today.
Adjust the slider to see what happens at different points in time.
โ interactive visualization โ coming to this page format soon
Notice: Whenever Alice broadcasts Tx2 before Tx1's lock expires, Tx2 confirms first and consumes the input. Tx1 becomes permanently invalid โ its nLockTime only delayed broadcast, not betrayal. The deadline must be bound to the coin, not the transaction wrapping it.
Both opcodes encumber a UTXO, but they answer different questions:
The key difference: CSV's countdown only starts when the parent transaction confirms. Adjust when the parent confirms and watch how the unlock points move.
โ interactive visualization โ coming to this page format soon
Reflect: Move the parent-confirmation slider. The CLTV unlock stays anchored at block 832,960 regardless of when the parent confirms โ it's a wall-clock deadline. The CSV unlock slides with the parent, always N blocks later. This is exactly why Lightning channels use CSV: the safety window must begin when the channel state actually lands on-chain, not at some predetermined calendar date.
OP_DROPWalk through what happens on the script stack as Bob's redeem script executes:
<BobPubKey> OP_CHECKSIGVERIFY <832960> OP_CHECKLOCKTIMEVERIFY OP_DROP
Use the slider to step through each opcode and watch the stack.
โ interactive visualization โ coming to this page format soon
Notice: At step 4, OP_CHECKLOCKTIMEVERIFY enforces the deadline but leaves 832960 on the stack. This is because CLTV was grafted onto a previously-unused NOP opcode for soft-fork compatibility โ old nodes treat it as a no-op, so it cannot mutate the stack. OP_DROP is not part of the timelock logic; it's just cleanup.
Question 1
Alice signs a transaction Tx1 paying Bob 1 BTC, with nLockTime set to a block height 3 months in the future. She gives Tx1 to Bob.
Why is Bob not actually paid by this alone?
โ Correct! The lock is on the wrapper, not the coins.
โ Not quite. The transaction is valid and the fee/signature aren't the issue. Think about what nLockTime restricts and what it doesn't.
Solution:
nLockTime lives on the transaction, not on the coins. Miners will refuse to include Tx1 until the locktime is reached โ but nothing stops Alice from broadcasting a second transaction Tx2 today that spends the same input UTXO back to herself. Once Tx2 confirms, the input no longer exists, and Tx1 becomes permanently invalid.
The fix (CLTV/CSV) moves the lock into the output script of the UTXO itself, so consensus rejects any spend that doesn't honor the deadline.
Question 2
Which of the following correctly describes a key difference between OP_CHECKLOCKTIMEVERIFY (CLTV) and OP_CHECKSEQUENCEVERIFY (CSV)?
โ Correct! Absolute deadline vs. relative aging.
โ Not quite. Both are full-consensus rules and both are NOP-compatible (don't consume their argument). The real difference is what kind of clock they read.
Solution:
Both are enforced by full consensus (not just miners), and both are NOP-style opcodes that leave their argument on the stack โ so the other options reverse the truth or invent distinctions that don't exist. Lightning relies primarily on CSV (relative aging windows for penalty); CLTV is widely used in HTLCs and escrow.
Question 3
True or False: When OP_CHECKLOCKTIMEVERIFY succeeds, it consumes (pops) its locktime argument from the stack โ that's why scripts using CLTV need OP_DROP afterward to handle the leftover stack item.
โ
Correct! CLTV is NOP-compatible โ it leaves the stack unchanged, and OP_DROP cleans up afterward.
โ Not quite. Re-read the statement carefully โ it gets the cause-and-effect backwards. If CLTV consumed its argument, why would you need OP_DROP?
Solution: False.
The statement contradicts itself. CLTV does not consume its argument โ it leaves the locktime value on the stack. That is precisely why OP_DROP is needed afterward.
The reason: CLTV was added via soft fork by repurposing a previously-unused NOP (no-operation) opcode. Old nodes that don't know about CLTV must still be able to validate the script, and they treat the opcode as a no-op โ meaning it cannot alter the stack. So CLTV-aware nodes also leave the stack unchanged (other than the verification check), and OP_DROP is just stack hygiene to clean up the leftover value.
Question 4
Bob writes a redeem script with <832960> OP_CHECKLOCKTIMEVERIFY OP_DROP .... He later tries to spend this UTXO with a transaction whose nLockTime = 832960 and whose input sequence = 0xFFFFFFFF (the maximum value).
What happens?
โ Correct! A maxed-out sequence disables nLockTime enforcement, so CLTV refuses to honor the spend.
โ Not quite. The nLockTime check passes, and 832,960 is well below the timestamp threshold (~500 million). There's a second requirement CLTV places on the input itself.
Solution:
CLTV imposes two requirements on the spending transaction:
nLockTime must be โฅ the CLTV value (here 832,960). โ satisfied.sequence field must be strictly less than 0xFFFFFFFF. โ violated.Why the sequence rule? Setting sequence = 0xFFFFFFFF is the historical signal that disables nLockTime enforcement on that input. If CLTV allowed that, the spender could effectively bypass the timelock. So CLTV explicitly rejects spends where the sequence is at maximum.
(For reference: 832,960 is below the threshold (~500 million) where Bitcoin switches from interpreting the value as a block height to a Unix timestamp, so the format is unambiguously a block height.)
Solved: 0 / 4