10

Giacomo Zucco pointed out the oddity of there being one timelock field per transaction, but one sequence per input. Even for the original use of determining the order of replacement, it would seem that only the maximum sequence is relevant in the context of the whole transaction rather than each input. Is there a known reason or benefit for each input having a sequence or is it a quirk in the transaction design? What about locktime, would there be a benefit if it also was set per input instead of only once per transaction?

2 Answers 2

7

See @RedGrittyBrick's answer for historical context for why there is a per-input nSequence field. The evolution since includes:

  • nLockTime's meaning has been unchanged since the early days; it indicates the earlier time or height when the transaction can be included in a block (consensus rule). BIP65 later added script functionality for putting constraints on the spending nLockTime value, but the semantics of nLockTime themselves have been unchanged.
  • nSequence was designed for transaction replacement, and in the original design for transaction replacement, every input could be replaced independently (and could signal independently whether it could be replaced). Originally, nSequence only had one consensus-affecting impact: if all nSequence were 0xFFFFFFFF, the transaction is always eligible for inclusion (even if nLockTime hasn't passed yet). The meaning of nSequence was however changed completely:
    • The original replacement semantics were disabled in August 2010, rendering the distinction between all non-0xFFFFFFFF nSequence values meaningless.
    • Non-eligible-for-inclusion-in-blocks transactions were disallowed in January 2013 for relay and mempool acceptance (due to DoS concerns) entirely.
    • Later, BIP68 added a consensus meaning to nSequence, as a "relative locktime", repurposing the old field that had become redundant. Simultaneously BIP112 added script functionality to put constraints on the spending nSequence.
    • BIP125 added new transaction replacement rules that didn't involve sequencing anymore.

In retrospect however, I believe it would actually have been better if both absolute and relative locktimes were per-input. Absolute locktimes (the per-transaction nLockTime field) suffer from the problem that one cannot specify both a height-based and a time-based one, which implies that two UTXOs which (through BIP65's OP_CHECKLOCKTIMEVERIFY) require distinct types of locktimes cannot be spent simultaneously in the same transaction.

6

I'm not sure if you will have already seen this:

From: Satoshi Nakamoto <[email protected]
Date: Wed, Mar 9, 2011 at 5:15 PM
To: Mike Hearn [email protected]
Subject: Re: Open sourced my Java SPV impl

[...]

I haven't fully understood why sequence numbers are a property of the tx inputs rather than the tx itself.

It's for contracts. An unrecorded open transaction can keep being replaced until nLockTime. It may contain payments by multiple parties. Each input owner signs their input. For a new version to be written, each must sign a higher sequence number (see IsNewerThan). By signing, an input owner says "I agree to put my money in, if everyone puts their money in and the outputs are this." There are other options in SignatureHash such as SIGHASH_SINGLE which means "I agree, as long as this one output (i.e. mine) is what I want, I don't care what you do with the other outputs.". If that's written with a high nSequenceNumber, the party can bow out of the negotiation except for that one stipulation, or sign SIGHASH_NONE and bow out completely.

The parties could create a pre-agreed default option by creating a higher nSequenceNumber tx using OP_CHECKMULTISIG that requires a subset of parties to sign to complete the signature. The parties hold this tx in reserve and if need be, pass it around until it has enough signatures.

One use of nLockTime is high frequency trades between a set of parties. They can keep updating a tx by unanimous agreement. The party giving money would be the first to sign the next version. If one party stops agreeing to changes, then the last state will be recorded at nLockTime. If desired, a default transaction can be prepared after each version so n-1 parties can push an unresponsive party out. Intermediate transactions do not need to be broadcast. Only the final outcome gets recorded by the network. Just before nLockTime, the parties and a few witness nodes broadcast the highest sequence tx they saw.

Quoted from https://www.bitcoin.com/satoshi-archive/emails/mike-hearn/13/
Also seen at https://plan99.net/~mike/satoshi-emails/thread4.html

Mike Hearn replied

Ah ha. A whole unexplored area of the system opens up before my eyes :-) The concept of forming distributed contracts and escrow transactions without needing to trust an intermediary is a concept nearly as novel as BitCoin itself, I think.


I believe the above explains Nakamoto's motivation for the choices initially made with respect to sequence and locktime. Or at least I believe Nakamoto believed it answered that specific question.


As I expect many people know, use of these data fields has subsequently been affected by adoption of ideas such as BIP-68 and forced closure of Lightning channels etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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