Track alignment

Carbon Markets & Emissions Transparency. Ingot addresses this track's problem head-on: lack of transparency, double counting and complex verification in the EU's new carbon border market. It builds a blockchain-based verification of embedded emissions, smart contracts that prevent double counting, and transparent, checkable passports for every shipment. It also touches Sustainable Supply Chains, because precursor emissions flow from tier to tier.

Inspiration

On 1 January 2026 the EU's Carbon Border Adjustment Mechanism (CBAM) started charging importers for the carbon embedded in steel, aluminium, cement and fertiliser. Türkiye sold €10.8 billion of these goods to the EU in 2025, more than any country but China. About 70 % of Turkish steel is made from scrap in electric arc furnaces, yet without verified data the EU applies a default of 2.428 t CO2e per tonne of hot-rolled coil (2.671 with the 2026 mark-up), a figure that assumes blast furnaces. Turkish exporters have protested; verifiers are scarce; analysts already report that most third-country reports would fail verification. And nothing stops the same "green" tonnes being promised to two importers, or a re-roller passing on cleaner figures than the slabs it bought.

On default values, a mill that cuts its emissions saves its EU buyers nothing. We wanted to fix that.

What it does

Ingot takes a mill from its raw evidence to its buyer's customs declaration, in five steps:

  1. Evidence. Gemini reads Turkish gas invoices, an electricity statement, a production report and a pig iron delivery note, and returns every number with the exact line it was read from. A re-sent invoice stamped KOPYA is caught and left out.
  2. Calculate. A deterministic engine applies the EU's definitive-period methodology (Implementing Regulation 2025/2547): a carbon mass balance for the furnace, combustion for the reheating furnace, crude steel as the internal precursor. The pig iron's emissions are read from the smelter's verified statement on the ledger, not typed in. The demo mill comes out at 0.354 t CO2e/t instead of the 2.671 default; with the 2026 benchmarks, CBAM factor and the Q3 2026 certificate price (€82.32), its EU buyer pays about €99 less per tonne.
  3. Verify & record. An accredited verifier sees plausibility checks against EU BAT reference ranges and signs the statement twice: EIP-712 for the contract and ML-DSA-65 (post-quantum) for the long term. The mill records it on chain together with a Merkle root of the salted report fields, and the pig iron allocation it used is consumed.
  4. Ship. Each shipment takes tonnes from the statement and gets a passport: a W3C-shaped credential with the verifier's signature, the ledger anchor and the shared fields with Merkle proofs.
  5. Declare. The importer checks the passport against the ledger (signature, statement, allocation, precursors, disclosures) and surrenders it once in its CBAM declaration.

The registry contract keeps four doors shut: a tonne is verified once (no overlapping periods), sold once (no over-allocation, one allocation per customs reference), ends once (declared or consumed, never twice), and cannot be laundered: a downstream product must carry the embedded emissions of the verified precursors it consumed, which the contract recomputes from the upstream statements. Every step has Try to cheat buttons that send real transactions and show the contract's refusal.

How we built it

  • Smart contract: Solidity 0.8.34 with OpenZeppelin's EIP712, ECDSA and MerkleProof; custom errors for every rule; Hardhat 3 with viem and node:test (30 tests, including the correction path and a 60-step randomised allocation sequence), plus an independent review whose findings we fixed and documented.
  • In-browser EVM: the compiled bytecode runs on an ethereumjs EVM inside the page, with a journal replayed from local storage, so every judge gets a private chain with real execution, real signatures and real reverts, and no wallet.
  • On a public chain: the same bytecode is deployed on Ethereum Sepolia with its source verified (exact match on Sourcify, and on Blockscout). The demo was replayed there, including a double sale the contract refused on chain, and the passport page checks a passport against Sepolia live, through a public RPC node, from any browser.
  • CBAM engine: TypeScript, every factor, default value, benchmark and price in one table with its legal source (Reg. 2025/2547 Annex II.G, Reg. 2025/2621, Reg. 2025/2620, Directive 2003/87/EC Art. 10a, the Commission's price page).
  • AI: Google Gemini (gemini-3.8-flash) through the Google Gen AI SDK with a response schema, every answer re-checked with zod, file-type sniffing, size limits and rate limiting. The model only reads; it never computes. On the seven sample documents it read 29 of 29 lines exactly, every document number and the copy stamp, in 5 to 12 seconds per file.
  • Privacy: salted Merkle commitments of the report with a random 32-byte seed; selective disclosure verified off chain and on chain.
  • Post-quantum attestations: verifiers co-sign every statement id with ML-DSA-65 (FIPS 204, via @noble/post-quantum); the registry stores the hash of each verifier's ML-DSA public key, and the passport check requires both signatures, so passports stay checkable once ECDSA can be forged.
  • App: Next.js 16, React 19, Tailwind 4; Vitest (32 unit tests) and a Playwright walkthrough of the whole flow; deployed on Vercel.

Challenges we ran into

Getting the regulation right. Our first engine used textbook factors; the CBAM methodology wants a carbon mass balance for electric arc furnaces with its own standard factors (3.00 t CO2/t for electrodes, not 3.66), and the free allocation adjustment for actual data runs recursively through the precursors using column A benchmarks. We rebuilt the engine around the regulation's equations and checked every number against the Commission's published files. Designing the precursor rule so the contract could verify it with integer arithmetic, exactly as the browser computes it, was the other hard part.

Accomplishments that we're proud of

  • A contract rule no other carbon ledger we found has: carbon cannot be laundered downstream, even with a valid verifier signature.
  • Every number in the calculation traceable to a line in a Turkish invoice, and every factor to a legal source.
  • A live demo where a judge can try to cheat and watch the EVM refuse.
  • The same contract live on Ethereum Sepolia with verified source, where anyone can check a passport against the public chain in under a second.
  • AI reading that is measured, not assumed: 29 of 29 lines read exactly from Turkish invoices and reports.
  • Hybrid, quantum-ready attestations: ECDSA for the contract, ML-DSA-65 bound on chain for the long term.
  • An independent review of the contract and engine, with every finding fixed and documented in docs/security.md.

What we learned

CBAM embedded emissions are not a product carbon footprint: they follow EU ETS rules, count only direct emissions for steel, forbid green certificates for electricity, and price the free allocation through benchmarks. And a blockchain earns its place only where several organisations must agree on one count, here the count of verified tonnes as they are split between buyers and consumed by downstream mills.

What's next for Ingot

A pilot with one Turkish EAF mill, its EU buyers and an EU-accredited verifier through a chamber of industry; a permissioned EVM network run by chambers and verifiers; export to the EU CBAM Registry's operator module; engines for aluminium, cement and fertiliser; and zero-knowledge range proofs so tonnages can stay private even on a public chain.

Built With

  • blockscout
  • eip-712
  • ethereum
  • google-gemini
  • hardhat
  • merkle-tree
  • ml-dsa
  • next.js
  • openzeppelin
  • playwright
  • post-quantum-cryptography
  • react
  • sepolia
  • solidity
  • sourcify
  • tailwindcss
  • typescript
  • vercel
  • viem
  • vitest
  • zod
Share this project:

Updates

Submission history