I have been trying to understand locktimes and sequence numbers. I'm gradually building up a picture in my head based on code, code comments and info on the web. Rather than asking lots of questions, I am going to describe my understanding of how locktime and sequence numbers work. Please could someone tell me if it is correct, and if not then please specify exactly which bits are wrong, using examples or pointing me to the source code.

Mining criteria

All transactions inputs have their own sequence number, and there is one locktime for the whole transaction. A transaction can be made "final" by:

  • setting the locktime to 0, or
  • setting the locktime to be less than the current block height, or
  • setting the locktime to be less than the current time (but still above a threshold so that it is not confused for a block height), or
  • setting ALL txin sequence numbers to 0xffffffff.

Any one of these conditions is sufficient for a transaction to be considered "final". If all conditions fail then the transaction is not "final". Only "final" transactions get mined into blocks - non final transactions never make it to the blockchain. Note that the only way that a transaction in the blockchain can contain a locktime with a future timestamp or future block number is if all sequence numbers are set to 0xffffffff.

Locking funds

Say that currently, the block height is 377199. If I wanted to send money to someone, but only have them receive it at some time in the future, then I could make a transaction to their address, set the locktime to 400000 and set all sequence numbers in the transaction to 0xffffffff. This transaction will get mined into block 377200 or maybe 377201. It will also probably require a mining fee. This fee will be part of the coinbase funds and is deducted immediately from the previous transaction being spent (ie. the miner does not have to wait until the locktime to put the funds in the coinbase).

All txin scripts in my locktime=400000 transaction must successfully validate against their corresponding txout scripts in the transaction(s) being spent. Once the locktime=400000 transaction has been mined into a block (say block=377200) then any block built on top of block=377200 cannot double-spend the txouts that my locktime=400000 transaction has already spent. As soon as the locktime=400000 transaction is mined into a block this causes the UTXOs it references to be immediately removed from the pool, even though the funds are locked away for a period until the locktime is reached.

Spending locked funds

Not all transaction outputs that have been mined into a block can be spent immediately or even at all. For one thing, if transaction A is spent by transaction B then the txout scripts in transaction B are not verified for syntax by the miners (though the txout scripts in A are verified). If the txout scripts in B are nonsense then the funds they direct will become forever unspendable.

But in a case where the scriptsig and scriptpubkey do validate, miners will only permit a transaction into the blockchain if it satisfies the locktime criteria. Say someone wishes to spend the locktime=400000 transaction funds (already mined into block) - they would construct a transaction of their own that uses the txouts from the locktime=400000 transaction, and broadcast it to the network. Miners would perform all the standard checks on this new transaction, and the specific checks relating to the locktime would be:

  • that the transaction is "final", as discussed before
  • that this latest block being created is 400000 or greater

If this latest block is not 400000 then the transaction cannot be mined into the block. And infact if a rogue miner does go and put the spending transaction into a block before block 400000 then this block will be rejected by other miners on the network for containing a transaction that fails to validate.

Say the person spending the locktime=400000 transaction funds wants this to happen as soon as block 400000 is reached. If they broadcast their spending transaction too early (eg 377199) then it may get rejected as miners discard the transaction for not validating. If the miners are smart (they probably are but I haven't looked at the code for this) then they will see that the transaction will become spendable at a date in the future, and will hold on to it so that they can mine it into block 400000 and get the fees before everybody else. However if the transaction is too far in the future then the miners may run out of memory to store this transaction and discard it. The person issuing the transaction can check its propagation on blockchain.info and re-broadcast it before block 400000 if propagation is too low.

OP_CHECKLOCKTIMEVERIFY

This opcode can be used in either scriptpubkey or scriptsig (or both at once). It basically compares a stack item (only the rightmost 5 bytes in minimized format) with the transaction's locktime. If the transaction locktime (timestamp when above the threshold or block number when below the threshold) is greater than the stack item then this opcode will validate successfully. But if the transaction locktime has not yet reached the stack item value then the opcode will fail to validate and miners will not include this transaction in a block.

In the case where a script contains OP_CHECKLOCKTIMEVERIFY but the sequence number for that script's txin is 0xffffff then this means that the locktime is being ignored. Therefore OP_CHECKLOCKTIMEVERIFY will fail and the transaction will not be mined into a block.

OP_CHECKLOCKTIMEVERIFY can also be used to make sure funds cannot be accessed until a future date or block. For example to send funds to address xyz but make them accessible at block 400000 or later, the following txout script could be used:

OP_DUP OP_HASH160 OP_PUSHDATA xyz OP_EQUALVERIFY OP_CHECKSIG OP_PUSHDATA 400000 OP_CHECKLOCKTIMEVERIFY

Then to spend this transaction, someone will need to submit a transaction containing locktime 400000 or greater (but still below the threshold).

Say that currently, the block height is 377199. If I wanted to send money to someone, but only have them receive it at some time in the future, then I could make a transaction to their address, set the locktime to 400000 and set all sequence numbers in the transaction to 0xffffffff. This transaction will get mined into block 377200 or maybe 377201.

nLockTime makes a transaction invalid not unspendable. If you attempt to broadcast a transaction before it is valid, it will not be relayed, and is not able to be included in any block. You can retain the transaction until it becomes valid (by block height or time), but you can also spend the original outputs with a completely different transaction in the mean time. For your example it will not make it into a block until at least height 400,000, and only if you broadcast it after that time. nLockTime does not affect the spendability of the output in the blocks, just the validity of the transaction that creates them.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.