Inspiration
Carbon markets promise climate action, but trust has collapsed. Credits get counted twice, projects exist only on paper, and a buyer cannot check what happened to a tonne after they paid for it. Most "blockchain carbon" tools put a token on top of the same paper claim.
I build IoT hardware, and in India many small solar, biochar and clean-cooking projects cannot sell credits because verification is slow and costly. I asked a simple question: what if the proof came from the physical world, from a meter that signs every reading, instead of from a PDF? That became TerraProof: every tonne, proven, from sensor to retirement.
What it does
TerraProof is a carbon credit marketplace where every credit carries a proof trail.
- Sellers list a project in one form. The server blocks duplicates by fingerprint and by registry cross-check, then two of three independent auditors must approve before any credit exists (lock-then-mint).
- Auditors review projects in a portal with meter and photo evidence. Approval is paused automatically while a linked meter shows an anomaly.
- Buyers browse a world map (search any place, drop a pin, see the nearest sellers), compare each credit on a five-axis quality radar, see exactly where their money goes, pay with UPI, card or net banking, and retire credits to get a certificate with a QR code and a public proof link.
- Real ESP32 meters sign every reading with a secure element and chain them together. Readings stream live to the seller's dashboard.
- Everyday tools: a footprint calculator, one-click offset bundles, monthly auto-offset, a watchlist with alerts, an embeddable "offset this order" widget, 13 currencies, English and Hindi, and a compliance export.
How the math works
Credits issued from measured data:
$$C=\frac{E_{base}-E_{project}-E_{leak}}{1000}\ \text{tCO}_2\text{e}$$
Avoided emissions from a solar meter, with an assumed grid factor $EF = 0.82$ kg/kWh:
$$E_{avoided}=\text{kWh}\times EF$$
Credit fingerprint (blocks double counting): a mint is rejected if $F$ already exists.
$$F=\text{SHA-256}(\text{name}\,|\,\text{lat}\,|\,\text{lon}\,|\,\text{vintage}\,|\,\text{type})$$
Integrity score from additionality ($A$), permanence ($P$), leakage control ($L$), sensor coverage ($M$) and auditor trust ($V$):
$$S=\frac{A+P+L+M+V}{5}$$
Tamper-evident meter chain, where each reading is signed with ECDSA (P-256) by the secure element:
$$h_n=\text{SHA-256}(\text{id}\,|\,t_n\,|\,\text{kWh}n\,|\,h{n-1})$$
Anomaly rule: a reading is flagged if $P=\dfrac{\Delta\text{kWh}}{\Delta t}>80$ kW, if the counter goes backwards, or if the last ten increments are identical (flat line or copy-paste).
Where each sale goes: 83.5% seller, 8% community fund, 5% buffer pool for reversals, 2% platform, 1.5% verifiers.
Nearest sellers use the haversine distance:
$$d=2R\arcsin\sqrt{\sin^2!\tfrac{\Delta\varphi}{2}+\cos\varphi_1\cos\varphi_2\sin^2!\tfrac{\Delta\lambda}{2}}$$
How I built it
- Frontend: a single-file web app (HTML, CSS, JavaScript) with SVG charts, a built-in world map, and optional Leaflet and OpenStreetMap tiles. It runs as an offline demo and switches to server mode when served by the backend.
- Backend: FastAPI and SQLAlchemy (SQLite or Postgres). It handles scrypt password hashing, JWT sessions, roles (buyer, seller, auditor, admin), the 2-of-3 audit logic, a hash-chained ledger, Razorpay checkout with signature verification, signed telemetry over HTTP or MQTT, and a WebSocket live feed.
- Smart contract: an ERC-1155 registry in Solidity (OpenZeppelin) with unique fingerprints, unique registry references, auditor consensus minting, a 5% buffer pool, flag and freeze, and burn-on-retire. It is tested with Hardhat, and a deploy script is ready for Polygon Amoy or Sepolia.
- Hardware: an ESP32-S3 meter node with a PZEM-004T energy sensor, an ATECC608A secure element, a DS3231 clock and a tamper switch. Its firmware signs and chains readings and publishes them to MQTT.
- Testing: 26 contract tests, 30 backend API tests, and end-to-end runs in a headless browser against a live server. One run used a real P-256 signature from a script in place of the ESP32.
Challenges I ran into
- Making "proof" more than a label. A hash on a screen proves nothing, so I tied credits to signed meter data and made the server reject replays, chain gaps and impossible output.
- Double counting without a central registry. I combined a fingerprint, a registry cross-check and lock-then-mint, so credits only exist after auditors sign.
- Device-to-server details. The signed message is about 280 bytes, which silently exceeds the default MQTT buffer. The signature format also had to match between the secure element and the Python verifier.
- Keeping it usable. A village solar owner and a corporate buyer need very different screens, so I added guided steps, UPI checkout, currencies and Hindi.
- Honest scope. Some parts are still simulated, and I wanted the demo to say so clearly rather than overclaim.
Accomplishments I'm proud of
A complete flow that works end to end: list, audit, mint, buy, retire, verify. It includes a visible double-listing block, an auditor portal, a live meter feed that flags tampering, and a certificate anyone can check.
What I learned
Trust in carbon markets is a data-quality problem more than a token problem. Measurement, reporting and verification (MRV) has to be digital, signed and checkable by strangers. I also learned how much unglamorous detail sits between "the idea works" and "the system works": buffer sizes, signature encodings, race conditions on the last tonnes, and account deletion that does not break financial records.
What's next
- Deploy the contract to a testnet and have auditor approvals mint on-chain (today the backend keeps credits in its database).
- Replace the simulated satellite check and registry cross-check with real Sentinel-2 and Verra or Gold Standard data.
- Run the ESP32 meter on a real solar installation and test with a live MQTT broker.
- Unify fingerprint hashing (SHA-256 in the app, keccak256 on-chain), add real KYC and email delivery, and get a security audit before handling real money.
Built With
- arduino
- chainlink
- chart.js
- css3
- docker
- esp32
- ethers.js
- fastapi
- github
- hardhat
- html5
- ipfs
- javascript
- leaflet.js
- mqtt
- openzeppelin
- polygon
- postgresql
- python
- react
- sha-256
- solidity
- tailwindcss
- vercel
- web-crypto-api
Log in or sign up for Devpost to join the conversation.