Anchored to Bitcoin

Blocktrails, key chaining, and provable state
April 2026 · melvin.me · Part 6 of Solid Articles

1. The Trust Problem

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.

2. Key Chaining

The core idea is simple. You have a private key. You have some state (say, {"balance": 1000}). You combine them:

StepWhat Happens
1. Hash the statet = SHA256(state) — a 32-byte tweak
2. Add to the keynewKey = oldKey + t — scalar addition on secp256k1
3. Derive an addressP2TR(newKey) — a taproot Bitcoin address
4. Send sats thereThe 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:

State₀ Key₀ TXO₀
spend
State₁ Key₁ TXO₁
spend
State₂ Key₂ TXO₂

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.

3. Try It

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}');
What you get

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.

4. Why This Matters for Tokens

In Parts 35, 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 BlocktrailsWith Blocktrails
Token balanceJSON in a fileState anchored to a Bitcoin TXO
TransferPod updates a numberState advances, new TXO on chain
Proof"The pod says so"Bitcoin spend chain + state hashes
Double spendPossible (edit the file)Impossible (Bitcoin UTXO rules)
VerificationTrust the podSPV-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.

5. The Voucher Economy

Now the pieces fit together. Every step in the payment flow has a Bitcoin proof:

ActionProof
Deposit satsTXO URI — points to sats on chain
Credit balanceWebledger entry — verified from TXO
Buy tokensState advance — new blocktrail TXO
Transfer tokensState advance — spend chain on Bitcoin
Withdraw tokensMRC20 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.

The key insight

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.

6. What Bitcoin Stores

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.

LayerWhat It StoresSize
BitcoinP2TR output (commitment)32 bytes
Pod / Nostr / GitActual state dataAny size
ClientState history for verificationVaries

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.