18 on chain flow
Overview
Complete On-Chain Flow Diagram
Project Approved (PoAI + Governance)
↓
Mint ProjectRecord (NFT)
↓
Configure Credit Units Contract
↓
Issue Credit Units (Semi-Fungible Mint)
↓
User Holds Credits
↓
Retirement (Burn)
↓
Certificate Generation (Off-Chain)1
Step 1: Project Approved (PoAI + Governance)
Prerequisites
On-Chain Action
projectRegistry.mintProjectRecord(
projectId = 101,
metadataHash = 0xabc123...,
capUnits = 10_000 * UNIT, // 10,000,000,000 (if UNIT = 1e6)
poaiBundleHash = 0xdef456...,
poaiAssetHash = 0x789ghi...,
poaiDataHash = 0x123jkl...,
poaiProcessHash = 0x456mno...
);event ProjectRecordMinted(
uint256 indexed projectId = 101,
uint256 indexed tokenId = 101,
uint256 maxIssuableUnits = 10_000_000_000,
bytes32 poaiBundleHash = 0xdef456...
);2
Step 2: Configure Credit Units Contract
On-Chain Action
carbonCredit1155.setProjectConfig(
tokenId = 101, // Same as ProjectRecord tokenId
capUnits = 10_000 * UNIT, // 10,000,000,000
policy = TransferPolicy.OPEN,
active = true
);event ProjectConfigured(
uint256 indexed tokenId = 101,
uint256 capUnits = 10_000_000_000,
TransferPolicy policy = OPEN,
bool active = true
);3
Step 3: Issue Credit Units (Semi-Fungible Mint)
Scenario: Issue 2,000 Credits to Treasury
carbonCredit1155.mintCredits(
tokenId = 101,
to = treasuryAddress, // 0xTreasury...
amountUnits = 2_000 * UNIT // 2,000,000,000 units
);event CreditsMinted(
uint256 indexed tokenId = 101,
address indexed to = treasuryAddress,
uint256 amountUnits = 2_000_000_000
);4
Step 4: User Holds Credits
Scenario A: Retail User Buys 0.25 Tons
// Marketplace contract transfers from treasury to user
carbonCredit1155.safeTransferFrom(
from = treasuryAddress,
to = userAddress, // 0xUser...
id = 101,
amount = 0.25 * UNIT // 250,000 units
);const balanceUnits = await contract.balanceOf(userAddress, 101);
const balanceTons = balanceUnits / UNIT; // 0.25
// Display: "You own 0.25 tons from Solar Rajasthan 2024"Scenario B: Enterprise Buys 12,437.62 Tons
carbonCredit1155.safeTransferFrom(
from = treasuryAddress,
to = enterpriseAddress, // 0xEnterprise...
id = 101,
amount = 12_437.62 * UNIT // 12,437,620,000 units
);const balanceUnits = await contract.balanceOf(enterpriseAddress, 101);
const balanceTons = balanceUnits / UNIT; // 12.43762
// Display: "You own 12,437.62 tons from Solar Rajasthan 2024"5
6
Step 6: Certificate Generation (Off-Chain)
Indexer Listens to Event
{
"event": "CreditsRetired",
"tokenId": 101,
"from": "0xUser...",
"amountUnits": 250000,
"transactionHash": "0xRetirementTxHash...",
"blockNumber": 12345678,
"timestamp": 1705238400
}Certificate Generation
{
"certificateId": "CERT-123",
"project": {
"id": "PJT-101",
"name": "Solar Rajasthan 2024",
"tokenId": 101
},
"retirement": {
"quantity": 0.25,
"quantityUnits": 250000,
"retiredBy": "0xUser...",
"timestamp": "2026-01-14T10:00:00Z",
"transactionHash": "0xRetirementTxHash..."
},
"poai": {
"bundleHash": "0xdef456...",
"assetHash": "0x789ghi...",
"dataHash": "0x123jkl...",
"processHash": "0x456mno..."
},
"onChainProof": {
"contractAddress": "0xCarbonCredit1155...",
"tokenId": 101,
"eventIndex": 0
}
}Complete Example: Solar Project Rajasthan
Initial State
Step-by-Step Transactions
1. Mint ProjectRecord
2. Configure Credits
3. Issue Credits
4. Retail Purchase
5. Retirement
6. Certificate Generated
State Tracking
Project State
Balance State
Available Supply
Event Flow Summary
Last updated