Timelocks
Timelocks are restrictions on transactions or outputs that only allow spending after a point in time. Timelocks extend Bitcoin scripting in the dimension of time.
Transaction Locktime
Transaction locktime is a transaction-level setting (a field in the transaction data structure) that defines the earliest time that a transaction is valid and can be relayed on the network or added to the blockchain.
Locktime is also known as nLocktime from the variable name used in the Bitcoin Core codebase.
If nLocktime
is nonzero and below 500 million, it is interpreted as a block height, meaning the transaction is not valid and is not relayed or included in the blockchain prior to the specified block height. If it is greater than or equal to 500 million, it is interpreted as a Unix Epoch timestamp (seconds since Jan-1-1970) and the transaction is not valid prior to the specified time
NOTE: nLocktime has the limitation that while it makes it possible to spend some outputs in the future, it does not make it impossible to spend them until that time
Check Lock Time Verify (CLTV)
CLTV is a per-output timelock, rather than a per-transaction timelock as is the case with nLocktime. In simple terms, by adding the CLTV opcode in the redeem script of an output it restricts the output, so that it can only be spent after the specified time has elapsed.
NOTE: While nLocktime is a transaction-level timelock, CLTV is an output-based timelock.
CLTV doesn’t replace nLocktime, but rather restricts specific UTXO such that they can only be spent in a future transaction with nLocktime set to a greater or equal value.
To lock an output to a time, say 3 months from now, the transaction would be a P2SH transaction with a redeem script like this: <now + 3 months> CHECKLOCKTIMEVERIFY DROP DUP HASH160 <Payee Public Key Hash> EQUALVERIFY CHECKSIG
NOTE: DROP
pops from the stack
Relative Timelocks
nLocktime
and CLTV
are both absolute timelocks in that they specify an absolute point in time.
Relative timelocks are useful because they allow a chain of two or more interdependent transactions to be held off chain, while imposing a time constraint on one transaction that is dependent on the elapsed time from the confirmation of a previous transaction. This functionality is especially useful in bidirectional state channels and Lightning Networks.
Relative timelocks, like absolute timelocks, are implemented with both a transaction-level feature and a script-level opcode. The transaction-level relative timelock is implemented as a consensus rule on the value of nSequence
, a transaction field that is set in every transaction input. Script-level relative timelocks are implemented with the CHECKSEQUENCEVERIFY
(CSV) opcode.
nSequence
Since the activation of BIP-68, new consensus rules apply for any transaction containing an input whose nSequence
value is less than 231 (bit 1<<31 is not set). Programmatically, that means that if the most significant bit (bit 1<<31) is not set, it is a flag that means “relative locktime.” Otherwise (bit 1<<31 set), the nSequence
value is reserved for other uses such as enabling CHECKLOCKTIMEVERIFY, nLocktime, Opt-In-Replace-By-Fee, and other future developments.
Transaction inputs with nSequence
values less than 231 are interpreted as having a relative timelock. Such a transaction is only valid once the input has aged by the relative timelock amount. For example, a transaction with one input with an nSequence
relative timelock of 30 blocks is only valid when at least 30 blocks have elapsed from the time the UTXO referenced in the input was mined. Since nSequence
is a per-input field, a transaction may contain any number of timelocked inputs, all of which must have sufficiently aged for the transaction to be valid.
The nSequence
value is specified in either blocks or seconds, but in a slightly different format than we saw used in nLocktime. A type-flag is used to differentiate between values counting blocks and values counting time in seconds. The type-flag is set in the 23rd least-significant bit (i.e., value 1<<22). If the type-flag is set, then the nSequence
value is interpreted as a multiple of 512 seconds. If the type-flag is not set, the nSequence value is interpreted as a number of blocks. When interpreting nSequence
as a relative timelock, only the 16 least significant bits are considered.
CSV
The CSV
opcode when evaluated in an UTXO’s redeem script allows spending only in a transaction whose input nSequence
value is greater than or equal to the CSV
parameter. Essentially, this restricts spending the UTXO until a certain number of blocks or seconds have elapsed relative to the time the UTXO was mined.
As with CLTV, the value in CSV must match the format in the corresponding nSequence value. If CSV is specified in terms of blocks, then so must nSequence. If CSV is specified in terms of seconds, then so must nSequence.