Documentation
Everything about Plinth, from the first bid to the contract methods.
Overview
Plinth sells one public slot, a short message on a wall, to the highest sealed bid. Each slot has a curator who writes plain rules. A message may stand on the pedestal only when an AI gate agrees that it follows every rule.
The model reads words only. It never sees a price, so money cannot influence a verdict. The winner pays the second-highest price, which makes the honest price the best price.
on GenLayer Studionet.Quick start
- Press Connect wallet. Every installed wallet is listed by name (EIP-6963).
- If your wallet is on another network, a banner offers Switch network. The wallet is asked to switch to GenLayer Studionet (chain id 61999) and to add it when it is missing.
- Open My Plinth and press Get 100 test GEN.
- Open a slot, write a message, choose a secret price and press Lock deposit and bid.
- After the bid phase, press Ask the AI gate on your bid. When it is cleared, come back in the reveal phase and press Reveal my price.
- When the reveal phase is over, anyone can press Settle this round.
To test fast, create a slot and use Fill a quick test slot: phases of 2, 3 and 2 minutes.
Round lifecycle
A round is told apart by the clock of the chain, shown on every slot page.
| Phase | What happens | Actions |
|---|---|---|
| Bid | Anyone except the curator and the beneficiary locks a deposit and a sealed price. | Place bids |
| Review | The AI gate reads each message. The curator may clear or veto. | Screen, escalate, appeal, clear, veto |
| Reveal | Cleared bidders show price and salt. | Reveal |
| Settle | Winner is picked, refunds are paid. The winner's price waits in escrow. | Settle |
| Display | The winning message stands for the display time. | Release (after), takedown (curator) |
The first bid after a round ends opens the next one. A new round can open when the display time of the previous winner has run out, shortened by one round length.
The AI gate
The gate gets the slot's rules and the message. Every rule gets a mark: 0 met, 1 unsure, 2 broken. The marks become a gate state:
| State | Meaning |
|---|---|
| Waiting | Not read yet. |
| Cleared | Every rule met. The bid may reveal. |
| Unsure | The gate could not decide, or no read was agreed. Only the curator can clear it, before the review ends; otherwise the bid is out. |
| Refused | A rule is broken or the tripwire fired. The bidder may appeal once; an appeal only leads to “unsure”. |
| Vetoed | The curator said no. The deposit comes back in full. |
Validators agree on the same state
A read is stored only when the validators reach the same gate state as the leader. A validator that gets a different verdict does not accept the leader's result, so an “unsure” cannot be forced through when a validator would have cleared the message.
Tripwire
A message that tries to instruct the gate (“ignore the rules…”) is refused without asking the model.
Money
- Deposit. Every bid locks the slot's highest allowed price, whatever the secret price is. Nobody can read your price from the amount.
- Second price. The highest revealed price wins (earlier bid on a tie) and pays the second-highest revealed price, or the reserve when it is alone.
- Refunds. Every deposit goes back except the winner's price and the forfeit of cleared bids that never revealed (the slot's forfeit percentage).
- Escrow. The price waits until the display ends. Then
releasepays the beneficiary. Atakedownreturns the unused part to the winner. - Solvency.
solvency()must always saybalanced: true. The home page shows it.
Sealed commitment
The chain stores only the hash. The site computes it in your browser and keeps price and salt in localStorage. Export a backup on My Plinth.
import { keccak256, toHex } from "viem";
const text = `plinth:${slotId}:${bidder.toLowerCase()}:${priceWei}:${salt}`;
const commitment = keccak256(toHex(text)).slice(2); // 64 hex digits, no 0xThe salt has 8–64 characters from A-Z a-z 0-9 . _ ~ -.
Roles
| Role | Powers |
|---|---|
| Curator | Opens the slot, writes rules, clears or vetoes in review, takes a display down, pauses, changes the beneficiary. Cannot bid and cannot touch money otherwise. |
| Beneficiary | Receives the prices. Defaults to the curator. Cannot bid. |
| Bidder | Bids, appeals, reveals. |
| Anyone | Asks the gate, escalates, settles, releases. |
Contract: write methods
| Method | Arguments | Who | Notes |
|---|---|---|---|
create_slot | name, rules, max_bid, reserve, hold_secs, bid_secs, review_secs, reveal_secs, forfeit_bps, beneficiary | Anyone | Opens a slot. Rules are 1–5 sentences joined with |. Prices in wei, at least 0.001 GEN; the reserve cannot exceed max_bid. |
set_paused | slot_id, paused | Curator | Stops or allows new bids. A running round always finishes. |
set_beneficiary | slot_id, who | Curator | Who receives prices of rounds opened from now on. Empty means the curator. |
bid | slot_id, creative, link, commitment | Bidder · payable | Attach exactly max_bid. Not allowed for the curator or the beneficiary. The first bid after a round ends opens the next round. |
screen | bid_id | Anyone | Runs the AI gate on a waiting bid during review. All rules met → cleared; any broken → refused; otherwise unsure. |
escalate | bid_id | Anyone | After half of the review phase, hands an unread bid to the curator (state: unsure). |
appeal | bid_id, note | Bidder | One appeal of a refusal during review. It can only move the bid to unsure. |
clear | bid_id | Curator | Clears an unsure bid. |
veto | bid_id, note | Curator | Removes a waiting, cleared or unsure bid during review. The deposit is refunded in full. |
reveal | bid_id, amount, salt | Bidder | During reveal, for a cleared bid. Must match the commitment. |
settle | slot_id | Anyone | After the reveal phase. Picks the winner, charges the second price, refunds the rest. |
release | round_id | Anyone | Pays the price to the beneficiary after the display ended. |
takedown | round_id, note | Curator | Ends a display early. The unused part of the price returns to the winner. |
Contract: view methods
| Method | Returns |
|---|---|
stats() | Counters: slots, rounds, bids, settled, void, takedowns, reads, volume, forfeits, deposited, paid. |
solvency() | Deposited, paid, held deposits, held escrow, and balanced. |
get_slot(slot_id) · list_slots(offset, limit) · slots_of(who, offset, limit) | One slot, a page of slots (50 max), or the slots of a curator. |
get_round(round_id) · rounds_of(slot_id, offset, limit) | One round, or the rounds of a slot, newest first. |
get_bid(bid_id) · bids_of_round(round_id, offset, limit) · bids_of(who, offset, limit) | One bid, the bids of a round in order, or the bids of an address. |
current(slot_id) | What is on display right now. |
status(slot_id) | Phase, deadline of the phase, can_bid, and the chain's own now. |
commitment_for(slot_id, bidder, amount, salt) | Computes a commitment. Compute it yourself in the browser instead; the site does. |
Views return JSON text. The site parses it.
Wallet and network
- Discovery. The site listens for
eip6963:announceProviderand sendseip6963:requestProvider. It never toucheswindow.ethereum. - Connect.
eth_requestAccountson the wallet you pick. The choice is remembered and re-connected silently witheth_accounts. - Disconnect. The button asks the wallet to revoke the permission (
wallet_revokePermissions), forgets the account and stops listening. Wallets that cannot revoke are simply forgotten by the site. - Network.
wallet_switchEthereumChainto0xf22f; when the wallet does not know it,wallet_addEthereumChainadds “GenLayer Studionet”.
| Setting | Value |
|---|---|
| Network name | GenLayer Studionet |
| Chain id | 61999 (0xf22f) |
| RPC | https://studio.genlayer.com/api |
| Currency | GEN (18 decimals) |
| Explorer | https://explorer-studio.genlayer.com |
| Contract | |
| Deploy transaction | |
Troubleshooting
- “Wrong network” banner. Press Switch network, or add the network by hand with the values above.
- A call takes minutes. AI-gated calls go through validator consensus. The spinner stays until the transaction is accepted.
- “The AI gate gave no usable answer”. Try again later. After half of the review phase anyone may hand the bid to the curator.
- I lost my price and salt. Import your backup. Without them a bid cannot reveal.
- Empty lists. The contract at the address above has no data yet, or the RPC is busy. Reload.
Run and deploy the site
The folder is plain static files with ES modules. Browsers block modules on file://, so serve it:
npx serve . # or: python3 -m http.server 8080Host it on any static host (Cloudflare Pages, GitHub Pages, Netlify). After a redeploy of the contract, change CONTRACT in js/core.js; nothing else refers to it.
FAQ
Can the curator steal a bid?
No. The curator can refuse messages, never move money, except ending a display early, which returns the unused part to the winner.
Why a fixed deposit?
If the deposit followed the price, it would leak the price.
Can I see other prices?
Only after they are revealed.
Is this real money?
No. Studionet GEN is test money.