Extension of the Ritual AI Bounty Judge workshop: a commit-reveal submission flow keeps answers hidden during the submission phase. Implemented on Ritual Testnet with Hardhat tests and a Next.js UI.
Workshop starter: cozfuttu/ritual-chain-workshop
Deployed contract (Ritual Testnet): 0x04e19459af2aa09ade09cc3063506fdb25e06654
| Component | Description |
|---|---|
| Solidity | submitCommitment + revealAnswer replace public submitAnswer |
| Deadlines | Submission deadline and reveal deadline per bounty |
| Judging | Only revealed submissions are eligible; one batch judgeAll LLM call |
| Web UI | Create → commit → reveal → judge → finalize (RainbowKit) |
| Tests | Seven automated cases in hardhat/test/AIJudge.ts |
[Commit] ──submissionDeadline──► [Reveal] ──revealDeadline──► [Judge] ──► [Finalize]
hash only plaintext on-chain batch LLM payout
- Create — Owner sets title, rubric, submission deadline, reveal deadline, and funds reward.
- Commit — Participants call
submitCommitment(bountyId, commitment)once before submission deadline. - Reveal — After submission deadline, participants call
revealAnswer(bountyId, answer, salt). - Judge — After reveal deadline, owner calls
judgeAll(bountyId, llmInput)(one Ritual LLM batch request). - Finalize — Owner calls
finalizeWinner(bountyId, winnerIndex); reward sent to revealed winner.
bytes32 commitment = keccak256(abi.encodePacked(answer, salt, msg.sender, bountyId));Binding msg.sender and bountyId prevents copying another participant's commitment.
| Field | Value |
|---|---|
| Network | Ritual Testnet |
| Chain ID | 1979 |
| RPC | https://rpc.ritualfoundation.org |
| Explorer | https://explorer.ritualfoundation.org |
| Contract | 0x04e19459af2aa09ade09cc3063506fdb25e06654 |
| Deploy tx | 0x0eb87b5bcade35be13ddc6f9e1e301ca0f03686d1f4ddfc09c23211ffc7a2c08 |
Deployment record: hardhat/deployments/ritual-testnet.json
cd hardhat
npm install
npx hardhat testcd web
npm install
cp .env.example .env.local
npm run devEnvironment variables (see web/.env.example):
NEXT_PUBLIC_CONTRACT_ADDRESS=0x04e19459af2aa09ade09cc3063506fdb25e06654
NEXT_PUBLIC_RITUAL_RPC_URL=https://rpc.ritualfoundation.org
NEXT_PUBLIC_RITUAL_CHAIN_ID=1979Connect Rainbow Wallet on Ritual Testnet (chain ID 1979).
cd hardhat
npm install
npx tsx scripts/deploy-ritual.tsSet DEPLOYER_PRIVATE_KEY in the environment. Do not commit private keys.
| Case | Expected |
|---|---|
| Valid commitment during submission phase | Stored; answer hidden |
| Second commitment from same address | Revert already committed |
| Valid reveal after submission deadline | Answer stored; revealed = true |
| Reveal with wrong salt | Revert invalid reveal |
| Reveal before submission deadline | Revert submission phase not ended |
judgeAll before reveal deadline |
Revert reveal phase not ended |
judgeAll with zero reveals |
Revert no revealed submissions |
End-to-end on Ritual Testnet: create bounty → commit → reveal → fund RitualWallet → judge → finalize.
| Aspect | Commit-reveal (implemented) | Ritual-native TEE (advanced) |
|---|---|---|
| On-chain during submission | Hash only | Encrypted blob / storage ref |
| Plaintext visibility | After reveal, before judging | Inside TEE until judging completes |
| Fairness | Blocks copying during submission | Hides answers through judging |
| Chain portability | Any EVM | Ritual precompiles / secrets |
| LLM input | Owner builds batch from revealed answers | TEE decrypts + one batch request |
Advanced design: Encrypt answers to a Ritual executor key; store ciphertext refs on-chain. judgeAll passes encrypted payloads into the LLM precompile; TEE decrypts privately and returns { winnerIndex, ranking, revealedAnswersRef, revealedAnswersHash }. The owner still finalizes payout.
In a fair bounty system, metadata should be public: bounty title, rubric, deadlines, reward, commitment hashes, and eventually the winner. Answers and salts must stay hidden during submission so late entrants cannot copy earlier work. After reveal, plaintext becomes visible on-chain in the commit-reveal model—acceptable for many EVM deployments, but Ritual TEE can keep plaintext private until judging finishes. AI should batch-rank all eligible submissions against the rubric and recommend a winner; it must not auto-pay or follow instructions embedded in submissions. A human owner should retain final payout authority to handle edge cases, disputes, or model mistakes. Commitments should bind to msg.sender and bountyId so one participant cannot steal another's reveal. Unrevealed commitments forfeit eligibility, incentivizing timely disclosure without exposing drafts early.
├── hardhat/
│ ├── contracts/AIJudge.sol
│ ├── test/AIJudge.ts
│ ├── scripts/deploy-ritual.ts
│ └── deployments/ritual-testnet.json
└── web/
Wallet connection via RainbowKit (Rainbow Wallet, MetaMask, WalletConnect).