18 on chain flow

Overview

This document provides a complete end-to-end walkthrough of on-chain operations, from project approval to credit retirement, with concrete examples and transaction flows.

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

  • PoAI verification completed (off-chain)

  • PoAI proof hashes generated:

    • poaiBundleHash

    • poaiAssetHash

    • poaiDataHash

    • poaiProcessHash

  • Governance vote passed

  • Issuance cap approved: 10,000 tons

On-Chain Action

Transaction: mintProjectRecord

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...
);

Result:

  • ProjectRecord NFT minted with tokenId = 101

  • PoAI hashes stored on-chain

  • Cap stored: 10,000,000,000 units

  • Status: Active

Event Emitted:

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

Transaction: setProjectConfig

carbonCredit1155.setProjectConfig(
    tokenId = 101,  // Same as ProjectRecord tokenId
    capUnits = 10_000 * UNIT,  // 10,000,000,000
    policy = TransferPolicy.OPEN,
    active = true
);

Validations:

  • ✅ ProjectRecord exists (tokenId 101)

  • ✅ PoAI approved (hashes non-zero)

  • ✅ Cap > 0

Result:

  • Project tokenId 101 configured

  • Cap set: 10,000,000,000 units

  • Transfer policy: OPEN

  • Status: Active (can mint credits)

Event Emitted:

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

On-Chain Action:

Transaction: mintCredits

carbonCredit1155.mintCredits(
    tokenId = 101,
    to = treasuryAddress,  // 0xTreasury...
    amountUnits = 2_000 * UNIT  // 2,000,000,000 units
);

Validations:

  • ✅ Project active (tokenId 101)

  • ✅ issued[101] + 2_000_000_000 <= cap[101]

    • 0 + 2_000_000_000 <= 10_000_000_000 ✅

State Changes:

  • issued[101] = 2_000_000_000

  • balanceOf(treasuryAddress, 101) = 2_000_000_000

  • Total supply for tokenId 101: 2,000,000,000 units

Event Emitted:

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

Purchase Flow (Pattern A: On-Chain Swap):

Transaction: transfer (from marketplace contract)

// Marketplace contract transfers from treasury to user
carbonCredit1155.safeTransferFrom(
    from = treasuryAddress,
    to = userAddress,  // 0xUser...
    id = 101,
    amount = 0.25 * UNIT  // 250,000 units
);

State Changes:

  • balanceOf(treasuryAddress, 101) = 1_999_750_000

  • balanceOf(userAddress, 101) = 250_000

UI Display:

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

Purchase Flow:

carbonCredit1155.safeTransferFrom(
    from = treasuryAddress,
    to = enterpriseAddress,  // 0xEnterprise...
    id = 101,
    amount = 12_437.62 * UNIT  // 12,437,620,000 units
);

State Changes:

  • balanceOf(treasuryAddress, 101) = 1_987_312_380

  • balanceOf(enterpriseAddress, 101) = 12_437_620_000

UI Display:

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

Step 5: Retirement (Burn)

Scenario: Retail User Retires 0.25 Tons

On-Chain Action:

Transaction: retire

carbonCredit1155.retire(
    tokenId = 101,
    amountUnits = 0.25 * UNIT  // 250,000 units
);

Validations:

  • ✅ balanceOf(msg.sender, 101) >= 250_000

    • User has 250,000 units ✅

State Changes:

  • balanceOf(userAddress, 101) = 0 (burned)

  • retired[101] = 250_000

  • Total supply for tokenId 101: 1,999,750,000 units (reduced by 250,000)

Event Emitted:

event CreditsRetired(
    uint256 indexed tokenId = 101,
    address indexed from = userAddress,
    uint256 amountUnits = 250_000
);

Transaction Hash: 0xRetirementTxHash...

6

Step 6: Certificate Generation (Off-Chain)

Indexer Listens to Event

Event Received:

{
  "event": "CreditsRetired",
  "tokenId": 101,
  "from": "0xUser...",
  "amountUnits": 250000,
  "transactionHash": "0xRetirementTxHash...",
  "blockNumber": 12345678,
  "timestamp": 1705238400
}

Certificate Generation

Backend Service:

  1. Fetch Project Details:

    • ProjectRecord tokenId 101

    • Project name: "Solar Rajasthan 2024"

    • PoAI proof hashes

  2. Generate Certificate:

{
  "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
  }
}
  1. Generate PDF Certificate:

    • Human-readable format

    • Includes all certificate data

    • Platform branding

  2. Store Certificate:

    • PDF stored (S3/IPFS)

    • JSON metadata stored

    • Certificate URI generated

  3. Notify User:

    • Email notification

    • In-app notification

    • Certificate download link


Complete Example: Solar Project Rajasthan

Initial State

  • Project: Solar Rajasthan 2024

  • Cap: 10,000 tons

  • UNIT: 1e6

  • Cap Units: 10,000,000,000

Step-by-Step Transactions

1. Mint ProjectRecord

2. Configure Credits

3. Issue Credits

4. Retail Purchase

5. Retirement

6. Certificate Generated

  • Indexer detects CreditsRetired event

  • Certificate service generates certificate

  • Certificate includes:

    • Project: Solar Rajasthan 2024

    • Quantity: 0.25 tons

    • Transaction: 0xRetirementTxHash...

    • PoAI: 0xdef456...


State Tracking

Project State

Balance State

Available Supply


Event Flow Summary

Last updated