In Part 5, you saw your balance in the webledger — a JSON file on your pod. But here's the uncomfortable question: why should anyone believe it?
The pod operator could edit the file. They could credit themselves a million sats. They could erase your balance. It's just a JSON file. What makes it more than a spreadsheet?
Bitcoin. Specifically, a technique called blocktrails that anchors state to the Bitcoin blockchain using nothing but keys and hashes. No sidechain. No new token. No consensus change. Just secp256k1 math — the same curve your Nostr key uses.
The core idea is simple. You have a private key. You have some state (say, {"balance": 1000}). You combine them:
| Step | What Happens |
|---|---|
| 1. Hash the state | t = SHA256(state) — a 32-byte tweak |
| 2. Add to the key | newKey = oldKey + t — scalar addition on secp256k1 |
| 3. Derive an address | P2TR(newKey) — a taproot Bitcoin address |
| 4. Send sats there | The state is now anchored to Bitcoin |
The Bitcoin address encodes both the key and the state. Anyone who knows the state can verify the address. Anyone who sees the address on the blockchain knows the state was committed.
To update the state, you spend the output and chain to the next derived key:
Each state change produces a new key, a new address, and a new Bitcoin output. The spend chain on Bitcoin mirrors the state chain off-chain. Bitcoin enforces the ordering. The client verifies the state.
npm install blocktrails
import { Blocktrail } from 'blocktrails';
const trail = new Blocktrail(privateKey);
// Create genesis state
const genesis = trail.genesis('{"balance": 1000}');
console.log(genesis.p2trAddress); // bc1p...
// Advance to new state
trail.advance('{"balance": 900}');
A taproot address (bc1p...) that encodes your state. Send sats to it, and the state is anchored to Bitcoin. Advance the state, and a new address is derived. The chain of addresses on Bitcoin proves the chain of states off-chain.
In Parts 3–5, the pod tracks balances in a webledger. Deposits are verified against Bitcoin (the TXO proves sats exist on chain). But what about the balance itself? What about tokens the pod issues?
Without blocktrails, a pod token is a database entry. With blocktrails, it's a state chain anchored to Bitcoin:
| Without Blocktrails | With Blocktrails | |
|---|---|---|
| Token balance | JSON in a file | State anchored to a Bitcoin TXO |
| Transfer | Pod updates a number | State advances, new TXO on chain |
| Proof | "The pod says so" | Bitcoin spend chain + state hashes |
| Double spend | Possible (edit the file) | Impossible (Bitcoin UTXO rules) |
| Verification | Trust the pod | SPV-compatible (no full node needed) |
This is what MRC20 builds on — a token profile on top of blocktrails. Mint, transfer, burn — all anchored. When you withdraw tokens from a pod with /pay/.withdraw, you get an MRC20 state proof that anyone can verify against Bitcoin.
Now the pieces fit together. Every step in the payment flow has a Bitcoin proof:
| Action | Proof |
|---|---|
| Deposit sats | TXO URI — points to sats on chain |
| Credit balance | Webledger entry — verified from TXO |
| Buy tokens | State advance — new blocktrail TXO |
| Transfer tokens | State advance — spend chain on Bitcoin |
| Withdraw tokens | MRC20 proof — portable, verifiable |
A TXO is a voucher. It says "this value exists at this point on the blockchain." A blocktrail is a chain of vouchers. Each state change is a new voucher, linked to the previous one by key chaining. The entire history is verifiable by anyone with the state data and a set of Bitcoin headers.
Your Nostr key started as an identity (Part 2). Then it became a payment address (Part 3). Now it's also the root of a cryptographic state chain anchored to Bitcoin.
One secp256k1 key. Identity, authentication, payments, and provable state. All the same 32 bytes.
Almost nothing. Bitcoin only stores the commitment — the x-coordinate of the derived public key, encoded as a taproot output. That's 32 bytes per state change.
The actual state lives off-chain: on your pod, in a git repo, on Nostr relays, or anywhere. Bitcoin doesn't care what the state says. It just guarantees the ordering and prevents double-spends through its UTXO mechanics.
| Layer | What It Stores | Size |
|---|---|---|
| Bitcoin | P2TR output (commitment) | 32 bytes |
| Pod / Nostr / Git | Actual state data | Any size |
| Client | State history for verification | Varies |
Verification is SPV-compatible. You don't need a full Bitcoin node — just block headers and merkle proofs, exactly like Section 8 of the whitepaper.
Part 7: Your Pod, Your Token. Now that state is provable, your pod can issue tokens. /pay/.buy converts sats to pod tokens. /pay/.withdraw exports them as MRC20 proofs anchored via blocktrails. Portable, verifiable, yours.