-
-
Prove a credit was retired once, without publishing who retired it
-
11 real Verra projects: ICVCM methodology status (deterministic) and AI-assisted evidence checks
-
Report provenance: the browser re-hashes the published report and matches it to the on-chain version
-
Every “found” cites a paragraph of the project’s documents, with its page
-
Deterministic data checks: issued credits vs the documents’ own figures
-
Every anchored report version stays readable and checkable
-
Anyone can verify a retirement: the browser reads the Sepolia contract directly; the buyer stays sealed
-
The auditor opens the sealed identity, runs six checks and writes the result on-chain once
-
Assessor screen: add registry documents, re-run the checks, compare, publish and anchor
-
Where two models disagree, a person decides; both answers stay in the report
-
The problem: retirements explicitly marked “undisclosed” rose from 0.4% to 17% (our OffsetsDB count)
-
Replaying 38,382 real retirements: a linear scan breaks, the hinted list stays at constant gas
Inspiration
Two trends in the voluntary carbon market pull against each other. Buyers increasingly hide who retires credits: in CarbonPlan's OffsetsDB (495,403 retirements, 1.59 billion tonnes, seven registries), the share of retired tonnes explicitly marked "not disclosed", "anonymous" or "private" rose from 0.4% up to 2018 to 17.2% in 2023-2026, our own count and a conservative lower bound. At the same time the market needs proof that each credit is retired only once, and that quality claims rest on evidence rather than on a label.
Today a buyer gets either confidentiality or public proof. We wanted both: a public, one-time retirement record, a buyer identity that stays sealed but can be audited, and a quality signal that points to the exact paragraph it relies on.
What it does
OnceSealed is a prototype verification and privacy layer that could sit on top of existing registries such as Verra.
- Once: smart contracts to prevent double counting.
RetirementRegistryon Sepolia records retirements as serial ranges in standard lots and rejects any range that overlaps an earlier one. There is no transfer or mint function: retired credits never become tradable tokens, in line with Verra's 2022 ban on tokenizing retired credits. - Sealed: the buyer stays private but auditable. Only a salted commitment, bound to the retired range, goes on-chain:
$$ c = \mathrm{keccak256}\big(\mathrm{abi.encode}(\mathit{buyerId},\ \mathit{salt},\ \mathit{batchId},\ \mathit{start},\ \mathit{end})\big) $$
The buyer's LEI is encrypted to an auditor, who opens it, runs six checks and writes Verified or Rejected on-chain, once. The buyer's receipt allows selective disclosure: anyone can check it against the chain in the browser. This is a commitment-plus-encryption design, not zero-knowledge.
- Evidence-backed quality: blockchain-based carbon credit verification. For 11 real Verra projects the system reads the project description and the monitoring, validation and verification reports and answers 18 yes/no checks against five ICVCM Core Carbon Principles. Every "found" must cite a paragraph of the documents, a second model cross-checks each answer, and a team member decides where the two disagree (12 flagged: the person sided with the checklist model on 9, with the second model on 2, and left 1 open). Deterministic data checks compare the documents' own figures with the credits actually issued. The report's hash and the exact method (models, prompt, questions, excerpt rule) are anchored on-chain, and every version stays readable.
- Verify without trusting us. The public verify and report pages read the contract directly from the browser and re-hash the published files there; a shared test suite proves the browser computes exactly what the Python code computes.
What is real and what is simulated. Project data, issuance quantities, retirement histories and project
documents are real (CarbonPlan OffsetsDB, Verra registry). Serial numbers are simulated (labelled SIM-), buyers are
fictional companies with valid-format LEIs, and nothing is retired in a real registry. The quality score says how
well the documents evidence each principle; it is a signal, not an ICVCM assessment or a rating of the project.
How we built it
- Contract: Solidity 0.8.28 with Foundry and OpenZeppelin (
AccessControlDefaultAdminRules, two-step admin transfer). Our first design scanned every earlier retirement of a batch. Replaying the 38,382 real retirements of one Verra vintage, it hit the block gas limit at retirement 7,467. The final design keeps a sorted linked list with a caller-supplied hint, so each retirement costs a constant ~211k gas on a local chain however many came before. Verified on Etherscan, analysed with Slither, threat model T1-T13 in the repository. - Privacy: Python (
web3.py, PyNaCl sealed boxes, SQLite vault). One set of test vectors is checked by pytest, Foundry and the browser's own tests. - AI and data checks: PyMuPDF extraction with paragraph ids and tables;
deepseek-v4.1-flashfor the checklist and TypeSafejev-1.13as a second opinion, both third-party models through OpenRouter; a prompt-injection screen; deterministic comparisons with OffsetsDB issuance records. - App: FastAPI for the operator, auditor and assessor roles (local demo), Next.js 16 + viem for the public pages (hosted on Vercel).
- Measurement first: we labelled 177 checklist questions (a team member and an AI annotator, kappa 0.90, the team member settled every disagreement) and measured three models before choosing one: LLM 0.94 (95% CI 0.90-0.97), Jev 0.88, and Turnike-JEV-4B 0.86, a decision model built by a team member.
Challenges we ran into
- Gas on today's Sepolia is not gas on a local chain. New storage writes cost several times more after recent network upgrades (a retirement takes 1.02M gas instead of ~211k), and the deployment sits near the per-transaction gas cap. We report both measurements separately.
- Privacy leaks through metadata. Project plus amount singled out one retirement for 88.7% of retired tonnes. Standard lots and batched publication reduce that, but 14.5-36.8% of tonnes still have no crowd to hide in, and we say so.
- The excerpt mattered more than the model. On 2,500-character excerpts the checks missed evidence the documents contained. Reading 30,000 characters found 61 more answers; a blind check against length-matched decoy paragraphs confirmed 75% of them. When we added monitoring reports, they first crowded project-description evidence out of the excerpt, so each document type now gets its own budget.
- Documents can talk to the model. A planted "answer no" paragraph flipped 71% of right answers, so instruction-like paragraphs are screened out before any model reads the text (the screen flags 0 of 43,396 real paragraphs).
- Tables in PDFs mislead. Merged cells and component tables produced convincing but false alarms; the data checks now read only the columns they can identify and say "not available" rather than guess.
Accomplishments that we're proud of
- A complete loop on a public testnet: retire, audit, verify a receipt, all checkable from a browser.
- AI output that is measured, cited, cross-checked and versioned instead of asserted.
- Findings that line up with independent reviews: for Cordillera Azul (VCS985), whose rating BeZero lowered over its baseline, issuance is 1.72x the project description's projection, while the monitoring reports account for every issued credit, so the gap sits exactly where a contested baseline would show.
What we learned
This was our first blockchain hackathon. We learned that trust is built from things a stranger can re-check: a contract anyone can read, a hash anyone can recompute, a paragraph anyone can open. We learned to measure on the real network and real data before believing a number, because both the gas figures and the privacy figures changed once we did. And we learned that a model's accuracy figure is only as good as the excerpt it was measured on, so we now publish the excerpt rule with every report.
What's next
Integration with a registry's real serials and KYC, several auditors with key rotation, zero-knowledge proofs for selective disclosure, a held-out test set from new documents, and Turnike-Carbon, a model trained for this task.
Log in or sign up for Devpost to join the conversation.