> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sundialprotocol.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Ledger and transactions

> The Sundial L2 ledger: blocks and their 10-field headers, the UTXO set, how events are applied, and how the L2 transaction type differs from Cardano's.

The Sundial L2 ledger is a chain of blocks. Each block turns the previous block's set of unspent transaction outputs (UTXOs) into a new one.

Unlike an L1 ledger, it is an open system. Blocks create and destroy UTXOs in response to events on L1 (deposits and withdrawal orders) as well as L2 transactions.

## Blocks

A block is a header hash, a header and a body. The body holds four sets:

| Set | Contents |
| - | - |
| `utxos` | The unspent outputs after applying the block |
| `transactions` | Transaction requests and transaction orders |
| `deposits` | Deposit events from L1 |
| `withdrawals` | Withdrawal orders from L1 |

The full block is published to the data availability layer. Only the header hash and header go to L1. That is sufficient because the header holds the Merkle Patricia Trie root of each set, and each root can be checked on L1 by streaming over the set.

### Order of application

A block applies its events in a fixed order:

1. Withdrawals
2. Transaction orders
3. Transaction requests
4. Deposits

A block that breaks this order is invalid. Orders come before requests so that a transaction order, which costs more to create, is never invalidated in favour of a request.

### The block header

| Field | Meaning |
| - | - |
| `prev_utxos_root` | The previous block's `utxos_root` |
| `utxos_root` | Trie root of the block's UTXO set |
| `transactions_root` | Trie root of the block's transactions |
| `deposits_root` | Trie root of the block's deposits |
| `withdrawals_root` | Trie root of the block's withdrawals |
| `start_time`, `end_time` | The block's event interval |
| `prev_header_hash` | Hash of the previous header. 28 zero bytes for the genesis block. |
| `operator_vkey` | Key hash of the operator that committed the header |
| `protocol_version` | The protocol version that applies to this block |

The header hash is the Blake2b-224 hash of the header, 28 bytes.

## The UTXO set

The UTXO set maps output references to outputs. An output has an address, a value, an optional inline datum and an optional script. An output reference is the ID of the event that created the output (a transaction or a deposit) and its index.

Every L2 address carries the network ID of the Sundial instance, which separates the L2 ledger from the settlement L1 and from other Sundial instances.

## Transactions

There are two ways a transaction reaches a block:

* A **transaction request** is submitted to an operator's API. This is the normal path.
* A **transaction order** is posted on L1. Operators must include it. See [Deposits, withdrawals and transaction orders](https://docs.sundialprotocol.com/l2/user-events.md).

Both land in the same `transactions` set.

### How the transaction type differs from Cardano's

The L2 transaction type is based on Cardano's Conway-era transaction, restricted to what a contract-secured L2 can validate.

| Rule | Why |
| - | - |
| **UTXO transactions only.** No certificates, stake withdrawals, voting or treasury fields. | The L2's consensus is not proof of stake, and its L1 scripts can't authorize staking or governance actions for users. |
| **Conway-era features only.** No bootstrap addresses. Plutus scripts are Plutus V3. | There is no obligation to support earlier eras. |
| **No transaction metadata.** | Scripts can't read metadata, and it adds bytes to every block. Put content you need in an output datum. |
| **Inline datums only.** | The ledger never has to index datum hashes to datums. |
| **Observers and ordered inputs.** The type adopts [CIP-112](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0112) and [CIP-128](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0128). | CIP-112 replaces the "withdraw zero" pattern with an Observe script purpose. CIP-128 keeps inputs in submitted order, which makes scripts cheaper. |
| **POSIX time.** Validity intervals are timestamps, not slots. | The L2's consensus doesn't use slots. |
| **Declared signers.** `required_signer_hashes` lists the key hash of every spent key-hash input. | A missing signature can then be proven without resolving every input. |
| **The validity flag is always true.** | Invalidity is expressed through validity tags and fraud proofs. |

Violating any of these is fraud under the [ledger rules](https://docs.sundialprotocol.com/l2/fraud-proofs.md#ledger-rules).

### Hashed fields

In the form that L1 scripts work with, every variable-length field of a transaction is replaced by its hash. This lets a fraud proof step through a transaction at bounded cost. The data availability layer holds the preimages, and a mismatch between a hash and its preimage is itself provable.

## Confirmed state

A block is confirmed once all its predecessors are confirmed and its maturity period has passed without a verified fraud proof. Confirmation is irreversible, which lets the L1 representation be condensed:

* **`ConfirmedState`** keeps only the last confirmed header's hash, its UTXO root, its time bounds and its protocol version. Each merge overwrites it. Earlier headers are pinned by the chain of header hashes.
* **`Settlement`** takes the block's deposit, withdrawal and transaction roots into a separate settlement UTXO. Users reference it to absorb deposits and pay out withdrawals. See [Consensus](https://docs.sundialprotocol.com/l2/consensus.md#settlement).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.