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.

This site is a static front end. There is no server and no database. Everything is read from, and written to, the contract at on GenLayer Studionet.

Quick start

  1. Press Connect wallet. Every installed wallet is listed by name (EIP-6963).
  2. 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.
  3. Open My Plinth and press Get 100 test GEN.
  4. Open a slot, write a message, choose a secret price and press Lock deposit and bid.
  5. 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.
  6. 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.

PhaseWhat happensActions
BidAnyone except the curator and the beneficiary locks a deposit and a sealed price.Place bids
ReviewThe AI gate reads each message. The curator may clear or veto.Screen, escalate, appeal, clear, veto
RevealCleared bidders show price and salt.Reveal
SettleWinner is picked, refunds are paid. The winner's price waits in escrow.Settle
DisplayThe 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:

StateMeaning
WaitingNot read yet.
ClearedEvery rule met. The bid may reveal.
UnsureThe gate could not decide, or no read was agreed. Only the curator can clear it, before the review ends; otherwise the bid is out.
RefusedA rule is broken or the tripwire fired. The bidder may appeal once; an appeal only leads to “unsure”.
VetoedThe 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 release pays the beneficiary. A takedown returns the unused part to the winner.
  • Solvency. solvency() must always say balanced: 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 0x

The salt has 8–64 characters from A-Z a-z 0-9 . _ ~ -.

Roles

RolePowers
CuratorOpens the slot, writes rules, clears or vetoes in review, takes a display down, pauses, changes the beneficiary. Cannot bid and cannot touch money otherwise.
BeneficiaryReceives the prices. Defaults to the curator. Cannot bid.
BidderBids, appeals, reveals.
AnyoneAsks the gate, escalates, settles, releases.

Contract: write methods

MethodArgumentsWhoNotes
create_slotname, rules, max_bid, reserve, hold_secs, bid_secs, review_secs, reveal_secs, forfeit_bps, beneficiaryAnyoneOpens a slot. Rules are 1–5 sentences joined with |. Prices in wei, at least 0.001 GEN; the reserve cannot exceed max_bid.
set_pausedslot_id, pausedCuratorStops or allows new bids. A running round always finishes.
set_beneficiaryslot_id, whoCuratorWho receives prices of rounds opened from now on. Empty means the curator.
bidslot_id, creative, link, commitmentBidder · payableAttach exactly max_bid. Not allowed for the curator or the beneficiary. The first bid after a round ends opens the next round.
screenbid_idAnyoneRuns the AI gate on a waiting bid during review. All rules met → cleared; any broken → refused; otherwise unsure.
escalatebid_idAnyoneAfter half of the review phase, hands an unread bid to the curator (state: unsure).
appealbid_id, noteBidderOne appeal of a refusal during review. It can only move the bid to unsure.
clearbid_idCuratorClears an unsure bid.
vetobid_id, noteCuratorRemoves a waiting, cleared or unsure bid during review. The deposit is refunded in full.
revealbid_id, amount, saltBidderDuring reveal, for a cleared bid. Must match the commitment.
settleslot_idAnyoneAfter the reveal phase. Picks the winner, charges the second price, refunds the rest.
releaseround_idAnyonePays the price to the beneficiary after the display ended.
takedownround_id, noteCuratorEnds a display early. The unused part of the price returns to the winner.

Contract: view methods

MethodReturns
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:announceProvider and sends eip6963:requestProvider. It never touches window.ethereum.
  • Connect. eth_requestAccounts on the wallet you pick. The choice is remembered and re-connected silently with eth_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_switchEthereumChain to 0xf22f; when the wallet does not know it, wallet_addEthereumChain adds “GenLayer Studionet”.
SettingValue
Network nameGenLayer Studionet
Chain id61999 (0xf22f)
RPChttps://studio.genlayer.com/api
CurrencyGEN (18 decimals)
Explorerhttps://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 8080

Host 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.