Skip to content

AryanSaxenaa/veritas

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Veritas

Blockchain-First Carbon Credit Marketplace

Trustless. Transparent. Immutable.

A fully decentralized platform where every carbon credit issuance, verification, trade, and retirement is permanently recorded on the Ethereum blockchain—eliminating intermediaries and ensuring complete transparency in carbon offsetting.

Solidity ERC-1155 OpenZeppelin Ethereum


Table of Contents


Overview

Veritas is a blockchain-native carbon credit marketplace where smart contracts are the source of truth. Unlike traditional carbon registries that rely on centralized databases and trusted intermediaries, Veritas leverages the Ethereum blockchain to create a trustless, transparent, and tamper-proof system for carbon credit management.

The Problem with Traditional Carbon Markets

  • Double Counting - Credits sold multiple times across different registries
  • Opaque Verification - No public audit trail for verification decisions
  • Centralized Control - Single points of failure and manipulation
  • Slow Settlement - Days or weeks for cross-border transactions
  • High Fees - Intermediaries extract value at every step

The Blockchain Solution

Challenge Blockchain Solution Implementation
Double Counting On-chain token ownership ERC-1155 enforces single owner per token unit
Opaque Verification Public verification events CreditVerified event emitted on-chain
Centralized Control Decentralized access control OpenZeppelin AccessControl with multiple roles
Slow Settlement Atomic swaps Payment + transfer in single transaction
High Fees Peer-to-peer trading Direct buyer-seller trades, no middlemen

Why Blockchain is Essential

Immutability

Every credit issuance, transfer, and retirement is permanently recorded on the Ethereum blockchain. Once a transaction is confirmed, it cannot be altered or deleted—creating an unbreakable audit trail.

Transparency

All smart contract code is open source and verified on Etherscan. Anyone can inspect the logic that governs credit issuance, verification rules, and retirement mechanics.

Trustlessness

Smart contracts eliminate the need to trust intermediaries. The code automatically enforces rules:

  • Only ISSUER_ROLE can mint credits
  • Only VERIFIER_ROLE can approve credits
  • Unverified credits cannot be listed on the marketplace
  • Retired credits cannot be transferred

Atomic Transactions

The marketplace smart contract ensures that payment and credit transfer happen in the same transaction—or neither happens. No risk of payment without delivery or delivery without payment.

Provenance Tracking

Every credit carries its complete history on-chain:

  • Who issued it and when
  • Which verifier approved it
  • Every transfer between wallets
  • When and why it was retired

Carbon Credit Lifecycle (On-Chain)

Every stage of the carbon credit lifecycle is enforced by smart contract logic and recorded permanently on the blockchain:

┌─────────────────────────────────────────────────────────────────────────────┐
│                    ON-CHAIN CARBON CREDIT LIFECYCLE                         │
└─────────────────────────────────────────────────────────────────────────────┘

    ┌──────────┐      ┌──────────┐      ┌──────────┐      ┌──────────┐
    │  ISSUE   │ ───► │  VERIFY  │ ───► │  TRADE   │ ───► │  RETIRE  │
    │ (mint)   │      │ (approve)│      │ (atomic) │      │ (burn)   │
    └──────────┘      └──────────┘      └──────────┘      └──────────┘
         │                 │                 │                 │
         ▼                 ▼                 ▼                 ▼
    ┌──────────┐      ┌──────────┐      ┌──────────┐      ┌──────────┐
    │ ERC-1155 │      │ On-chain │      │ Escrow   │      │ Token    │
    │ _mint()  │      │isVerified│      │ Contract │      │ _burn()  │
    │ + event  │      │ = true   │      │ + ETH    │      │ + cert   │
    └──────────┘      └──────────┘      └──────────┘      └──────────┘

1. 🏭 Issuance — On-Chain Minting

Smart Contract Function: issueCarbonCredit()

// Only addresses with ISSUER_ROLE can call this function
function issueCarbonCredit(
    address to,
    uint256 quantity,
    string memory projectId,
    string memory vintage,
    string memory serialNumber,
    string memory registry,
    string memory metadataURI
) external onlyRole(ISSUER_ROLE) returns (uint256)

On-Chain Data Stored:

  • projectId — Unique project identifier
  • vintage — Year of carbon reduction
  • serialNumber — Registry serial number
  • registry — Issuing registry (Verra, Gold Standard, etc.)
  • metadataURI — IPFS hash for extended metadata
  • issuer — Wallet address of issuer
  • issuanceDate — Block timestamp
  • isVerified — Starts as false

Blockchain Event Emitted:

event CreditIssued(tokenId, issuer, recipient, quantity, projectId, vintage);

2. Verification — On-Chain Approval

Smart Contract Function: verifyCredit()

// Only addresses with VERIFIER_ROLE can verify credits
function verifyCredit(uint256 tokenId) external onlyRole(VERIFIER_ROLE) {
    require(exists(tokenId), "Token does not exist");
    require(!creditMetadata[tokenId].isVerified, "Already verified");
    creditMetadata[tokenId].isVerified = true;
    emit CreditVerified(tokenId, msg.sender);
}

Why This Matters:

  • Verification status is stored on-chain, not in a database
  • The marketplace contract checks this flag before allowing listings
  • Anyone can verify a credit's status by querying the blockchain
  • Verification events create a public, immutable audit trail

Marketplace Verification Check:

// CarbonMarketplace.sol - prevents unverified credits from being listed
try ICarbonCredit(tokenAddress).isCreditVerified(tokenId) returns (bool verified) {
    require(verified, "Credit not verified");
} catch {
    revert("Token contract does not support verification check");
}

3. Trading — Atomic Swaps with Escrow

Smart Contract: CarbonMarketplace.sol

The marketplace contract implements a secure escrow pattern:

┌─────────────────────────────────────────────────────────────────┐
│                     ATOMIC SWAP FLOW                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  SELLER                    MARKETPLACE                BUYER     │
│    │                           │                         │      │
│    │── approve(marketplace) ──►│                         │      │
│    │── createListing() ───────►│ (tokens held in escrow) │      │
│    │                           │◄── buyListing() + ETH ──│      │
│    │◄────── ETH transferred ───│── tokens transferred ──►│      │
│    │                           │                         │      │
│  Single transaction = Payment + Delivery (atomic)               │
└─────────────────────────────────────────────────────────────────┘

Security Features:

  • ReentrancyGuard — Prevents reentrancy attacks
  • ERC1155Holder — Safe token reception
  • Escrow pattern — Tokens held by contract until purchase
  • Atomic execution — All-or-nothing transaction

4. Retirement — Permanent Token Burn

Smart Contract Function: retireCarbonCredit()

function retireCarbonCredit(
    uint256 tokenId,
    uint256 quantity,
    string memory reason
) external {
    require(balanceOf(msg.sender, tokenId) >= quantity, "Insufficient balance");
    
    // Permanently burn tokens - they can NEVER be recovered
    _burn(msg.sender, tokenId, quantity);
    
    // Record retirement reason on-chain
    retirements[tokenId].push(RetirementEvent({
        tokenId: tokenId,
        quantity: quantity,
        retiree: msg.sender,
        reason: reason,
        timestamp: block.timestamp
    }));
    
    // Mint ERC-721 certificate as proof
    retirementCertificate.mint(msg.sender, tokenId, quantity, reason, certURI);
}

Blockchain Guarantees:

  • Burned tokens are permanently destroyed (ERC-1155 _burn)
  • Retirement reason is immutably recorded on-chain
  • isRetired flag prevents any future transfers
  • ERC-721 certificate serves as on-chain proof of retirement

Blockchain Architecture

System Overview

┌─────────────────────────────────────────────────────────────────────────────┐
│                        VERITAS BLOCKCHAIN ARCHITECTURE                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│    ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐        │
│    │   FRONTEND      │    │   BACKEND       │    │  ETHEREUM       │        │
│    │   (React)       │◄──►│  (Express)      │◄──►│  BLOCKCHAIN     │        │
│    └─────────────────┘    └─────────────────┘    └─────────────────┘        │
│            │                      │                       │                 │
│            │                      │                       ▼                 │
│            │                      │             ┌─────────────────────┐     │
│            │                      │             │  SMART CONTRACTS    │     │
│            │                      │             │  (Solidity 0.8.20)  │     │
│            │                      │             └─────────────────────┘     │
│            │                      │                       │                 │
│            ▼                      ▼                       ▼                 │
│    ┌─────────────────────────────────────────────────────────────────┐      │
│    │                      ETHERS.JS v6                               │      │
│    │           (Wallet Connection + Contract Calls)                  │      │
│    └─────────────────────────────────────────────────────────────────┘      │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Smart Contract Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                         SMART CONTRACT LAYER                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │                        CarbonCredit.sol                               │  │
│  │                         (ERC-1155)                                    │  │
│  ├───────────────────────────────────────────────────────────────────────┤  │
│  │  INHERITS:                                                            │  │
│  │  • ERC1155 (OpenZeppelin) — Multi-token standard                      │  │
│  │  • AccessControl — Role-based permissions                             │  │
│  │  • ERC1155Supply — Track total supply per token                       │  │
│  │  • ERC1155Burnable — Permanent token destruction                      │  │
│  ├───────────────────────────────────────────────────────────────────────┤  │
│  │  ROLES:                                                               │  │
│  │  • DEFAULT_ADMIN_ROLE — Grant/revoke all roles                        │  │
│  │  • ISSUER_ROLE — Mint new carbon credits                              │  │
│  │  • VERIFIER_ROLE — Verify and approve credits                         │  │
│  ├───────────────────────────────────────────────────────────────────────┤  │
│  │  STORAGE:                                                             │  │
│  │  • mapping(uint256 => CreditMetadata) creditMetadata                  │  │
│  │  • mapping(uint256 => RetirementEvent[]) retirements                  │  │
│  └───────────────────────────────────────────────────────────────────────┘  │
│                                    │                                        │
│                                    ▼                                        │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │                     CarbonMarketplace.sol                             │  │
│  ├───────────────────────────────────────────────────────────────────────┤  │
│  │  INHERITS:                                                            │  │
│  │  • ERC1155Holder — Receive ERC-1155 tokens                            │  │
│  │  • ReentrancyGuard — Prevent reentrancy attacks                       │  │
│  ├───────────────────────────────────────────────────────────────────────┤  │
│  │  SECURITY:                                                            │  │
│  │  • Verification check before listing                                  │  │
│  │  • Escrow pattern for safe trading                                    │  │
│  │  • NonReentrant modifier on all state-changing functions              │  │
│  └───────────────────────────────────────────────────────────────────────┘  │
│                                    │                                        │
│                                    ▼                                        │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │                   RetirementCertificate.sol                           │  │
│  │                         (ERC-721)                                     │  │
│  ├───────────────────────────────────────────────────────────────────────┤  │
│  │  • Non-fungible proof of retirement                                   │  │
│  │  • Stores retirement metadata permanently                             │  │
│  │  • Minted automatically on credit retirement                          │  │
│  └───────────────────────────────────────────────────────────────────────┘  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Deployed Contracts (Sepolia Testnet)

Contract Address Etherscan
CarbonCredit 0xc5320DF1BF249E1092b0705c49CAcf588DfBBa1A View ↗
CarbonMarketplace 0x5E7076A4afaB7169FE5d9AC84fFD977E4c4278AC View ↗

On-Chain Events

All critical actions emit events that are permanently recorded on the blockchain:

Event Data Logged Purpose
CreditIssued tokenId, issuer, recipient, quantity, projectId, vintage Track credit creation
CreditVerified tokenId, verifier Audit verification decisions
CreditRetired tokenId, retiree, quantity, reason Permanent retirement record
ListingCreated listingId, seller, tokenId, quantity, price Marketplace activity
ListingSold listingId, buyer, quantity, totalPrice Trade execution

Role-Based Access Control (On-Chain)

Access control is enforced entirely on-chain using OpenZeppelin's AccessControl:

bytes32 public constant ISSUER_ROLE = keccak256("ISSUER_ROLE");
bytes32 public constant VERIFIER_ROLE = keccak256("VERIFIER_ROLE");

// Role hierarchy
// DEFAULT_ADMIN_ROLE
//     ├── ISSUER_ROLE
//     └── VERIFIER_ROLE
Role Bytes32 Hash Capabilities
Admin 0x00...00 Grant/revoke all roles, upgrade contracts
Issuer keccak256("ISSUER_ROLE") Call issueCarbonCredit()
Verifier keccak256("VERIFIER_ROLE") Call verifyCredit(), updateMetadata()
User No role required Buy, sell, transfer, retire credits

Blockchain Security Features

1. Reentrancy Protection

contract CarbonMarketplace is ReentrancyGuard {
    function buyListing(uint256 listingId, uint256 quantity) 
        external payable nonReentrant { ... }
}

2. Access Control Modifiers

function issueCarbonCredit(...) external onlyRole(ISSUER_ROLE) { ... }
function verifyCredit(...) external onlyRole(VERIFIER_ROLE) { ... }

3. Transfer Restrictions

// Retired credits cannot be transferred
function safeTransferFrom(...) public override {
    require(!creditMetadata[id].isRetired, "Cannot transfer retired credits");
    super.safeTransferFrom(...);
}

4. Verification Gating

// Unverified credits cannot be listed on marketplace
require(ICarbonCredit(tokenAddress).isCreditVerified(tokenId), "Credit not verified");

Tech Stack

⛓️ Blockchain (Core)

Technology Purpose
Solidity 0.8.20 Smart contract language with latest safety features
OpenZeppelin Contracts Audited implementations of ERC-1155, ERC-721, AccessControl
ERC-1155 Multi-token standard for efficient batch operations
ERC-721 Non-fungible tokens for retirement certificates
Hardhat Development environment, testing, and deployment
Ethers.js v6 TypeScript-first Ethereum library for frontend/backend
Sepolia Testnet Ethereum test network for deployment

🖥️ Frontend

Technology Purpose
React 18 UI framework with concurrent features
TypeScript Type-safe JavaScript
Vite Fast build tool and dev server
TailwindCSS Utility-first styling
Framer Motion Smooth animations
MetaMask Integration Wallet connection and signing

🔧 Backend

Technology Purpose
Node.js + Express REST API server
MongoDB Atlas Off-chain metadata cache
JWT User authentication
Blockchain Indexer Event listener for on-chain state sync

Project Structure

veritas/
├── contracts/                 # Solidity smart contracts
│   ├── CarbonCredit.sol      # ERC-1155 carbon credit token
│   ├── CarbonMarketplace.sol # Trading marketplace
│   └── RetirementCertificate.sol # ERC-721 certificates
├── components/               # React components
│   ├── Navbar.tsx
│   ├── Footer.tsx
│   ├── Hero.tsx
│   └── ...
├── pages/                    # Page components
│   ├── Home.tsx             # Landing page
│   ├── Marketplace.tsx      # Credit marketplace
│   ├── Dashboard.tsx        # User portfolio
│   ├── Issuer.tsx           # Credit issuance
│   ├── Verifier.tsx         # Verification dashboard
│   ├── Retire.tsx           # Credit retirement
│   └── Admin.tsx            # Admin panel
├── contexts/                 # React contexts
│   ├── AuthContext.tsx      # Authentication state
│   └── WalletContext.tsx    # Wallet connection
├── lib/
│   └── blockchain.ts        # Blockchain service layer
├── server/                   # Backend server
│   ├── server.js            # Express server
│   ├── models/              # MongoDB models
│   ├── routes/              # API routes
│   └── services/
│       └── indexer.js       # Blockchain event indexer
├── scripts/                  # Deployment scripts
└── artifacts/               # Compiled contracts

Getting Started

Prerequisites

  • Node.js 18+
  • MongoDB Atlas account
  • MetaMask wallet
  • Alchemy/Infura API key for Sepolia

Installation

  1. Clone the repository

    git clone https://github.com/AryanSaxenaa/veritas.git
    cd veritas
  2. Install frontend dependencies

    npm install
  3. Install backend dependencies

    cd server
    npm install
    cd ..
  4. Configure environment variables (see Environment Variables)

  5. Start the backend server

    cd server
    npm run dev
  6. Start the frontend (new terminal)

    npm run dev
  7. Open in browser

    http://localhost:3000
    

Smart Contracts

Smart Contract Deep Dive

CarbonCredit.sol — The Core Token Contract

This ERC-1155 contract is the heart of the system. Every carbon credit exists as a token on this contract.

// On-chain metadata structure — permanently stored on Ethereum
struct CreditMetadata {
    string projectId;       // Unique project identifier
    string vintage;         // Year of carbon reduction
    string serialNumber;    // Registry serial number
    string registry;        // Issuing registry (Verra, Gold Standard)
    string metadataURI;     // IPFS hash for extended data
    address issuer;         // Who created this credit
    uint256 issuanceDate;   // Block timestamp of creation
    bool isRetired;         // Permanently burned?
    bool isVerified;        // Approved by verifier?
}

Key Functions:

Function Access On-Chain Action
issueCarbonCredit() ISSUER_ROLE Mints new tokens, stores metadata
verifyCredit() VERIFIER_ROLE Sets isVerified = true, emits event
retireCarbonCredit() Token holder Burns tokens, records retirement
isCreditVerified() Public Read verification status
getCreditMetadata() Public Read all on-chain metadata
getRetirementHistory() Public Read retirement events

CarbonMarketplace.sol — Trustless Trading

The marketplace enables peer-to-peer trading with built-in security:

struct Listing {
    uint256 listingId;      // Auto-incrementing ID
    address seller;         // Seller's wallet
    address tokenAddress;   // CarbonCredit contract
    uint256 tokenId;        // Which credit
    uint256 quantity;       // How many tonnes
    uint256 pricePerUnit;   // Price in wei
    bool isActive;          // Still available?
}

Trading Flow (Single Transaction):

1. Seller approves marketplace → setApprovalForAll()
2. Seller creates listing      → createListing() [tokens → escrow]
3. Buyer purchases             → buyListing() [ETH → seller, tokens → buyer]

Compile & Deploy to Ethereum

# Compile Solidity contracts
npx hardhat compile

# Deploy to Sepolia testnet
npx hardhat run scripts/deploy.cjs --network sepolia

# Verify on Etherscan (optional)
npx hardhat verify --network sepolia <CONTRACT_ADDRESS>

Environment Variables

Frontend (.env)

VITE_CONTRACT_ADDRESS_SEPOLIA=0xc5320DF1BF249E1092b0705c49CAcf588DfBBa1A
VITE_MARKETPLACE_ADDRESS_SEPOLIA=0x5E7076A4afaB7169FE5d9AC84fFD977E4c4278AC
VITE_API_URL=http://localhost:5000/api

Backend (server/.env)

MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/veritas
JWT_SECRET=your-secure-jwt-secret
PORT=5000
SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/your-api-key
CONTRACT_ADDRESS=0xc5320DF1BF249E1092b0705c49CAcf588DfBBa1A
MARKETPLACE_ADDRESS=0x5E7076A4afaB7169FE5d9AC84fFD977E4c4278AC

Deployment

Frontend (Vercel/Netlify)

  1. Build the production bundle:

    npm run build
  2. Deploy the dist folder to your hosting provider

  3. Set environment variables in your hosting dashboard

Backend (Railway/Render/Heroku)

  1. Push server folder to deployment platform

  2. Set environment variables

  3. Ensure MongoDB Atlas IP whitelist includes deployment IP

Smart Contracts

Contracts are already deployed on Sepolia. To redeploy:

npx hardhat run scripts/deploy.cjs --network sepolia

Update contract addresses in both .env files after deployment.


API Endpoints

Authentication

Method Endpoint Description
POST /api/auth/register Register new user
POST /api/auth/login User login
POST /api/auth/request-role Request issuer/verifier role

Credits

Method Endpoint Description
GET /api/credits Get all credits
GET /api/credits/pending Get unverified credits
GET /api/credits/verified Get verified credits
POST /api/credits/update-metadata Update credit metadata

Marketplace

Method Endpoint Description
GET /api/marketplace/listings Get active listings

User Roles

Role Access
Guest View landing page, register
User Marketplace, Dashboard, Retire
Issuer + Issue Credits
Verifier + Verify Credits
Admin + Admin Panel, Grant Roles

License

This project is licensed under the MIT License.



🔗 Blockchain = Trust

Every transaction is permanent. Every credit is traceable. Every retirement is verifiable.

CarbonCredit on EtherscanMarketplace on EtherscanReport Bug

Built for a sustainable future

Blockchain-Carbon-Credit-Management-System.pptxDescription.docx Experimental Data Performed Over Blockchain.docx 2  Marketplace

1  Landing Page 3  Metamask connect wallet 4  Metamask Purchase Credits 5  User Dashboard 6  Retire 7  Admin Console 8  Issue Credits 9  Verify

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors