13 - nLocktime

The nLocktime value is used for creating payment channels. If a transaction has any inputs with non-final nSequence values (e.g. nSequence < 0xffffffff) and an nLocktime in the future, it is considered a payment channel, and cannot be put into a block until either the nLocktime expires, or the transaction is updated to have all final inputs.

This can be useful if an output must be created that can't be spent before a particular time. The nSequence can be checked to be non-final, and the nLocktime can be checked to be later than a pre-set time/date value.

Example: Check channel status

Stack
Script
Description

<nSequence><r_tx_preimg>

...

nSequence is left on the stack. R_tx_preimg has had version, hash_prevouts, hash_nSequence, hash_outpoints, script, value, nSequence and hash_outputs removed

<nSequence> <r_tx_preimg>

OP_4

nLocktime is 4 bytes

<nSequence> <r_tx_preimg> 0x04

OP_SPLIT

Split nSequence

<nSequence> <nLocktime> <rr_tx_preimg>

OP_SWAP

Swap nLocktime to top of stack

<nSequence> <rr_tx_preimg><nLocktime>

0x00

add 0x00 (push 0x00 to stack, do not use OP_FALSE)

<nSequence> <rr_tx_preimg><nLocktime> 0x00

OP_CAT

add two leading zeroes as MSB so locktime will be interpreted as a positive integer

<nSequence> <rr_tx_preimg> <nLocktime+00>

<expiry>

Load pre-set expiry time to stack. this is in Unix epoch time, rather than block-height.

<nSequence> <rr_tx_preimg> <nLocktime+00> <expiry>

OP_GREATERTHANOREQUAL

Check that the nLocktime is at or after the pre-set expiry

<nSequence> <rr_tx_preimg> <result>

OP_VERIFY

If expiry is valid, the script will continue

<nSequence><rr_tx_preimg>

OP_SWAP

Swap nLocktime to top of stack

<rr_tx_preimg><nSequence>

0x00

Push 0x00 onto the stack

<rr_tx_preimg><nSequence> 0x00

OP_CAT

Attach 00 to front of nSequence to ensure it is interpreted as a positive integer by the validation engine

<r_tx_preimg><nSequence+00>

0xffffffff00

load finalised nSequence to stack. Value is little-endian so leading zeroes/MSB are on the right

<r_tx_preimg><nSequence+00> 0xffffffff00

OP_LESSTHAN

Check nSequence is less than final

<r_tx_preimg> <result>

OP_VERIFY

If the input is non-final, the script can continue

<r_tx_preimg>

...

rest of script

In this script, we first check that the nLocktime is set to a time in the future, before also checking whether the input is non-final. By doing both of these things, we can validate that the transaction will remain in an open payment channel until the nLocktime has expired, replicating and extending the functionality of removed opcode OP_CHECKLOCKTIMEVERIFY.

Last updated

Was this helpful?