ZiwaChain: Making Environmental Work Easier to Verify

Track 3: Sustainable Supply Chains

The question: What happens after collection?

ZiwaChain grew out of my work on ZiwaClear, a project exploring how communities around Lake Victoria could coordinate water-hyacinth removal and connect the collected biomass to downstream use.

As I explored the problem, I kept returning to one question:

What happens after the material is collected?

Collection is only one stage in a supply chain. Someone has to inspect the material. A receiving party has to accept it. Someone has to process it into another product, and that product should eventually reach its intended use.

When multiple people and organisations handle the material, keeping track of its journey becomes a different problem from recording the initial collection. What quantity was reported? What was accepted? How much was processed? What happened to the resulting products? If the work involves incentives or payments, was a settlement confirmed?

These are separate events, and recording one does not prove that the others happened.

My early field conversations around Lake Victoria also challenged some of my assumptions. Water hyacinth does not affect every location in the same way or remain in one place indefinitely. Conversations with local fishers raised questions about trust, incentives, and the practical conditions under which people would participate in removal efforts.

Those conversations did not establish that every community faces the same challenge, or that blockchain is necessarily the answer. They did make me think more carefully about accountability throughout the journey of environmental work.

I wanted to explore whether a shared, inspectable record could connect the different stages without treating a collection entry as proof of everything that followed.

That became ZiwaChain.

The solution: Track the journey, not just the collection

ZiwaChain is a blockchain-based traceability prototype designed to record the journey of collected material through a defined sequence:

Collection → Verification or rejection → Acceptance → Processing → End use

Settlement confirmation is recorded separately within the workflow.

Each stage represents a distinct event. A batch recorded as collected cannot simply be treated as accepted, and acceptance alone does not establish that the material was processed or reached its intended use.

This is where ZiwaChain fits the Sustainable Supply Chains track. It explores how product traceability, digital records, and a work-credit mechanism could support greater accountability in a recovery and circular-economy supply chain.

The prototype does not establish a complete operational supply chain or prove that its participants are acting truthfully. Instead, it provides a technical foundation for recording events, enforcing rules around quantities and permissions, and checking the resulting records against a public blockchain.

One of my central design decisions was to put critical rules in the smart contract rather than relying entirely on the frontend to prevent invalid records.

Building the rules, not just recording the claims

I built ZiwaChain as a solo project using Solidity 0.8.28, OpenZeppelin Contracts v5, and Hardhat. I deployed the smart contract to Base Sepolia, an Ethereum-compatible test network.

Before this project, I had never worked with Solidity.

The challenge was not simply learning a new language or getting a contract to compile. I had to work out how to represent a real-world supply-chain process as explicit states, decide who could move a record forward, and account for what happens when a collection is rejected, quantities are inconsistent, or evidence needs correction.

1. Quantities must follow the material

A traceability record becomes less useful if its quantities can grow arbitrarily as material moves through successive stages.

ZiwaChain checks that a receiving party cannot accept more than the recorded harvest quantity. It also prevents cumulative end-use quantities from exceeding the amount recorded as processed.

For example, the acceptance function includes this check:

if (acceptedKg == 0) revert InvalidQuantity();
if (acceptedKg > b.harvestedKg) {
    revert MassBalanceViolation();
}

The end-use function applies the same principle downstream:

if (b.endUseKgTotal + endUseKg > b.processedKg) {
    revert MassBalanceViolation();
}

These checks encode a supply-chain rule: downstream quantities must remain consistent with the quantities recorded at earlier stages.

The checks live in the contract itself, so an invalid transaction cannot proceed merely because a frontend failed to catch it.

But there is a boundary to what this achieves. The contract can compare submitted quantities; it cannot independently check a physical scale. If someone reports an incorrect collection quantity and that error is not caught during verification, the blockchain cannot discover the true weight on its own.

The goal is to constrain the records and make inconsistencies harder to introduce, not to pretend that mathematical rules replace physical evidence.

2. Separate submission from verification

The integrity of a supply-chain record also depends on who can approve it.

ZiwaChain separates the relayer role, which submits collection records on behalf of the workflow, from the verifier role, which records the inspection outcome.

The contract explicitly prevents an address holding the relayer role from acting as the verifier:

if (hasRole(RELAYER_ROLE, msg.sender)) {
    revert VerifierCannotBeRelayer();
}

This restriction is part of the verifyBatch function, which also checks that the caller has the required verifier role.

The intention is to make separation of duties an enforceable software rule instead of relying only on a process that participants are expected to follow.

It is not a complete solution to conflicts of interest. Different addresses could still be controlled by the same person, private keys could be shared, and the administrator remains responsible for assigning roles. The contract also cannot establish whether a verifier is genuinely independent in the real world.

Nevertheless, it enforces a specific boundary: an address with the relayer role cannot also perform the verification action.

3. Mistakes need an audit trail too

Real supply-chain records will not always be perfect. Evidence may need correction, and a useful system has to account for that without making previous entries disappear silently.

ZiwaChain includes a correctRecord function that allows an existing evidence hash to be superseded while preserving a link to the replacement.

address author = _hashAuthor[batchId][supersededHash];
if (author == address(0)) revert HashNotFound();
if (author != msg.sender) revert NotHashAuthor();

if (_supersededByMap[batchId][supersededHash] != bytes32(0)) {
    revert HashAlreadySuperseded(supersededHash);
}

_supersededByMap[batchId][supersededHash] = newHash;
_recordHash(batchId, newHash);
emit RecordCorrected(
    batchId, msg.sender, supersededHash, newHash, reasonHash
);

The contract checks that the original hash exists, that the caller is its recorded author, and that it has not already been superseded. It then records the replacement and emits a correction event.

This function corrects evidence references, not batch quantities. It also does not independently determine whether a correction is justified; the reason is represented by a hash, and the underlying explanation still needs to be assessed.

I wanted to account for the fact that recordkeeping involves human error. A correction should be visible as a correction, not indistinguishable from an original entry.

Designing for cases beyond the happy path

I did not want the prototype to demonstrate only a successful batch moving from collection to end use. The rejected and inconsistent cases are just as important when testing the rules.

ZiwaChain detects reused evidence hashes and emits an EvidenceReused event for review. It does not automatically classify the batch as fraudulent. An identical hash indicates that the same digital evidence reference has appeared before; it is a reason to investigate, not proof of dishonest behaviour.

The prototype also includes a work-credit mechanism using OpenZeppelin's ERC-1155 implementation. Token ID 1 represents the WORK_CREDIT token, with one credit minted per kilogram recorded as reaching the defined end-use stage.

I added a transfer restriction by overriding OpenZeppelin's _update hook:

function _update(
    address from,
    address to,
    uint256[] memory ids,
    uint256[] memory values
) internal override {
    if (from != address(0)) revert NonTransferable();
    super._update(from, to, ids, values);
}

In this implementation, minting from the zero address is permitted, while transfers from existing holders revert. The work-credit tokens are therefore not freely transferable.

The credits represent qualifying work recorded within the prototype. They are not money or carbon credits and do not establish measured emissions reductions. Tokens are minted to a designated custodian, while the contract maintains an internal mapping associating recorded credits with a harvester pseudonym. The token balance alone is not proof that an individual received payment or directly controls the tokens.

These details matter because an incentive mechanism should not be confused with evidence of environmental impact or a functioning payment system.

Making records easier for people to inspect

A smart contract is not a practical interface for everyone. Someone checking a batch should not need to understand Solidity, transaction receipts, or JSON structures just to interpret a record.

I built a certificate-generation workflow and a browser-based verification interface to make the information easier to inspect.

The off-chain hashing pipeline uses canonical JSON, salted payload hashes, and Keccak-256. Canonicalisation gives equivalent JSON objects a consistent representation before hashing, so the payload's digital fingerprint can be recomputed and compared. HMAC-SHA256 derives pseudonymous identifiers using a server-side secret, a group identifier, and a batch identifier.

These mechanisms are intended to help detect unexpected changes to data and reduce the unnecessary exposure of direct identifiers. They do not guarantee complete anonymity or establish that the original information was truthful. The server-side secret also remains a trust and security dependency.

The browser-side verification logic is designed to recompute certificate hashes, inspect transaction receipts and on-chain events, detect superseded or reused evidence, query contract state, check quantity constraints and work-credit records, and compare recorded payment-reference hashes.

The aim is to let someone examine a recorded batch journey without relying solely on a claim displayed by the person who submitted it.

The end-to-end QR/reference-link workflow still needs further validation. Generating a certificate or displaying its QR code is not enough: the link must open the correct batch, and the verification checks must complete successfully against the intended deployed contract.

That distinction is important to the project. A certificate should offer a route to checking a record, not just a polished summary that looks authoritative.

What the working prototype demonstrates

I deployed the contract to Base Sepolia and ran a seed script that created four synthetic demonstration batches. These are test records, not actual water-hyacinth harvests from Lake Victoria.

Each batch exercises a different scenario.

Batch A: A complete recorded journey

The demonstration records:

  • 1,000 kg collected
  • 900 kg accepted
  • 800 kg processed
  • 800 kg recorded as reaching end use

The end-use records split the final 800 kg into two entries: 500 kg for grid bioenergy and 300 kg for bottled biogas. The demo also records a simulated settlement confirmation and issues 800 work credits.

This example demonstrates how the system distinguishes collection, acceptance, processing, and end-use quantities rather than treating the initial collection as proof of the entire downstream journey.

Batch B: A rejected collection

A separate batch is rejected following an illustrative quality failure. The rejected state prevents it from proceeding through the successful lifecycle, and no work credits are issued.

This tests whether a rejected collection remains distinguishable from one that progresses through the workflow.

Batch C: Corrected evidence

The system records a replacement evidence hash while preserving the link to the superseded version.

This demonstrates how the record can reflect a correction without silently erasing the earlier evidence reference.

Batch D: Reused evidence

Another batch reuses an evidence hash already associated with Batch A. The contract emits a warning event for review rather than automatically classifying the batch as fraudulent.

Together, these examples exercise successful progression, rejection, correction, and a potentially concerning inconsistency.

The project also includes a simulated SMS interaction for settlement confirmation. The OTP and reply-handling logic is implemented and tested, but message delivery is simulated. There is no live SMS-provider integration, real USSD gateway, or direct integration with Safaricom's M-Pesa APIs. A recorded settlement confirmation is not proof that money arrived in a participant's account.

Engineering evidence

My latest reported codebase checks showed:

  • 99 passing automated tests covering the contract lifecycle, access permissions, quantity constraints, evidence correction, duplicate-evidence handling, hashing, certificates, verification, and simulated SMS behaviour.
  • A successful production frontend build using npm run web:build.
  • A deployed smart contract on Base Sepolia.

The contract can be inspected here:

These results demonstrate that the tested code paths execute under the conditions covered by the tests and that the contract has been deployed to a public test network. They do not prove the absence of vulnerabilities, establish that the records describe real events, or show that the workflow is production-ready. The prototype has not undergone a completed independent security audit.

What I learned building ZiwaChain

The most important lesson was that a trustworthy digital record and a truthful real-world claim are not the same thing.

A transaction can show that an action was recorded. A hash can help show that data has not changed unexpectedly. A smart contract can reject a quantity that violates a programmed rule. None of these independently proves that the physical material was weighed correctly, came from the claimed location, or reached its intended destination.

That distinction influenced how I approached the system. I separated submission from verification, enforced quantity constraints between stages, preserved a correction trail for evidence, and treated duplicate evidence as a warning requiring review rather than an automatic fraud verdict.

I also learned that the interface matters. A record that can be checked technically but cannot be understood by the people expected to use it is of limited practical value. The certificate and verification interface are therefore part of the problem I am trying to solve, not just an addition to the frontend.

Building ZiwaChain meant learning Solidity while thinking through state transitions, permissions, edge cases, and the limitations of what code can establish. It taught me to ask not only whether a system works when everything goes as expected, but also how it behaves when a collection is rejected, evidence changes, or records disagree.

It also made me more careful about claims. A successful test suite is evidence of tested behaviour, not proof of real-world adoption. A recorded quantity is not a measured environmental outcome. And a work-credit token is not proof of a payment or an emissions reduction.

What comes next

ZiwaChain is currently a deployed testnet prototype. It has not yet been integrated with ZiwaClear in production, validated through real field operations, connected to a live payment service, or supported by a confirmed downstream buyer network.

The next steps are to:

  1. Validate the full certificate journey. Confirm that certificate generation, QR/reference links, and on-chain verification work reliably together against the deployed contract.
  2. Validate the operating model. Work with potential participants to understand who records collections, who inspects them, how disputes are handled, and what evidence receiving parties require.
  3. Connect real communication workflows. Integrate a live SMS provider and assess an appropriate USSD, with secure handling of secrets and persistent state.
  4. Test settlement reconciliation. Determine how recorded confirmations could be connected to reliable payment evidence without confusing a participant's confirmation with independent verification of a payment.
  5. Run a carefully scoped field pilot. Test whether the workflow works for actual participants, assess record quality and usability, and arrange appropriate independent security review before considering production use.

These are proposed next steps, not completed capabilities.

I am not claiming that ZiwaChain has already removed tonnes of water hyacinth, generated verified climate benefits, or established a sustainable business model. The current achievement is a working technical foundation for testing whether the journey of recovered material can be recorded and checked more transparently.

For the Sustainable Supply Chains track, the question is not simply whether blockchain can store a record. It is whether connecting the stages of a supply chain can make claims easier to examine, inconsistencies easier to identify, and accountability easier to build into the process.

That is what I set out to explore with ZiwaChain.

What happens after collection, and how can we make that journey easier to follow, easier to inspect, and more accountable without pretending that a blockchain can prove what it cannot?

Built With

Share this project:

Updates

Submission history