Documentation
How this works, and what it isn't.
the cat experiment is one picture of a cat, cut into 1000 visible squares, sold one square at a time to one wallet at a time. Everything below is the whole mechanism — there is no second layer of cleverness underneath it.
The picture
The picture is a 40 × 25 lattice — exactly 1000 squares, no remainder. The whole cat is on the homepage from the start, assembled from those squares, with a hairline grid so each cell reads as a piece. /api/mosaic serves the assembled image; /api/tile/:id serves any single square, owned or not. Buying a piece does not uncover it — it is already visible. Buying records that you hold that square.
Selling your piece does not hide it. The picture is the picture; only the names on the squares change.
The price
Issue price is a step function of how many pieces have already sold. It is computed on the server when you reserve, never sent up from the browser, and it never goes down. Open reservations count toward the total, so two people racing for the last piece of a tier do not both get the cheaper one.
| Pieces | Price | Tier raises |
|---|---|---|
| 1–100 | 0.02 ETH | 2 ETH |
| 101–250 | 0.035 ETH | 5.25 ETH |
| 251–450 | 0.06 ETH | 12 ETH |
| 451–650 | 0.1 ETH | 20 ETH |
| 651–850 | 0.16 ETH | 32 ETH |
| 851–980 | 0.25 ETH | 32.5 ETH |
| 981–1000 | 0.4 ETH | 8 ETH |
If every piece sells, the primary issue raises 111.75 ETH. Secondary sales take no fee at all — the buyer pays the seller directly and nothing is skimmed in between.
One piece per wallet
This is enforced by a unique index on the owner column, not by the application remembering to check. A wallet that holds a piece cannot buy another until it parts with the one it has — the write simply fails.
It is worth being precise about what this does and does not do. It guarantees that the board shows 1000 distinct wallets when it is full. It does not guarantee 1000 distinct people. Anybody willing to fund a second wallet can hold a second piece, and there is no way to prevent that without asking who you are, which would be worse. The rule is a shape imposed on the game, not an identity system.
The market
Because holders cannot accumulate, one primitive is not enough. There are three.
- listing
- The holder names a price. Anybody holding nothing can pay it. The ETH goes from buyer to seller directly; the server verifies the transfer and moves the row. Listing and withdrawing are signatures, not transactions — they cost nothing.
- offer
- Anybody holding nothing bids on a specific piece. Nothing is escrowed, because there is no program to escrow it — an offer is an invitation, and the holder accepting it does not oblige the bidder to pay. This is written into the message your wallet shows you when you sign.
- swap
- Two holders trade squares. Since no ETH changes hands, no transaction is needed at all: both parties sign a message, the server checks both signatures and both still hold what they claim, and the two rows cross inside one database transaction. Free, and instant.
Read this part
What is on chain, and what is not
Sites like this one tend to be vague here. Being specific. This implementation settles payments in native ETH on Robinhood Chain — an EVM L2. A remake of the experiment can settle on any chain; this site’s payments are Robinhood ETH.
- on chain
- Every payment. Buying a piece at issue, buying a listing and paying an accepted offer are all plain native ETH transfers on Robinhood Chain, signed by you, from your wallet, to the treasury or to the seller. There is no approval step and no contract that can move funds later.
- off chain
- Ownership. Who holds which piece lives in a Postgres database that we run. There is no token, no NFT and no mint — your piece is a row, not an asset in your wallet.
- how they're bound
- A purchase reserves the piece and issues a one-time 32-byte reference. Your transfer writes that reference into the transaction
datafield. The server then fetches the transaction, confirmsfromis your wallet,tois the payee,valueis at least the invoice amount,inputequals the reference, and stores the transaction hash under a unique index so the same payment can never be used twice. - what this means
- You can prove you paid — the transaction is public and permanent. You cannot independently prove you own a piece, because ownership is our record. If this site disappears, your payment remains on chain and your piece does not. That is the trade you are making, and it is the honest reason this was not built as an NFT collection: doing it properly on chain means a custom contract and an audit, and doing it improperly on chain would be worse than being straightforward about a database.
- what we can do
- Everything. We could edit the ledger. The mitigation is that the whole thing is readable — every piece, every event and every transaction signature is public at
/api/v1, so an altered row is checkable against the chain by anyone who cares to look.
When things go wrong
- paid, nothing happened
- The claim step retries for half a minute, because the RPC that serves
eth_getTransactionByHashcan lag confirmation. Your reservation stays valid for ten minutes — reload the piece page and it will settle. The signature is the receipt either way. - two people, one piece
- Impossible to lose money to. A piece can only have one open reservation, enforced by a partial unique index, so the second buyer is refused before they are ever asked to pay.
- the seller sold first
- An accepted offer or a listing can go stale if the holder moves the piece elsewhere first. The claim re-checks who holds the piece under a row lock and refuses rather than taking your money for a piece that has left.
- expiry
- Reservations last 10 minutes, offers 7 days, swaps 7 days, listings 30 days. Anything past its expiry is swept before the board is read, so nothing stale is ever shown as live.
This is unaudited, experimental software handling real money on mainnet. Read the API docs if you would rather verify than trust.