the board · manual

spec

Everything plaintext is made of. No servers you have to trust for what matters: the names, the notices, and the prices all live on-chain. This page is the reference.

the contract

plaintext (ERC-721, symbol TXT)
address   0xC4bfCb7c103Ad4571D98b5F5bC9bc7b860023f5c
chain     Robinhood Chain — id 4663 (0x1237), an Arbitrum Orbit L2
gas token ETH
rpc       https://rpc.mainnet.chain.robinhood.com
explorer  https://robinhoodchain.blockscout.com/address/0xC4bfCb7c103Ad4571D98b5F5bC9bc7b860023f5c
treasury  gokhan.eth  0x36de990133D36d7E3DF9a820aA3eDE5a2320De71
feed      Chainlink ETH/USD  0x78F3556b67E17Df817D51Ef5a990cDaF09E8d3A9

read the contract on the explorer → · download the ABI (json)

prices

Fixed in US cents as constants, converted to ETH at call time via the Chainlink feed. There is no owner, no setter, no upgrade path — nobody can change these, including whoever deployed it.

the door, name dealt   $1.00    enter()
the door, name chosen  $5.00    enterAs(string name)
a notice               $3.00    post(string cid)
a remark               $0.50    reply(uint256 parent, string cid)
change your name       $5.00    rename(string name)
reading                free
a tip                  any      tip(uint256 id)   — 100% to the author

Listed addresses (the founder) write free — see the public exempt(address) map. Everyone else pays.

the on-chain API

enter()                          payable  take a dealt name
enterAs(string handle)           payable  take a chosen name
rename(string handle)            payable  trade your name for another
post(string cid)                 payable  publish a notice, mints you the token
reply(uint256 parent, string)    payable  a remark under a notice
tip(uint256 id)                  payable  pay a notice's author directly

nameOf(address)          -> string     your name
holderOfName(bytes32)    -> address    who holds keccak256(name)
exempt(address)          -> bool       writes free?
parentOf(uint256)        -> uint256    0 = top-level notice
tokenURI(uint256)        -> string     ipfs://<cid>
noticeWei() doorChosenWei() ...        current price in wei

events (for indexers)

Entered(address indexed hand, string name, bool chosen)
Renamed(address indexed hand, string oldName, string newName)
Posted (address indexed hand, uint256 indexed id, uint256 indexed parent, string cid)
Tipped (address indexed from, address indexed to, uint256 indexed id, uint256 amount)

The public RPC disables eth_subscribe; poll eth_getLogs (the 10k cap is on log count, not block range).

where writing lives

A notice's text is content-addressed with a real IPFS CID (v1, raw, sha2-256) and that hash is minted to you as the token. The bytes are served at /ipfs/<cid>; the same hash resolves on the public IPFS network once anyone pins it. The chain holds the CID and the ownership; this site renders a copy.

profiles (off-chain)

Bio and links are the one thing kept off-chain — they're editable, so they live in a database, not the immutable contract. You prove ownership to edit by signing a message with your wallet; the server recovers the signer and checks it is you. Names and notices stay the on-chain source of truth.

GET  /api/profile?address=0x…      read a profile
POST /api/profile                  {address, bio, website, x, github, telegram, ts, signature}

what is immutable vs not

on-chain, permanent   your name, your notices/remarks (as tokens), the prices, the exemption
off-chain, editable   your bio + links (signed), the rendered cache (rebuildable from chain)

the stack

contract   Solidity 0.8.28, OpenZeppelin ERC-721, on Robinhood Chain 4663
site       one Cloudflare Worker + D1 (a cache of on-chain events) + R2 (bodies)
read       zero JavaScript, one column, the UA serif — every page is a text file
write      /join — a small React app: sign in with a wallet or X, pay, publish

profile · enter · hands · manual · spec · feed · every notice is a token on chain 4663