# Blockchain Native

> A blockchain-native application is built from the same components as the one you build today, with one swap at each layer. Here is every swap, and a ledger built both ways.

A blockchain-native application is economic activity whose settlement, custody and rules are on-chain by construction, rather than a conventional business with a token attached to the side of it. That sounds like a different kind of engineering. It is less different than it sounds.

Every component of the stack you build today has a counterpart. The counterpart does the same job with one change: what used to be trusted is now proved. Apogee exists to make that change cheap enough to be the default.

## The shift in one sentence

In a conventional application the server is the authority: it holds the data, applies the rules and reports the result. In a blockchain-native application the chain holds a commitment to the data, the rules are a program anyone can name by its digest, and a result is accepted only with a proof that this program produced it.

The operator does not disappear. Someone still runs the program, stores the data and answers requests. What disappears is the need to believe them.

## Layer by layer

| Layer | Conventional application | Blockchain-native, on Apogee | What carries over |
| --- | --- | --- | --- |
| Business logic | A service you deploy to servers you operate | A guest program: `no_std` Rust compiled to RISC-V and proved on every run | You still write functions over data. The program is named by its identity, a digest of its code and configuration. |
| Data store | SQL tables, a key-value store | The data stays off-chain; the chain stores a state root, one hash that summarizes a snapshot of all of it | A snapshot you can name in 32 bytes and check anything against. |
| Read query | `SELECT balance FROM accounts WHERE id = ?` | An inclusion proof, a Merkle path, which the guest checks against the root | A query still returns a row. The row now arrives with evidence, and the guest refuses any row that does not check. |
| Write | `UPDATE …; COMMIT;` | A state transition: the guest computes the new root and publishes it | Commit still means "make it durable". It now means a contract moving the stored root forward. |
| Request | An HTTP request body | The public input, which the proof binds | Inputs in, outputs out. |
| Bulk payload | Uploads, joined rows, fetched documents | Advice: bytes the prover supplies and the guest checks against something the proof binds | Pass large data by reference and check what arrived. |
| Response | A JSON body | The journal: the public output, bound by the proof | Anyone can read the response and know it is the program's. |
| Authentication | Sessions, tokens, passwords | Signatures verified inside the guest; secp256k1 recovery runs on delegated field and curve arithmetic | Identity is a key, and authorization is a check you can read in the source. |
| Cryptography libraries | `sha2`, `ring`, OpenSSL | `guest_sdk::keccak256`, `sha256`, `ec_add`, each routed to a dedicated circuit | The same calls, at a fraction of the cycles. |
| Release | Push a binary and behaviour changes at once | Register the new program identity with the verifier contract | Releases become explicit: a new build is a new identity that the contract has to accept. |
| Scale | More servers, sharded databases | An execution cut into shards that prove in parallel, folded by recursion into one proof | Throughput comes from provers working side by side, while the chain still checks one proof. |
| Audit | Logs and attestations you ask people to believe | The proof and its journal | Assurance moves from reputation to verification. |

The middle column is what a blockchain-native application is made of. Apogee supplies the machinery underneath it: the RISC-V machine, the circuits, the commitments, the recursion and the verifier contract. None of that appears in your program.

## What does not change

- **You still write ordinary Rust.** Structs, enums, traits, iterators, `Vec`, `BTreeMap`, and any crate that builds without `std`. There is no circuit language to learn.
- **You still test on your laptop.** The usual layout puts the application logic in a `no_std` library that runs on the host, under `cargo test`, exactly as it runs in the guest. See [Writing a guest](https://apogee.gweb3networks.com/docs/launch/write#host-first).
- **You still reason about state, requests and responses.** The shapes are the same; only their guarantees change.
- **Deterministic code stays deterministic.** Good backend code already avoids hidden inputs. The VM makes that absolute.

## What does change

- **No ambient world.** A guest has no clock, no randomness, no network and no files. Everything it knows arrives as public input or as advice, and a request for host data is a call no proof admits.
- **Every instruction has a price.** Each executed instruction becomes a proved row. Copies, allocations and dead loops cost proving time, so the old discipline of counting cycles comes back.
- **Supplied data is checked, not trusted.** Advice is chosen by the prover. A guest checks it against something the proof binds before anything derived from it is published.
- **Outputs are small and public.** The journal holds at most 16,380 bytes. A large result is published as a digest.
- **Nothing is hidden.** Apogee v1.0.0 proofs are succinct, not zero-knowledge. A guest must not hold secrets.

## A ledger, built both ways

A deposit into an account balance: the smallest state change worth proving.

### The conventional version

```sql
BEGIN;
SELECT balance FROM accounts WHERE id = $1 FOR UPDATE;    -- read
UPDATE accounts SET balance = balance + $2 WHERE id = $1;  -- write
COMMIT;                                                     -- make it durable
```

Users trust the operator to have run exactly this, against the real table, and to report the result honestly.

### The blockchain-native version

The accounts live in a binary Merkle tree whose leaves are `keccak256(account ‖ balance)`. A contract stores the root. The guest receives the old root and the request as public input, receives the account's balance and Merkle path as advice, checks the path, and publishes the old and new roots.

```rust title="guests/ledger/src/main.rs"
#![no_std]
#![no_main]

guest_sdk::entry!(main);

const DEPTH: usize = 20; // room for 2^20 accounts

/// A leaf commits to one account's balance.
fn leaf(account: &[u8; 20], balance: u64) -> [u8; 32] {
    let mut bytes = [0u8; 28];
    bytes[..20].copy_from_slice(account);
    bytes[20..].copy_from_slice(&balance.to_le_bytes());
    guest_sdk::keccak256(&bytes)
}

/// Fold a leaf up its Merkle path; bit `level` of `index` says whether the
/// node is a right child at that level.
fn root_of(mut node: [u8; 32], index: u32, path: &[[u8; 32]; DEPTH]) -> [u8; 32] {
    let mut pair = [0u8; 64];
    for (level, sibling) in path.iter().enumerate() {
        let (left, right) = if (index >> level) & 1 == 0 { (&node, sibling) } else { (sibling, &node) };
        pair[..32].copy_from_slice(left);
        pair[32..].copy_from_slice(right);
        node = guest_sdk::keccak256(&pair);
    }
    node
}

/// Public input: old_root (32) ‖ account (20) ‖ amount (8, LE)
/// Advice:       balance (8, LE) ‖ index (4, LE) ‖ path (DEPTH × 32)
/// Journal:      old_root ‖ new_root ‖ account ‖ amount
fn main() {
    let input = guest_sdk::public_input();
    let advice = guest_sdk::advice();
    if input.len() != 60 || advice.len() != 12 + 32 * DEPTH {
        guest_sdk::exit(1);
    }
    let old_root: [u8; 32] = input[..32].try_into().unwrap();
    let account: [u8; 20] = input[32..52].try_into().unwrap();
    let amount = u64::from_le_bytes(input[52..60].try_into().unwrap());

    let balance = u64::from_le_bytes(advice[..8].try_into().unwrap());
    let index = u32::from_le_bytes(advice[8..12].try_into().unwrap());
    let mut path = [[0u8; 32]; DEPTH];
    for (i, sibling) in path.iter_mut().enumerate() {
        sibling.copy_from_slice(&advice[12 + 32 * i..12 + 32 * (i + 1)]);
    }

    // The query: the balance the prover supplied is the one the root commits to.
    if root_of(leaf(&account, balance), index, &path) != old_root {
        guest_sdk::exit(2);
    }
    // The write: the same path with the new leaf gives the new root.
    let Some(new_balance) = balance.checked_add(amount) else { guest_sdk::exit(3) };
    let new_root = root_of(leaf(&account, new_balance), index, &path);

    // The commit: publish the transition for the contract to apply.
    guest_sdk::commit(&old_root);
    guest_sdk::commit(&new_root);
    guest_sdk::commit(&account);
    guest_sdk::commit(&amount.to_le_bytes());
}
```

Read it against the SQL. `SELECT … FOR UPDATE` became a Merkle path checked against the root. `UPDATE` became a new leaf on the same path. `COMMIT` became four calls to `commit`, which write the journal the proof will bind. The balance came from the prover, and that is fine: a balance the root does not commit to fails the check and the run exits 2.

The contract that owns the root accepts a transition only with a proof that this program produced it and exited 0:

```solidity title="Ledger.sol (sketch)"
interface IApogeeVerifier {
    function verify(bytes calldata input, bytes calldata output, uint256 exitStatus,
                    uint256[10] calldata proof, uint256[] calldata points) external view returns (bool);
}

contract Ledger {
    IApogeeVerifier public immutable verifier;
    bytes32 public root;

    constructor(IApogeeVerifier v, bytes32 genesis) { verifier = v; root = genesis; }

    function apply(bytes calldata input, bytes calldata journal,
                   uint256[10] calldata proof, uint256[] calldata points) external {
        require(verifier.verify(input, journal, 0, proof, points), "proof");
        require(bytes32(journal[0:32]) == root, "stale root");
        root = bytes32(journal[32:64]);
    }
}
```

> [!NOTE]
> This is a sketch to show the shape, not a production contract. A real deployment takes a batch of requests per proof, which the guest folds into one transition, and pins the verifier to the right program and public-value lengths. [Settle on-chain](https://apogee.gweb3networks.com/docs/launch/on-chain) covers the deployed verifier, its key and its ceremony.

## The model in three lines

1. The chain holds a root.
2. The guest proves the transition.
3. The contract moves the root.

Everything else, from the shards and circuits to the recursion and the decider, is Apogee's. That is the abstraction: a program, its input and its output, and a proof that ties them together.

## Next

- [Quickstart](https://apogee.gweb3networks.com/docs/launch/quickstart): From an empty crate to a verified proof.

- [Inputs, advice and the journal](https://apogee.gweb3networks.com/docs/launch/io): The three memory regions every guest works with.

- [Guest programming guide](https://apogee.gweb3networks.com/docs/launch/guide): The habits that keep a guest correct, provable and cheap.
