> For the complete documentation index, see [llms.txt](https://hub.bsvblockchain.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hub.bsvblockchain.org/bitcoin-protocol-documentation/specification/transactions.md).

# Transactions

A transaction is the data structure that consumes existing outputs and creates new ones. It comprises a list of **inputs** and a list of **outputs**.

Each **input** consists of:

1. a reference to the previous output being spent (its transaction id and output index), and
2. an unlocking script that satisfies that output's spending condition (typically a digital signature).

Each **output** consists of:

1. an amount, and
2. a locking script that sets the condition under which the output may later be spent.

A transaction is identified by its **Transaction Identifier (TxID)**, the double-SHA-256 of its serialization (see [Serialization format](#serialization-format)).

<figure><img src="/files/NIZx3fcb2zjtdf3SypNf" alt=""><figcaption></figcaption></figure>

Input in the transaction is to have a set of fields that unlock funds from the previous unspent output. The nature of the unlocking process depends on the lock used when the output was created in the previous transaction (UTXO), which is being spent. There is no separate consensus cap on the *count* of inputs or outputs: both are CompactSize-prefixed lists. In practice the **serialized transaction size limit** (1 MB pre-Genesis, 1 GB from Genesis) binds long before encoding limits on the count field. Separately, each input's prevout index is a 32-bit field, so an individual previous transaction cannot have a spendable output at index greater than `2³²−1`.

The overall data structure of a transaction is shown in the following diagram.

<figure><img src="/files/RWvfUBFEk7PCw9Ng8Atc" alt=""><figcaption><p>Internal data structure of a transaction</p></figcaption></figure>

{% hint style="info" %}
One of the biggest nuisances in transaction formats used in bitcoin is the usage of little endian and big endian format for different things. Always keep in mind this property as part of debugging process when developing code to build transactions.
{% endhint %}

## Serialization format

This section specifies the exact byte layout of a transaction as it appears on the wire and in a block. It is the consensus serialization: two encodings of the same transaction that differ in any byte are different transactions with different TxIDs.

**Ground truth.** The field layout and constants below derive from `CTransaction`, `CTxIn`, `CTxOut`, and `COutPoint` in [`src/primitives/transaction.h`](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/primitives/transaction.h), and the count/length prefixing from `WriteCompactSize` in [`src/serialize.h`](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/serialize.h#L296). All citations are pinned to release **v1.2.2** (commit `879fc8b`).

### Conventions

* **Little-endian** unless stated otherwise: all integer fields (`nVersion`, `nSequence`, `nLockTime`, the output amount, and the `CompactSize` multi-byte forms) are serialized least-significant byte first.
* **`txid` / hashes** are 32-byte values written in internal byte order (the reverse of the big-endian hex string normally displayed to users).
* **CompactSize** is the variable-length count/length prefix — see [CompactSize (VarInt)](#compactsize-varint).

### Top-level transaction

A transaction serializes as exactly four fields, in this order (`SerializeTransaction`, [`transaction.h` L227–L252](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/primitives/transaction.h#L227-L252)):

| # | Field        | Type        | Size (bytes) | Encoding                | Notes                                                                                                                                                                                               |
| - | ------------ | ----------- | ------------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | `nVersion`   | int32       | 4            | little-endian, signed   | Default `CURRENT_VERSION = 2`. Pre-Chronicle standard versions are 1–2; version influences Chronicle malleability opt-outs (see [Script](/bitcoin-protocol-documentation/specification/script.md)). |
| 2 | input count  | CompactSize | 1–9          | —                       | Number of inputs that follow.                                                                                                                                                                       |
| 3 | `vin`        | `CTxIn`\[]  | variable     | —                       | The inputs, back to back, in order (see [Input](#input-ctxin)).                                                                                                                                     |
| 4 | output count | CompactSize | 1–9          | —                       | Number of outputs that follow.                                                                                                                                                                      |
| 5 | `vout`       | `CTxOut`\[] | variable     | —                       | The outputs, back to back, in order (see [Output](#output-ctxout)).                                                                                                                                 |
| 6 | `nLockTime`  | uint32      | 4            | little-endian, unsigned | Earliest time/height at which the transaction may be included; see [nLockTime](#nlocktime).                                                                                                         |

There is no field for the number of bytes in the transaction: total size is implied by the fields. The **TxID** is the double-SHA-256 of this exact byte serialization, displayed as big-endian hex (byte-reversed).

### Input (`CTxIn`)

Each input serializes three fields ([`transaction.h` L150–L157](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/primitives/transaction.h#L150-L157)):

| # | Field              | Type        | Size (bytes) | Encoding      | Notes                                                                                         |
| - | ------------------ | ----------- | ------------ | ------------- | --------------------------------------------------------------------------------------------- |
| 1 | `prevout`          | `COutPoint` | 36           | see below     | The output being spent.                                                                       |
| 2 | `scriptSig` length | CompactSize | 1–9          | —             | Byte length of the unlocking script.                                                          |
| 3 | `scriptSig`        | bytes       | variable     | raw           | The unlocking script (see [Script](/bitcoin-protocol-documentation/specification/script.md)). |
| 4 | `nSequence`        | uint32      | 4            | little-endian | Default `SEQUENCE_FINAL = 0xffffffff`. See [nSequence](#nsequence).                           |

The `prevout` (`COutPoint`, [`transaction.h` L60–L66](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/primitives/transaction.h#L60-L66)) is a fixed 36 bytes:

| # | Field  | Type   | Size (bytes) | Encoding            | Notes                                                                                                                                                                           |
| - | ------ | ------ | ------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | `txid` | hash   | 32           | internal byte order | TxID of the transaction containing the output being spent.                                                                                                                      |
| 2 | `n`    | uint32 | 4            | little-endian       | Index of the output within that transaction (0-based). Because this field is 4 bytes, an output at index > `0xffffffff` (4,294,967,295) could never be referenced by any input. |

### Output (`CTxOut`)

Each output serializes two fields ([`transaction.h` L188–L193](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/primitives/transaction.h#L188-L193)):

| # | Field                 | Type        | Size (bytes) | Encoding              | Notes                                                                                                 |
| - | --------------------- | ----------- | ------------ | --------------------- | ----------------------------------------------------------------------------------------------------- |
| 1 | `nValue`              | int64       | 8            | little-endian, signed | Amount in **satoshis**. Must be in `[0, MAX_MONEY]`; `MAX_MONEY = 21,000,000 × 100,000,000` satoshis. |
| 2 | `scriptPubKey` length | CompactSize | 1–9          | —                     | Byte length of the locking script.                                                                    |
| 3 | `scriptPubKey`        | bytes       | variable     | raw                   | The locking script (see [Script](/bitcoin-protocol-documentation/specification/script.md)).           |

`COIN = 100,000,000` satoshis; `MAX_MONEY` is a **consensus** value ([`amount.h` L115–L133](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/amount.h#L115-L133)).

## CompactSize (VarInt)

Every count and script-length prefix above is a **CompactSize**: a 1-, 3-, 5-, or 9-byte little-endian unsigned integer whose width is chosen by the value (`WriteCompactSize`, [`serialize.h` L296–L313](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/serialize.h#L296-L313)):

| Value range                | Total bytes | Encoding                                      |
| -------------------------- | ----------- | --------------------------------------------- |
| `0` … `252`                | 1           | the value as a single byte                    |
| `253` … `65,535`           | 3           | `0xfd` then the value as uint16 little-endian |
| `65,536` … `4,294,967,295` | 5           | `0xfe` then the value as uint32 little-endian |
| `4,294,967,296` … `2⁶⁴−1`  | 9           | `0xff` then the value as uint64 little-endian |

The encoding must be **canonical**: a value must use the shortest form that fits, and the decoder rejects a non-minimal encoding ([`serialize.h` `ReadCompactSize` L315](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/serialize.h#L315-L338)).

## nLockTime

`nLockTime` (4-byte LE uint32) sets the earliest point at which a transaction may be mined. It is interpreted against the threshold `LOCKTIME_THRESHOLD = 500,000,000` ([`script.h` L36](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/script.h#L36)):

| `nLockTime` value   | Interpretation                                                                         |
| ------------------- | -------------------------------------------------------------------------------------- |
| `0`                 | No lock — the transaction is final immediately.                                        |
| `1` … `499,999,999` | A **block height**; the transaction is not final until that height.                    |
| `≥ 500,000,000`     | A **Unix timestamp**; the transaction is not final until that time (median-time-past). |

`nLockTime` has no effect if **every** input has `nSequence = 0xffffffff` (`SEQUENCE_FINAL`), in which case the transaction is final regardless. The precise finality test is a consensus rule — see the Consensus Rules page.

## nSequence

`nSequence` is a 4-byte little-endian `uint32` on every input. Its only role that bears on validity in the **current** protocol is the finality flag: an input with `nSequence == 0xffffffff` (`SEQUENCE_FINAL`) is final, and if **every** input is final the transaction is final regardless of `nLockTime` (see [nLockTime](#nlocktime) and the finality rule on the Consensus Rules page).

### BIP68 relative locktime — pre-Genesis only

The `nSequence` field also carries the BIP68 relative-locktime bit-fields ([`transaction.h` L99–L129](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/primitives/transaction.h#L99-L129)):

| Constant                         | Value                    | Meaning                                                                                           |
| -------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------- |
| `SEQUENCE_FINAL`                 | `0xffffffff`             | Input is final; disables `nLockTime` when set on all inputs.                                      |
| `SEQUENCE_LOCKTIME_DISABLE_FLAG` | `1 << 31` (`0x80000000`) | When set, `nSequence` is **not** interpreted as a relative locktime.                              |
| `SEQUENCE_LOCKTIME_TYPE_FLAG`    | `1 << 22` (`0x00400000`) | When set, the relative locktime is measured in units of **512 seconds**; otherwise in **blocks**. |
| `SEQUENCE_LOCKTIME_MASK`         | `0x0000ffff`             | Masks the low 16 bits, which hold the relative-locktime value.                                    |
| `SEQUENCE_LOCKTIME_GRANULARITY`  | `9`                      | Time-based value is multiplied by `2⁹ = 512` seconds.                                             |

{% hint style="warning" %}
On BSV, **BIP68 relative-locktime is not enforced after Genesis.** The relative lock is applied only when the `LOCKTIME_VERIFY_SEQUENCE` verify flag is active, and that flag is set only for pre-Genesis blocks — `StandardNonFinalVerifyFlags` adds it only when Genesis is *not* active ([`src/policy/policy.h` L248–L256](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/policy/policy.h#L248-L256)). This mirrors `OP_CHECKSEQUENCEVERIFY` (`OP_CSV`), which reverts to a no-op at Genesis (see [Opcodes](/bitcoin-protocol-documentation/specification/opcodes.md)). After Genesis the bit-fields above are inert: the only consensus effect of `nSequence` is the `SEQUENCE_FINAL` finality check described above.
{% endhint %}

Where it *does* apply (pre-Genesis, transaction version ≥ 2, disable flag clear): the low 16 bits give the relative locktime — a count of blocks, or (if the type flag is set) a count of 512-second intervals — that must elapse after the spent output was confirmed, computed by `CalculateSequenceLocks` ([`src/validation.cpp` L257–L326](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/validation.cpp#L257-L326)).

## Coinbase transaction

The first transaction in every block is the **coinbase**. It is structurally a normal transaction with exactly **one input** whose `prevout` is null — a `txid` of all zeroes and `n = 0xffffffff` (`COutPoint::IsNull`, [`transaction.h` L68](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/primitives/transaction.h#L68)). Its `scriptSig` is not evaluated as script and carries the block-height prefix (BIP34) plus arbitrary miner data. The additional coinbase-specific rules (scriptSig length bounds, output value = subsidy + fees, maturity) are consensus rules covered on the Consensus Rules and Blocks pages.

## Size limits by era

The maximum serialized transaction size is a consensus limit that changed at Genesis ([`consensus.h` L27–L29](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/consensus/consensus.h#L27-L29)):

| Limit                   | Pre-Genesis            | Genesis onward             |
| ----------------------- | ---------------------- | -------------------------- |
| `MAX_TX_SIZE_CONSENSUS` | 1,000,000 bytes (1 MB) | 1,000,000,000 bytes (1 GB) |

This is the *consensus* bound on validity. Miners may additionally apply smaller **policy** limits to transactions they accept or relay; those are configurable and do not bear on whether a transaction is valid.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://hub.bsvblockchain.org/bitcoin-protocol-documentation/specification/transactions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
