§ 05 · Transactions
Locktime and sequence
Two small fields that say "not before"
On this page 6 sections
Most transactions can be mined the moment they’re broadcast. Two small fields let a transaction say otherwise: “not before block such-and-such”, or “not until this coin is so many blocks old”.
The locktimeLocktime: A field that stops a transaction from being valid before a chosen block height or time. Zero, the usual value, means no lock. sits at the very end of the transaction and applies to the whole thing. The sequenceSequence: A 4-byte number in each input, used for relative time locks and to signal that a transaction may be replaced by one paying more (RBF). sits in each input and has grown three jobs over Bitcoin’s history. Pearl inherited both unchanged, switched on from block 1. Its wallet, though, leaves them at their “off” values.
Try it
The OP_RETURN example signals replace-by-fee. Find its sequence field.
What is the locktime?
- Size
- 4 bytes
- Type
- Unsigned integer
- Format
- Little-endian
- Range
- 0 to 4,294,967,295
The last four bytes of every transaction. The value is read three ways:
| Value | Meaning |
|---|---|
| 0 | No lock. What Pearl’s wallet always writes. |
| 1 to 499,999,999 | A block height: the transaction can only be in a block whose height is greater than this. |
| 500,000,000 and up | A Unix time: only in a block whose median time past is later than this. |
There’s an escape hatch: if every input’s sequence is ffffffff, the locktime is ignored altogether.
Here are the locktime bytes of a real payment, 00000000:
| Field | Bytes | Value |
|---|---|---|
| Version version | 4 @0 | 1 int32 little-endian. Pearl wallets and pearld coinbases use version 1; relay policy accepts 1-2. |
| Marker marker | 1 @4 | 0x00 Segwit marker (BIP-144): says witness data follows the outputs. |
| Flag flag | 1 @5 | 0x01 Witness flag; 0x01 is the only value Pearl accepts. |
| Input count vin.length | 1 @6 | 1 CompactSize number of inputs. |
| Previous txid vin[0].txid | 32 @7 | 33218153e215d1a1e80941850a696af178fc83bd6cf266be92e7ba9170553959 The transaction being spent, stored byte-reversed (internal order); shown here in normal display order. |
| Output index vin[0].vout | 4 @39 | 683 Which output of that transaction is spent (uint32 LE). |
| scriptSig length vin[0].scriptSig.length | 1 @43 | 0 Always 0 for non-coinbase inputs in Pearl: every spend uses the witness instead. |
| Sequence vin[0].sequence | 4 @44 | 0xffffffff Final (0xffffffff): no RBF signal, no relative locktime, and locktime is ignored for this input. Pearl wallets use this. |
| Output count vout.length | 1 @48 | 2 CompactSize number of outputs. |
| Amount vout[0].value | 8 @49 | 295,646,640 grains (2.95646640 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains). |
| Script length vout[0].scriptPubKey.length | 1 @57 | 34 CompactSize length of the locking script. |
| Locking script vout[0].scriptPubKey | 34 @58 | prl1p674s9jt2xs4amk6aq7ul867kcp8qwll5zsvpzzu6revewsu5z6eqv9d5z4 OP_1 OP_PUSHBYTES_32 <output key Q>: a Taproot output. |
| Amount vout[1].value | 8 @92 | 200,000,000 grains (2.00000000 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains). |
| Script length vout[1].scriptPubKey.length | 1 @100 | 34 CompactSize length of the locking script. |
| Locking script vout[1].scriptPubKey | 34 @101 | prl1pvt5a5d5z42egswfv7uscht7rv2rj3z4m8n3qp3w35592ydq88v4seuhn70 OP_1 OP_PUSHBYTES_32 <output key Q>: a Taproot output. |
| Witness items witness[0].length | 1 @135 | 1 Number of witness stack items for input 0. |
| Schnorr signature length witness[0][0].length | 1 @136 | 64 CompactSize length of this witness item. |
| Schnorr signature witness[0][0] | 64 @137 | 4686c7014749649b25555874c7772ecb7a44e85454893ed5888db11ebcdc82a22d74ce1a1671d02810f5ba1dca3277409e95a653ba9644099f7da26be7a86ba2 64-byte BIP-340 signature (R.x ‖ s) with SIGHASH_DEFAULT: a Taproot key-path spend. |
| Locktime locktime | 4 @201 | 0 0: no time lock. |
Which clock do time locks use?
Not the block’s own timestamp, which a miner could fudge. Time locks are compared with the median time pastMedian time past: The median timestamp of the previous 11 blocks. Time-based locktimes are compared against it, not against the clock, so miners cannot unlock coins early by lying about the time.: the median timestamp of the previous 11 blocks (BIP-113).
Pearl adds a twist. Each block’s timestamp must be at least one second after its parent’s, so timestamps only go up, and the median of 11 is simply the 6th most recent. At the 194-second target, that’s roughly five block intervals, about 16 minutes, behind the latest block. (An estimate from the rules, not a measurement.)
What is the sequence number?
- Size
- 4 bytes per input
- Type
- Unsigned integer
- Format
- Little-endian
Satoshi meant it for updating unconfirmed transactions. That idea was dropped, and the field was later reused, bit by bit:
| Sequence | What it means |
|---|---|
ffffffff |
Final. No replace-by-fee signal, no relative lock; if all inputs say this, locktime is off. Pearl’s wallet default. |
fffffffe |
Locktime enabled, no replace-by-fee signal. |
fffffffd or less |
Signals opt-in replace-by-fee (BIP-125). |
| top bit clear, version ≥ 2 | A relative lock (BIP-68), described below. |
A real transaction from block 130,809 uses fdffffff, that is 0xfffffffd: it signals replace-by-fee, and since its top bit is set, it isn’t a relative lock.
| Field | Bytes | Value |
|---|---|---|
| Version version | 4 @0 | 2 int32 little-endian. Pearl wallets and pearld coinbases use version 1; relay policy accepts 1-2. |
| Marker marker | 1 @4 | 0x00 Segwit marker (BIP-144): says witness data follows the outputs. |
| Flag flag | 1 @5 | 0x01 Witness flag; 0x01 is the only value Pearl accepts. |
| Input count vin.length | 1 @6 | 1 CompactSize number of inputs. |
| Previous txid vin[0].txid | 32 @7 | ad4e340fe4d41a0842ab0a102222fc07a8052afe171ba7e7cbc3dfacb83fe845 The transaction being spent, stored byte-reversed (internal order); shown here in normal display order. |
| Output index vin[0].vout | 4 @39 | 2 Which output of that transaction is spent (uint32 LE). |
| scriptSig length vin[0].scriptSig.length | 1 @43 | 0 Always 0 for non-coinbase inputs in Pearl: every spend uses the witness instead. |
| Sequence vin[0].sequence | 4 @44 | 0xfffffffd signals opt-in replace-by-fee (BIP-125). |
| Output count vout.length | 1 @48 | 3 CompactSize number of outputs. |
| Amount vout[0].value | 8 @49 | 48,047,555,000 grains (480.47555000 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains). |
| Script length vout[0].scriptPubKey.length | 1 @57 | 34 CompactSize length of the locking script. |
| Locking script vout[0].scriptPubKey | 34 @58 | prl1p3995s5kmdgjrldc9yd450kjuevvv8w5fd3dssw9e6hpwjw3wln6qstfvct OP_1 OP_PUSHBYTES_32 <output key Q>: a Taproot output. |
| Amount vout[1].value | 8 @92 | 0 grains (0.00000000 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains). |
| Script length vout[1].scriptPubKey.length | 1 @100 | 39 CompactSize length of the locking script. |
| Locking script vout[1].scriptPubKey | 39 @101 | OP_RETURN data (unspendable) OP_RETURN data carrier: provably unspendable, never enters the UTXO set. |
| Amount vout[2].value | 8 @140 | 6,422,205,178,247 grains (64222.05178247 PRL) int64 little-endian, in grains (1 PRL = 100,000,000 grains). |
| Script length vout[2].scriptPubKey.length | 1 @148 | 34 CompactSize length of the locking script. |
| Locking script vout[2].scriptPubKey | 34 @149 | prl1p5f450a5540efskxv050tgscelscuztut6zfaqssq8vnlnw53wvdsmw4yvs OP_1 OP_PUSHBYTES_32 <output key Q>: a Taproot output. |
| Witness items witness[0].length | 1 @183 | 1 Number of witness stack items for input 0. |
| Schnorr signature length witness[0][0].length | 1 @184 | 64 CompactSize length of this witness item. |
| Schnorr signature witness[0][0] | 64 @185 | 834fa0d9eb91ac59fcf21e911b43eca33608b6b8393c6a304a959cfaeebbb505ff38d095905be416e78c70ae3fe6d018d823d6ff36467f3199bea33f91976c71 64-byte BIP-340 signature (R.x ‖ s) with SIGHASH_DEFAULT: a Taproot key-path spend. |
| Locktime locktime | 4 @249 | 0 0: no time lock. |
How does a relative lock work?
A relative lockRelative locktime: A lock written in an input's sequence number: the coin it spends must be a certain number of blocks (or 512-second units) old. It only applies to transactions of version 2 or higher. says “the coin this input spends must be at least N blocks (or N × 512 seconds) old”. It’s written in the sequence number when the transaction’s version is 2 or higher:
| Field | Size | Description |
|---|---|---|
| bit 31 | 1 bit | Disable flag. Set: no relative lock (true of every value from 80000000 up, including fffffffd–ffffffff). |
| bit 22 | 1 bit | Type flag. Clear: the value counts blocks. Set: it counts units of 512 seconds. |
| bits 0–15 | 16 bits | The value: up to 65,535 blocks or 65,535 × 512 seconds (about 388 days). |
Scripts can demand these locks too: OP_CHECKLOCKTIMEVERIFY (BIP-65) and OP_CHECKSEQUENCEVERIFY (BIP-112) work in Pearl’s tapscript, as in Bitcoin. All of these rules are on from the first block; Pearl never had a soft-fork activation for them.
What is replace-by-fee on Pearl?
Replace-by-feeReplace-by-fee (RBF): Swapping an unconfirmed transaction for a new version that pays a higher fee. On Pearl it is opt-in, and the reference wallet doesn't turn it on. lets you swap an unconfirmed transaction for a new version that pays a higher fee. On Pearl it’s opt-in only, as in Bitcoin’s BIP-125:
- A transaction is replaceable if any of its inputs has a sequence of
fffffffdor less, or if an unconfirmed ancestor signals. - The replacement must pay a strictly higher fee rate than each transaction it replaces, and an absolute fee at least their total plus the minimum relay fee for its own size.
- It may evict at most 100 transactions, may not add new unconfirmed inputs, and may not spend the outputs it replaces.
- A node started with
-rejectreplacementrefuses all replacements.
There is no “full RBF” mode, in which any transaction can be replaced whether it signals or not.
What does Pearl’s wallet write?
| Field | Oyster’s value | Effect |
|---|---|---|
| version | 1 | BIP-68 never applies |
| locktime | 0 | no absolute lock |
| sequence | ffffffff |
no RBF, no relative lock |
Bitcoin Core’s wallet does differently: version 2, and a locktime set to the current height to discourage miners from rewriting recent blocks (“anti-fee-sniping”). Pearl’s wallet does neither.