-
-
Every hash is correct and the file is sealed, but invoice #12 shows 800 t of pig iron. RED.
-
Real code: the quote must be in the document and the number must be in the quote.
-
The CBAM default assumes a blast furnace: up to 18× more CO₂ than a scrap EAF plant.
-
Exporter screen: a cheat file goes red with the exact source line.
-
Verifier screen: every number with its source quote, every flag with its reason.
-
The cheat: the form says 0 t pig iron, the invoice says 800 t.
-
The AI must quote every number it reads. No quote, no number.
-
Verified carbon passport with a GS1 Digital Link QR code.
-
Trust layer: three EIP-712 signatures, approved model hashes and two Groth16 proofs.
-
Passport page: proven claims for everyone, the exact value only for the importer.
-
Every PDF is hashed into one Merkle root on Sepolia. Change one byte and the contract reverts.
-
Code, not AI: CBAM math and rules from EU BREF. An AI finding is never more than yellow.
-
Measured: 42/42 correct status, 93.3% injection catch rate, 0% false alarms, ~$0.0045 per file.
Inspiration
From 2026, every EU importer of steel pays for CBAM certificates. It can use a plant's real emissions only when an accredited verifier has checked them. Without verified data it must use the EU default value.
For Turkish rebar the default is 2.541 tCO₂/t in 2026 (2.310 plus the 10% mark-up, Implementing Regulation (EU) 2025/2621). That number assumes a blast furnace. But 72% of Turkish steel is made by melting scrap in electric arc furnaces. Our demo plant emits 0.143 tCO₂/t of direct emissions, about 18× less than the default.
So a clean scrap plant that cannot prove its number is charged as if it were a blast furnace. The gap is about €48–97 per tonne, or €0.5–1 million a year for a plant that sells 10,000 t to the EU. The bottleneck is verification: it is slow, it is paper-heavy, and the verifiers are few. We wanted to give the verifier a file that is fast to check and impossible to fake quietly.
What it does
Damga AI has three screens for three people:
- Exporter (the plant's export manager). Uploads the yearly CBAM form and the evidence PDFs (gas bills, electricity bills, purchase invoices, lab reports, production records). Damga AI reads every document, calculates the emissions, runs the checks, and seals the file on Ethereum Sepolia. The file gets a green, yellow or red status, and every finding points to the exact document and line.
- Verifier (the accredited human verifier). Sees the checked file: every number with its source quote, every flag with its reason. The verifier signs with EIP-712. The AI never approves anything; the human does.
- Passport (EU importer, customs, buyers). The smart contract checks three signatures and two zero-knowledge proofs, then issues a Digital Product Passport with a GS1 Digital Link QR code and a W3C Verifiable Credential. Anyone can see the proven claims ("direct emissions ≤ 0.200 tCO₂/t", "scrap share ≥ 90%") without seeing invoices or prices. The EU importer gets the exact value with a secret salt from the exporter.
Example from the demo: a plant says "scrap share 100%, pig iron 0 t". All document hashes are correct and the file is sealed on-chain. But invoice #12 shows 800 t of pig iron. Damga AI quotes that line and the file goes RED. Sealed is not the same as true.
How we built it
1. Every document is fingerprinted. Each PDF is turned into text and gets a SHA-256 hash. All hashes become one Merkle root (keccak, sorted pairs) stored on Sepolia. If one byte of one PDF changes later, the root does not match and the contract reverts with DocsChanged().
2. A prompt-injection guard runs before the main AI. A regex screen plus a small guard model (Jev 1.14) checks every document. Suspicious text is marked injection_screened and the file goes yellow. We tested the guard only on real public attack sets (Microsoft BIPIA, deepset, Lakera).
3. The AI must quote. MiMo v2.6 Flash extracts each number together with the exact sentence it was read from. Then plain code checks two things: the quote really is in the document, and the number really is in the quote. If either check fails, the number is thrown out. The AI cannot invent a value.
4. Code, not AI, makes the decisions. The CBAM math is plain Python:
CO₂ = gas × NCV × EF + (C_in − C_out) × 44/12.
The rules are code too:
material_balance— metal yield must be between 0.812 and 0.963 (EU BREF for iron and steel, Table 8.1), otherwise red;form_vs_docs— the form must match the bills within 2%, otherwise red;missing_evidence— all 12 monthly gas bills must be there;- an AI finding alone can never be more than yellow. Only code can make a file red.
5. The trust layer. Three keys sign with EIP-712: the plant (declaration), the AI service (attestation) and the verifier (approval). The AI can only attest; it can never mint a passport. The contract accepts only approved model hashes and ruleset hashes (UnapprovedModel, UnapprovedRuleset). Two Groth16 circuits written in Circom over Poseidon commitments prove "emissions ≤ limit" and "scrap share ≥ minimum". The contract checks every piece before it issues the passport. Every attempt, red ones too, stays on-chain.
Stack: Python + FastAPI backend, React + TypeScript + Vite frontend, Solidity + Foundry contracts on Ethereum Sepolia, Circom + snarkjs for the proofs, models through OpenRouter, and Docker on Google Cloud Run for the live demo.
Measured results
- 42 / 42 test files got the right status (honest, cheat, tampered, missing, injection cases).
- Prompt-injection guard: 93.3% caught on held-out public attack sets, 0% false alarms on honest documents.
- Cost: about $0.0045 per file; 9–33 seconds per file.
- 36 backend tests, Foundry contract tests and web tests.
scripts/verify.py --passport 2re-checks the real passport #2 on Sepolia with no API key and no private key: chain records, both ZK proofs, the Merkle root, the three signatures, and the emission math.
Track alignment
Sustainable Supply Chains — digital product passports and recycling traceability: the passport proves the scrap share and the carbon of a recycled-steel product along the supply chain. It also covers Carbon Markets & Emissions Transparency.
- Target users: export managers of Turkish scrap EAF steel plants, accredited CBAM verifiers, and EU importers and customs.
- Scale: Türkiye exported 7.9 Mt of steel to the EU in 2025 (40.7% of its steel exports), and 72.2% of its crude steel came from EAFs. On 2026-07-31 there was still no accredited CBAM verifier.
- Adoption: the plant uses a web page and needs no wallet (a relayer pays gas). The verifier signs with its own wallet. The importer only scans a QR code. New sectors are added as YAML sector packs.
Challenges we ran into
- LLMs are not deterministic, but a passport must be reproducible. We sign and store the AI output with its input hash and model version, and the checker replays only the code part, which always gives the same result hash.
- Hashes do not prove truth. A perfectly sealed file can still lie. That is why the rule engine compares the form with the documents and with physics (mass balance), and why a human verifier stays in the loop.
- Prompt injection inside invoices. A PDF can contain text that talks to the AI. We had to screen documents before extraction and cap what any AI finding can do.
- Privacy vs. proof. Buyers want proof, plants do not want to show prices. Zero-knowledge proofs solved it: the claims are public, the invoices are not.
- Gas. One honest passport costs about 7.96M gas on Sepolia (two Groth16 verifications plus signatures). An L2 is on the roadmap.
What we learned
- The safest place for AI is narrow: read and quote, never decide.
- Rules from official sources (EU BREF, the CBAM regulations) are stronger than any model's opinion.
- Honest limits make a demo more believable, not less.
Try it in 2 minutes
Live demo: https://damga-ai-690050774723.europe-west1.run.app
- Open Exporter and pick a cheat file: see the RED status and the quoted invoice line.
- Open Verifier for the same file: every number has its source quote.
- Open passport #2: https://damga-ai-690050774723.europe-west1.run.app/passport/2 . In the Importer View, paste this demo salt to see the exact value (0.143):
16731685818393394413049888552644868701242073587084459994005164083576283444767
The hosted demo runs with no keys: it replays the signed, precomputed AI results and does not send transactions, so it costs nothing and resets on restart. The real on-chain passport is #2 on Sepolia: DamgaRegistry, source verified on Sourcify.
Honest notes
- The invoices and plant data are synthetic. The plant (Aliağa Demo Steel Works) and the verifier (Demo Verification GmbH) are fictional. The official CBAM numbers and BREF ranges are real.
- The cheats are clear on purpose so they are easy to see in a short demo. A 1.5% gas gap is under the 2% tolerance and is not flagged.
- If the documents are false too, only the physics checks remain. This is why the human verifier and the site visit stay.
- The AI models are not European models; they run through OpenRouter.
- Damga AI does not replace the accredited verifier. It gives the verifier a checked, sealed and complete file.
What's next for DAMGA AI
The plant's verifier signs from its own wallet; Turkish e-Fatura (UBL XML) input; supplier passports for pig iron and DRI; more sectors as sector packs; an L2 to cut gas; a multisig owner; a random second check by an independent verifier. The same passport fields are ready for the coming EU Digital Product Passport for steel.
Built With
- circom
- docker
- eip-712
- ethereum
- ethers.js
- fastapi
- foundry
- google-cloud-run
- groth16
- gs1-digital-link
- jev
- mimo
- openrouter
- pydantic
- pypdf
- python
- react
- sepolia
- snarkjs
- solidity
- typescript
- vite
- w3c-verifiable-credentials
- web3.py
- zero-knowledge-proofs
Log in or sign up for Devpost to join the conversation.