Over the last nine articles, we built a stack: pods for data, ACLs for access control, Nostr keys for identity, webledgers for balances, blocktrails for Bitcoin anchoring, tokens for value, and an AMM for trading.
But here's the thing: nothing about blocktrails is specific to money. The key chaining from Part 6 anchors state to Bitcoin. Any state. The MRC20 token profile is just one application. The primitive is more powerful than what we've used it for.
A fungible token (MRC20) has a balance — "you have 50 PODS." An NFT has an owner — "you own this specific thing."
With blocktrails, an NFT is a state chain where the state is ownership:
// Genesis: Alice creates an NFT
{ "owner": "did:nostr:alice...", "name": "Rare Pepe #1" }
// Transfer: Alice sends to Bob
{ "owner": "did:nostr:bob...", "name": "Rare Pepe #1" }
Each state advance produces a new Bitcoin TXO. The spend chain proves the transfer happened. Anyone can verify the current owner by replaying the state chain against the Bitcoin headers.
| Ethereum NFT | Blocktrail NFT | |
|---|---|---|
| Storage | Smart contract on Ethereum | State on pod, commitment on Bitcoin |
| Transfer | Contract call (gas fee) | State advance (Bitcoin tx fee) |
| Verification | Ethereum full node or Infura | SPV — Bitcoin headers only |
| Metadata | Usually IPFS or centralised | JSON-LD on your Solid pod |
| Cost | $5–$50 per transfer | ~$0.10 (one Bitcoin UTXO) |
The NFT metadata lives in your pod as a JSON-LD resource — the same format from Part 1. It's your data, on your server, with your ACLs. The ownership proof is on Bitcoin.
A smart contract is state that changes according to rules. Blocktrails handle the state. The rules live in your application:
// Escrow contract state
{
"type": "Escrow",
"seller": "did:nostr:alice...",
"buyer": "did:nostr:bob...",
"amount": 1000,
"status": "funded" // → "released" or "refunded"
}
The pod validates state transitions against the rules before advancing the blocktrail. Bitcoin proves the transitions happened in order. The client verifies both the state chain and the rules.
This is client-side validation — the same model RGB and Taro use, but without a new protocol. The rules are JavaScript. The state is JSON. The anchor is Bitcoin. The data lives on a Solid pod.
The git-mark profile anchors git commits to Bitcoin. The commit hash is the tweak. Each push advances the blocktrail. The result: a provable, tamper-evident code history anchored to the Bitcoin timechain.
git commit -m "Initial release" # → blocktrail advance, TXO on Bitcoin git commit -m "Fix security bug" # → blocktrail advance, new TXO
Anyone can verify that your git history hasn't been rewritten by checking the blocktrail against Bitcoin headers. Code audits become cryptographically verifiable.
Every example follows the same pattern:
| Application | State | Tweak | What Bitcoin Proves |
|---|---|---|---|
| Token (MRC20) | Balance | SHA256(state) | Transfer ordering |
| NFT | Ownership | SHA256(state) | Current owner |
| Escrow | Contract status | SHA256(state) | State transitions |
| Git | Commit hash | Commit hash | Code history |
| Anything | Any JSON | SHA256(state) | Ordering + integrity |
The last row is the point. Blocktrails anchor arbitrary state to Bitcoin. Tokens were the first use case because payments were the series topic. But the primitive is general-purpose.
Ten articles. One stack:
| Layer | What | Article |
|---|---|---|
| Data | Solid pod — JSON-LD resources, LDP CRUD | Part 1 |
| Access | Web Access Control — .acl files | Part 1 |
| Identity | Nostr key → did:nostr → NIP-98 | Part 2 |
| Payments | HTTP 402 + PaymentCondition | Parts 3–4 |
| Accounting | Webledger + TXO deposits | Part 5 |
| Anchoring | Blocktrails — key chaining on secp256k1 | Part 6 |
| Tokens | MRC20 — mint, transfer, withdraw | Part 7 |
| Multi-chain | Multiple Bitcoin networks + P2P trading | Part 8 |
| Exchange | AMM — constant-product market making | Part 9 |
| General | NFTs, contracts, git — any state | This article |
All of this runs on a single npm package. npm install -g javascript-solid-server. Eighteen thousand lines of JavaScript. Fifteen dependencies. Runs on a phone.
One secp256k1 key gives you: an identity (did:nostr), authentication (NIP-98), a payment address (taproot), a balance (webledger), provable state (blocktrails), and access to every feature in this series.
The web had a status code for payments since 1997. It had a standard for access control since 2012. It had decentralised identifiers since 2019. It had Nostr keys since 2020. It had blocktrails since 2025. It just needed someone to connect them.