Inspiration

I live in a village in Andhra Pradesh, close to the Nallamala hills. Andhra Pradesh has some of India's largest dry forests, like Nallamala and Seshachalam, so forests are not an abstract idea for me.

When I started reading about forest carbon credits, I expected some kind of check that the forest is really there. What I found was that a company can pay for a forest it will never visit, and the proof it gets is a report. Researchers who went through more than 2,300 carbon projects found that fewer than 16% of the credits matched real emission cuts, and forest-protection projects delivered only about a quarter of what they claimed (Probst et al., Nature Communications, 2024).

Free satellite pictures already cover every forest on Earth every few days. Blockchains are good at refusing to break their own rules. I wanted to see what happens if you put those two together.

The problem

Three things keep going wrong with forest credits:

  1. Nobody checks the forest. It can be smaller than claimed, or partly cut, and the buyer has no way to know.
  2. The same land gets sold twice. Two projects with overlapping maps can both sell credits for the same trees.
  3. Nobody can repeat the math. The numbers live in a PDF, not in something anyone can run again.

What it does

GroveProof checks a forest from space before any credits can exist, and then keeps the record honest.

  • Check a forest. Pick a sample forest, search any place, or draw your own area. The checker downloads Sentinel-2 pictures from the same months one year apart, removes clouds, maps forest pixel by pixel and measures tree loss. You get one answer: Verified, Needs review, Not eligible, Already claimed, or Can't check yet. Every number has a "how was this calculated" view.
  • Create credits. Only a Verified forest can become credits, and never more than the satellites allow. The smart contract enforces this, not the website.
  • No double counting. The land is stored on-chain as small hexagon map cells. If a new project touches a cell that already belongs to another project, the contract refuses it.
  • Buy and retire. Credits can be bought on the marketplace and retired. Retiring burns them and creates a certificate (R-1, R-2...) with a QR code that anyone can look up.
  • Re-run any check. The exact recipe of each check (scenes, dates, rules, model) is fingerprinted on-chain. Pressing "Re-run" downloads the same pictures and has to produce the same fingerprint.
  • Try to cheat. Each project page has five buttons that try to break the rules (retire twice, create too many, claim used land, buy from a frozen forest, fake the verifier). Each one goes to the real contract and gets refused, with the reason in plain words.

Who it is for

  • Companies buying credits that want to see the forest and the math, not a PDF.
  • Forest owners and village communities who protect a forest and want a cheap, quick way to show it is still standing.
  • Verifiers and registries who could use it as a first screen before sending people into the field.
  • Journalists, students and anyone curious, because every check and every credit can be looked up without an account or a wallet.

How it works

How GroveProof works

  1. Forest boundary. A sample forest or an area drawn on the map, plus the dates to compare.
  2. Map cells. The area is split into H3 hexagons (about 0.1 km² each).
  3. Already claimed? The smart contract checks those cells. If any belongs to another project, the answer is "Already claimed" and nothing else happens.
  4. Satellite checker. Sentinel-2 pictures from the same months one year apart, clouds removed. A Random Forest model I trained maps forest in every 10 m pixel (93.1% accuracy on held-out pixels). Tree loss is counted where forest disappears, or where greenness or moisture drops sharply.
  5. Verdict and credits. Fixed rules in a fixed order decide the verdict, so weak evidence can never become Verified. Credits use IPCC default factors and then hold back 20 to 35% for uncertainty plus a 10% buffer.
  6. Language model. It only writes the plain-language summary. If it writes any number that isn't in the result, its text is thrown away.
  7. Polygon smart contract. Stores the verdict, the credit limit and the fingerprints of the recipe and the result.

From there: the credit passport and map, the marketplace (buy, retire, certificate), and re-run or re-check. If a later check finds 5% or more of the forest gone, the contract freezes the credits that haven't been retired yet.

Worked example (Nallamala hills): 246.5 ha of forest now, 0% loss, 100% seen clearly, so Verified. 246.5 ha × 1.5 t growth × 1.28 (roots) × 0.47 carbon × 44/12 = 815.6 t CO₂ a year. After 25% for uncertainty and 10% buffer: 550 credits at most.

How I built it

  • Satellite checker: Python, FastAPI, odc-stac and Microsoft Planetary Computer for Sentinel-2, scikit-learn for the Random Forest (trained on ESA WorldCover labels from areas kept separate from the test areas), h3 for map cells, web3.py to write results on-chain. Hosted on Render.
  • Smart contract: Solidity with OpenZeppelin (ERC-1155 credits), Hardhat, deployed on Polygon Amoy. 22 tests, including every cheating attempt.
  • Website: React, Vite, Tailwind, Leaflet for the map, ethers.js and MetaMask. Hosted on Vercel.
  • 40 tests on the checker side, including one that rebuilds every saved check and confirms its fingerprint still matches.

Results

On the test network right now: 3 real forest projects (GP-1, GP-2, GP-3), 80 credits created, 3 sales, 2 credits retired with certificate R-1, and one land claim refused because it overlapped GP-1. A fresh check takes about 20 seconds.

My own test on 20 places the system had never seen. I picked 10 patches in the Eastern Ghats where Global Forest Watch shows clearing in 2024, and 10 dense protected forests with no recorded loss (Similipal, Achanakmar, Nagarhole, Bandipur and others).

First version After the fix
Cleared forests wrongly marked Verified 8 of 10 1 of 10
Healthy forests marked Verified 10 of 10 10 of 10
Healthy forests wrongly flagged 0 0
Re-run gave the same fingerprint 20 of 20 20 of 20

The first result was bad. When I looked at the pictures, the cleared land had weeds and crops growing back by November, so it still looked green and the model called it forest. I measured every pixel and found that cleared ground stays drier even when it looks green: in the two biggest clearings about 24% of pixels lost a lot of moisture, against 0.6% at most in the healthy forests. So I added a moisture check. One honest caveat: I chose that rule after looking at these same 20 places, so 9 out of 10 is a best case. Testing fresh areas is the next thing on my list.

Real-world impact

  • Fewer fake credits. A forest has to pass a satellite check before any credit exists, and the contract caps how many can be made.
  • No double selling. Once land is registered, nobody else can register it again.
  • Cheap enough for small forests. The pictures are free and a check takes seconds, so a village forest or a small owner can get checked, not only big projects that can pay for audits.
  • Anyone can check it. A buyer, a journalist or someone living next to the forest can look up any credit, see the satellite pictures and re-run the check.
  • Credits stay honest after the sale. A later check can freeze credits if the forest disappears.

What it is not

  • It is not a certified carbon standard like Verra or Gold Standard, and it doesn't replace field audits.
  • It does not prove "additionality", meaning whether the forest would have been cut without the project. Satellites can't see that.
  • It does not check land ownership or the rights of people who live in the forest.
  • It runs on a test network. The coins have no value, and the carbon numbers use IPCC default factors, set up only for tropical dry forest in peninsular and central India.
  • Satellites see the canopy from above, so logging under the canopy can be missed, and a young plantation can look like forest.

Challenges I ran into

  • Leaf fall looked like tree loss. Dry forests here drop their leaves from February. My first checks compared January with March and showed "loss" in healthy forest. Comparing the same green months in both years fixed it.
  • Weeds made cleared land look green. This is the 8 out of 10 problem above, solved with the moisture check.
  • A wrong carbon factor. I first used a growth rate of 2.0, which belongs to a different region in the IPCC table. The right one for continental Asia is 1.5, so I corrected it, and the credit numbers went down.
  • Re-run broke on old checks. After changing the credit code, re-running GP-1 said "different result" even though everything matched. One extra field changed the fingerprint. I fixed it and added a test that rebuilds every saved check.
  • Public blockchain nodes only search 10,000 blocks at a time, so reading the history had to be split into pieces.

Accomplishments I'm proud of

  • It works end to end on real data: real satellite pictures, a real contract, real credits bought and retired.
  • It says no when it should: cloudy, cleared, already claimed.
  • I tested it on places it had never seen, and published the bad first result along with the fix.

What I learned

How satellite pictures actually behave (clouds, seasons, leaf fall), how much a model's training label matters, and that writing the rules into a contract changes the question from "do you trust us" to "check it yourself". I also learned to test on data I didn't pick for the demo.

What's next

  1. A fresh test on cleared forests in Odisha, Chhattisgarh and Telangana that played no part in choosing the rule.
  2. Retrain the forest model on green-season pictures with a stricter forest label.
  3. Carbon factors for more forest types.
  4. Automatic yearly re-checks, so credits stay up to date without anyone pressing a button.
  5. Field evidence (geotagged photos, forest department reports) reviewed by a second person before credits are created.

I built GroveProof on my own, from research and the satellite checker to the smart contract, the website and the video.

Built With

Share this project:

Updates

Submission history