Sustainable Supply Chain Tracking
What it does:
Tracks products and materials across the entire supply chain, recording sustainability data at each stage to provide verifiable proof of ethical and eco-friendly sourcing.
Why it matters:
Prevents greenwashing, exposes unethical suppliers, improves regulatory compliance, and enables consumers and partners to verify sustainability claims end-to-end.
How it works:
-
Raw material producers register sustainable sources on-chain
-
Each supply chain step creates a verifiable on-chain record
-
Sustainability metrics (carbon, water, labor) are attached as metadata
-
Ownership and custody transfers are recorded immutably
-
Auditors or oracles verify ESG claims at each stage
-
Final products carry on-chain sustainability histories
-
Data integrates with certifications, carbon reporting, and ESG dashboards
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title SustainableSupplyChainTracking
* @author Nam
* @notice Tracks product lifecycle and sustainability data across supply chains
*/
contract SustainableSupplyChainTracking is Ownable {
enum Stage {
RawMaterial,
Manufacturing,
Distribution,
Retail,
Completed
}
struct Product {
string productId;
address currentOwner;
Stage stage;
string sustainabilityDataURI; // IPFS: carbon, water, labor audits
bool completed;
}
mapping(bytes32 => Product) public products;
mapping(address => bool) public authorizedParticipants;
mapping(address => bool) public approvedAuditors;
// -------------------- EVENTS --------------------
event ProductRegistered(bytes32 indexed productHash, string productId);
event StageUpdated(bytes32 indexed productHash, Stage stage, address owner);
event SustainabilityVerified(bytes32 indexed productHash, address auditor);
// -------------------- PARTICIPANT MANAGEMENT --------------------
function authorizeParticipant(address _participant) external onlyOwner {
authorizedParticipants[_participant] = true;
}
function revokeParticipant(address _participant) external onlyOwner {
authorizedParticipants[_participant] = false;
}
function approveAuditor(address _auditor) external onlyOwner {
approvedAuditors[_auditor] = true;
}
// -------------------- PRODUCT REGISTRATION --------------------
function registerProduct(string calldata _productId, string calldata _sustainabilityURI) external {
require(authorizedParticipants[msg.sender], "Not authorized");
bytes32 productHash = keccak256(abi.encodePacked(_productId));
require(products[productHash].currentOwner == address(0), "Already registered");
products[productHash] = Product({
productId: _productId,
currentOwner: msg.sender,
stage: Stage.RawMaterial,
sustainabilityDataURI: _sustainabilityURI,
completed: false
});
emit ProductRegistered(productHash, _productId);
}
// -------------------- STAGE TRANSITION --------------------
function updateStage(
bytes32 _productHash,
Stage _stage,
string calldata _updatedSustainabilityURI
) external {
Product storage p = products[_productHash];
require(p.currentOwner == msg.sender, "Not owner");
require(!p.completed, "Already completed");
p.stage = _stage;
p.sustainabilityDataURI = _updatedSustainabilityURI;
if (_stage == Stage.Completed) {
p.completed = true;
}
emit StageUpdated(_productHash, _stage, msg.sender);
}
// -------------------- AUDIT VERIFICATION --------------------
function verifySustainability(bytes32 _productHash) external {
require(approvedAuditors[msg.sender], "Not authorized auditor");
emit SustainabilityVerified(_productHash, msg.sender);
}
}