All posts

Holy Mary Chain: a small blockchain for proving you were here

Why I built a Cosmos SDK chain to record who visited a shared XR space, how its three modules worked, and what was still unfinished when I retired it.

The previous version of this site had a shared XR space: visitors picked a name and an avatar, walked around, saw each other in real time and left notes behind. Underneath it ran Holy Mary Chain (HMC), a sovereign Layer 1 blockchain I built with Cosmos SDK and CometBFT. It produced a block roughly every five seconds and had its own native coin, uhmc.

The XR space is gone now, and HMC with it. This is a write-up of what it was, how it worked, and what I’d left unfinished.

Why a blockchain at all

Mostly curiosity, honestly. But there was a real idea underneath it.

With a normal database, I (or anyone with the password) could edit a row, backdate it, delete it, or invent a visit that never happened, and you’d have no way to prove otherwise. On HMC, entering the space was a transaction signed by a wallet generated in your browser and written to a ledger whose history can’t be quietly rewritten. “I was here on this date” became something anyone could check without having to trust me, the person running the site.

To be fair to the boring option: for a presence toy, a plain database covers most of this. What earned the chain its place was that one property, provable without trusting the operator, plus the fact that a working Layer 1 with custom modules is a genuinely hard and fun thing to build.

Deliberately worthless

HMC had no price, wasn’t for sale and wasn’t listed anywhere. Tokens came free from a faucet and had no cash value: closer to arcade tokens than money. That was a design decision, not a missing feature. The moment a token can be bought and sold, it walks into financial regulation that a personal project has no business being in.

How it was built

Cosmos SDK is to blockchains roughly what a web framework is to websites: it handles consensus, networking and transaction signing, so you write only the logic specific to your chain. HMC had three custom modules:

  • spark handled MsgIgnite, a transfer that burned 0.5% of every amount sent.
  • burn was an on-chain registry for that burn rate, meant to become governance-controlled.
  • presence was the one the XR space talked to. MsgEnterSpace and MsgLeaveSpace recorded a signed, timestamped event each time someone entered or left, with their position and display name.

Accounts, staking, governance and IBC came straight from the SDK’s standard modules. I didn’t need to reinvent account management or peer-to-peer networking.

The XR space used it like this:

Visitor opens the XR space
  → a CosmJS wallet is generated in the browser (or restored from localStorage)
  → MsgEnterSpace is signed and broadcast to the node's RPC endpoint
  → the transaction is confirmed on-chain
  → everyone in the space sees "HMC live · attested" in the header

No server of mine decided who had been in the room. The chain did, and anyone could query it.

What was unfinished

I tried to be honest about this while it ran, and it’s worth repeating now:

  • One validator. HMC ran on a single node I operated on a Hetzner server. Decentralized software, but not yet a decentralized network.
  • Events, not state. Entering and leaving emitted verifiable events, but the chain didn’t keep queryable state like “who is in this room right now”. The live presence list came from the XR space’s WebSocket layer; the chain was the attestation record underneath it.
  • Partial governance. The burn rate was still a hard-coded constant in spark rather than something adjustable through on-chain governance.
  • Hands-on operations. I maintained the node over SSH, with no automated deploys.