# Smart Contracts Reference - CarbonCore Documentation ## Overview CarbonCore platform operates through 11 interconnected smart contracts deployed on Ethereum blockchain. This document provides comprehensive technical reference for all contracts, their functions, events, and interactions. ## Contract Architecture ### Layer 1: Identity & Access Control ``` UserNFT → RoleManager ``` Manages user identities as NFTs and role-based permissions. ### Layer 2: Territory Management ``` TerritoryRegistry → StandardValidators → InsuranceManager ``` Handles territory registration, verification, and compliance. ### Layer 3: Token Generation ``` CarbonCreditFactory → TerritoryTokenFactory → TerritoryToken (ERC-20) ``` Manages carbon credit projects and automated token issuance. ### Layer 4: Trading & Requests ``` OTCMarketInterface → OTCMarketIndex → RequestManager → CommentManager ``` Facilitates OTC trading, order management, and metadata storage. --- ## 1. UserNFT Contract ### Purpose ERC-721 NFT contract for user identity management with extended profile functionality. ### Contract Address ``` Sepolia: 0xdc06fD25E479D570310bA0D3b555974d6841c076 ``` ### Key Features - One NFT per wallet address - Profile data stored on-chain - Transferable identity rights - Payment-based minting ### State Variables ```solidity struct UserProfile { address walletAddress; string firstName; string lastName; string email; string phoneNumber; string physicalAddress; string metadataURI; bool active; uint256 createdAt; uint256 updatedAt; } mapping(address => uint256) public addressToTokenId; mapping(uint256 => UserProfile) public userProfiles; uint256 public nextTokenId = 1; uint256 public constant MINTING_FEE = 0.001 ether; ``` ### Core Functions #### createUserProfile ```solidity function createUserProfile( address to, string memory firstName, string memory lastName, string memory email, string memory phoneNumber, string memory physicalAddress, string memory metadataURI ) external payable whenNotPaused nonReentrant returns (uint256) ``` **Description**: Creates new user profile NFT **Access**: Public (requires payment) **Payment**: 0.001 ETH **Returns**: Token ID #### updateUserProfile ```solidity function updateUserProfile( uint256 tokenId, string memory firstName, string memory lastName, string memory email, string memory phoneNumber, string memory physicalAddress, string memory metadataURI ) external whenNotPaused nonReentrant ``` **Description**: Updates existing profile data **Access**: Token owner only **Restrictions**: Cannot change wallet address #### getUserProfile ```solidity function getUserProfile(uint256 tokenId) external view returns (UserProfile memory) ``` **Description**: Retrieves complete user profile **Access**: Public view **Returns**: UserProfile struct #### getTokenIdByAddress ```solidity function getTokenIdByAddress(address userAddress) external view returns (uint256) ``` **Description**: Gets token ID for wallet address **Access**: Public view **Returns**: Token ID (0 if none exists) ### Events ```solidity event UserProfileCreated( uint256 indexed tokenId, address indexed owner, string firstName, string lastName ); event UserProfileUpdated( uint256 indexed tokenId, uint256 updatedAt ); ``` ### Integration Example ```javascript // Check if user has NFT profile const tokenId = await userNFT.getTokenIdByAddress(walletAddress); if (tokenId.toString() === '0') { // Create new profile const tx = await userNFT.createUserProfile( walletAddress, "John", "Doe", "john@example.com", "+1234567890", "123 Main St, City, Country", "", { value: ethers.utils.parseEther("0.001") } ); await tx.wait(); } // Get profile data const profile = await userNFT.getUserProfile(tokenId); console.log(`Name: ${profile.firstName} ${profile.lastName}`); ``` --- ## 2. RoleManager Contract ### Purpose Manages role-based access control system using Keccak256 role hashes. ### Contract Address ``` Sepolia: 0x60569F3910459056dA97076b49013BF9AB843102 ``` ### Role Definitions ```solidity bytes32 public constant ADMIN_ROLE = 0xa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775; bytes32 public constant LANDOWNER_ROLE = 0xf7349b1c3bccd912e0705395f31ffe0c6540328bca90a43fb582e92a6c4fba65; bytes32 public constant EXPERT_ROLE = 0xc30672a9c8070b0e2d80ad0ec34ad08dc4bb3ab082b8e26f95864700e4684fb9; bytes32 public constant GOVERNMENT_ROLE = 0xd9d062b29c8756d894f301c5167d214c34d627724cd7fc859ab9329c9330cf51; bytes32 public constant BUYER_ROLE = 0xf8cd32ed93fc2f9fc78152a14807c9609af3d99c5fe4dc6b106a801aaddfe90e; bytes32 public constant GUEST_ROLE = 0xb6a185f76b0ff8a0f9708ffce8e6b63ce2df58f28ad66179fb4e230e98d0a52f; ``` ### State Variables ```solidity mapping(uint256 => mapping(bytes32 => bool)) public userRoles; mapping(uint256 => bytes32[]) public userRolesList; IUserNFT public userNFT; ``` ### Core Functions #### grantRole ```solidity function grantRole(uint256 tokenId, bytes32 role) external onlyAdmin whenNotPaused ``` **Description**: Grants role to user **Access**: Admin only **Emits**: RoleGranted #### revokeRole ```solidity function revokeRole(uint256 tokenId, bytes32 role) external onlyAdmin whenNotPaused ``` **Description**: Revokes role from user **Access**: Admin only **Emits**: RoleRevoked #### hasRole ```solidity function hasRole(uint256 tokenId, bytes32 role) external view returns (bool) ``` **Description**: Checks if user has specific role **Access**: Public view **Returns**: Boolean #### getUserRoles ```solidity function getUserRoles(uint256 tokenId) external view returns (bytes32[] memory) ``` **Description**: Gets all roles for user **Access**: Public view **Returns**: Array of role hashes ### Events ```solidity event RoleGranted(uint256 indexed tokenId, bytes32 indexed role); event RoleRevoked(uint256 indexed tokenId, bytes32 indexed role); ``` ### Integration Example ```javascript // Check if user has LANDOWNER_ROLE const LANDOWNER_ROLE = "0xf7349b1c3bccd912e0705395f31ffe0c6540328bca90a43fb582e92a6c4fba65"; const hasRole = await roleManager.hasRole(tokenId, LANDOWNER_ROLE); if (!hasRole) { // Request role from admin console.log("User does not have LANDOWNER_ROLE"); } // Get all user roles const roles = await roleManager.getUserRoles(tokenId); console.log(`User has ${roles.length} roles`); ``` --- ## 3. TerritoryRegistry Contract ### Purpose Core contract for territory registration, verification, and lifecycle management. ### Contract Address ``` Sepolia: 0x2Bb231045BcC27ec9925bB7453976c517162a5A7 ``` ### Territory Status Enum ```solidity enum TerritoryStatus { Pending, // 0 - Newly registered UnderExpertise, // 1 - Expert claimed ExpertVerified, // 2 - Expert completed GovernmentVerified, // 3 - Government validated Rejected, // 4 - Rejected Inactive // 5 - Deactivated } ``` ### State Structures #### Territory ```solidity struct Territory { uint256 id; address owner; string name; string territoryType; string boundaryGeoJson; uint256 area; // in hectares uint256 ownerTokenId; string blockchainReference; TerritoryStatus status; uint256 createdAt; uint256 updatedAt; uint256 verificationExpiresAt; uint256 originalTerritoryId; // for splits/merges uint256[] childTerritoryIds; // child territories uint256[] parentTerritoryIds; // parent territories uint8 modificationType; // 0=none, 1=split, 2=merge, 3=extend } ``` #### Verification ```solidity struct Verification { uint256 territoryId; uint256 expertTokenId; address expertAddress; string reportUri; uint256 oxygenProduction; // kg/year uint256 co2Absorption; // kg/year - KEY PARAMETER bool approved; string notes; uint256 timestamp; } ``` #### GovernmentVerification ```solidity struct GovernmentVerification { uint256 territoryId; uint256 governmentTokenId; address governmentAddress; string reportUri; bool approved; // KEY CONDITION uint256 validityPeriod; // in seconds string notes; uint256 timestamp; } ``` ### Core Functions #### registerTerritory ```solidity function registerTerritory( string memory name, string memory territoryType, string memory boundaryGeoJson, uint256 area, string memory blockchainReference ) external whenNotPaused nonReentrant returns (uint256) ``` **Description**: Registers new territory **Access**: Users with NFT profile **Returns**: Territory ID **Initial Status**: Pending #### claimForVerification ```solidity function claimForVerification(uint256 territoryId) external onlyRole(EXPERT_ROLE) whenNotPaused ``` **Description**: Expert claims territory for verification **Access**: Expert role only **Changes Status**: Pending → UnderExpertise #### submitVerification ```solidity function submitVerification( uint256 territoryId, string memory reportUri, uint256 oxygenProduction, uint256 co2Absorption, bool approved, string memory notes ) external onlyRole(EXPERT_ROLE) whenNotPaused nonReentrant ``` **Description**: Expert submits verification results **Access**: Expert role (must have claimed) **Key Parameter**: co2Absorption (used for token calculation) **Changes Status**: UnderExpertise → ExpertVerified (if approved) #### submitGovernmentVerification ```solidity function submitGovernmentVerification( uint256 territoryId, string memory reportUri, bool approved, uint256 validityPeriod, string memory notes ) external onlyRole(GOVERNMENT_ROLE) whenNotPaused nonReentrant ``` **Description**: Government validates territory **Access**: Government role only **Changes Status**: ExpertVerified → GovernmentVerified (if approved) **Sets**: verificationExpiresAt timestamp #### getTerritory ```solidity function getTerritory(uint256 territoryId) external view returns (Territory memory) ``` **Description**: Retrieves complete territory data **Access**: Public view **Returns**: Territory struct #### getVerification ```solidity function getVerification(uint256 territoryId) external view returns (Verification memory) ``` **Description**: Gets expert verification data **Access**: Public view **Returns**: Verification struct #### getGovernmentVerification ```solidity function getGovernmentVerification(uint256 territoryId) external view returns (GovernmentVerification memory) ``` **Description**: Gets government validation data **Access**: Public view **Returns**: GovernmentVerification struct #### getOwnerTerritories ```solidity function getOwnerTerritories(address owner) external view returns (uint256[] memory) ``` **Description**: Lists all territories owned by address **Access**: Public view **Returns**: Array of territory IDs #### needsRenewal ```solidity function needsRenewal(uint256 territoryId) external view returns (bool) ``` **Description**: Checks if validation is expiring (within 30 days) **Access**: Public view **Returns**: Boolean ### Territory Modification Functions #### splitTerritory ```solidity function splitTerritory( uint256 originalTerritoryId, string[] memory names, string[] memory boundaryGeoJsons, uint256[] memory areas, string[] memory blockchainReferences ) external whenNotPaused nonReentrant returns (uint256[] memory) ``` **Description**: Splits territory into multiple new territories **Access**: Territory owner only **Returns**: Array of new territory IDs #### mergeTerritories ```solidity function mergeTerritories( uint256[] memory territoryIds, string memory name, string memory boundaryGeoJson, uint256 area, string memory blockchainReference ) external whenNotPaused nonReentrant returns (uint256) ``` **Description**: Merges multiple territories into one **Access**: Owner of all territories **Returns**: New merged territory ID #### extendTerritory ```solidity function extendTerritory( uint256 originalTerritoryId, string memory name, string memory boundaryGeoJson, uint256 area, string memory blockchainReference ) external whenNotPaused nonReentrant returns (uint256) ``` **Description**: Extends territory with additional area **Access**: Territory owner only **Returns**: New extended territory ID ### Events ```solidity event TerritoryRegistered( uint256 indexed territoryId, address indexed owner, string name, uint256 area ); event TerritoryStatusChanged( uint256 indexed territoryId, uint8 oldStatus, uint8 newStatus ); event VerificationClaimed( uint256 indexed territoryId, address indexed expert ); event VerificationSubmitted( uint256 indexed territoryId, address indexed expert, bool approved ); event GovernmentVerificationSubmitted( uint256 indexed territoryId, address indexed government, bool approved, uint256 validityPeriod ); event TerritorySplit( uint256 indexed originalTerritoryId, uint256[] newTerritoryIds ); event TerritoriesMerged( uint256[] indexed originalTerritoryIds, uint256 newTerritoryId ); event TerritoryExtended( uint256 indexed originalTerritoryId, uint256 newTerritoryId ); ``` ### Integration Example ```javascript // Register new territory const tx = await territoryRegistry.registerTerritory( "Amazon Conservation Alpha", "Forest", JSON.stringify(geoJsonBoundary), 1000, // 1000 hectares "ipfs://QmHash..." ); const receipt = await tx.wait(); const event = receipt.events.find(e => e.event === 'TerritoryRegistered'); const territoryId = event.args.territoryId; // Check territory status const territory = await territoryRegistry.getTerritory(territoryId); console.log(`Status: ${territory.status}`); // 0 = Pending // Expert claims for verification const claimTx = await territoryRegistry.claimForVerification(territoryId); await claimTx.wait(); // Expert submits verification const verifyTx = await territoryRegistry.submitVerification( territoryId, "ipfs://QmReport...", 50000000, // 50M kg O2/year 94000000, // 94M kg CO2/year true, // approved "Territory meets all requirements" ); await verifyTx.wait(); // Check verification data const verification = await territoryRegistry.getVerification(territoryId); console.log(`CO2 Absorption: ${verification.co2Absorption} kg/year`); ``` --- ## 4. CarbonCreditFactory Contract ### Purpose Manages carbon credit projects and automated daily token issuance. ### Contract Address ``` Sepolia: 0x20ACB9DA5a312903822A46DD77728112e9735cC0 ``` ### State Structure #### Project ```solidity struct Project { uint256 territoryId; uint256 vintageYear; uint256 co2AbsorptionRate; // kg/year uint256 lastIssuanceTime; uint256 dailyRate; // tokens per day (18 decimals) bool active; address tokenAddress; // deployed TerritoryToken } ``` ### State Variables ```solidity mapping(uint256 => Project) public projects; mapping(uint256 => uint256) public territoryBeneficiaries; // NFT-based uint256 public nextProjectId = 1; uint256 public minimumIssuanceInterval = 86400; // 24 hours ``` ### Core Functions #### createProject ```solidity function createProject( uint256 territoryId, uint256 vintageYear, string memory locationName ) external whenNotPaused nonReentrant returns (uint256) ``` **Description**: Creates new carbon credit project **Access**: Territory owner only **Requirements**: - Territory status = GovernmentVerified (3) - Territory has valid CO2 absorption data - No existing project for territory/vintage year **Process**: 1. Validates territory status and ownership 2. Retrieves CO2 absorption from verification 3. Creates new TerritoryToken contract via factory 4. Calculates daily rate: (co2Absorption * 1e18) / 365 5. Stores project data 6. Sets beneficiary to territory owner's NFT **Returns**: Project ID #### createProjectWithExistingToken ```solidity function createProjectWithExistingToken( uint256 territoryId, uint256 vintageYear, address existingTokenAddress ) external whenNotPaused nonReentrant returns (uint256) ``` **Description**: Creates project using pre-deployed token **Access**: Territory owner only **Use Case**: Reusing token after territory modifications #### issueCredits ```solidity function issueCredits(uint256 projectId) external whenNotPaused nonReentrant returns (uint256) ``` **Description**: Issues accumulated carbon credits **Access**: Public (anyone can trigger) **Requirements**: - Project must be active - At least 24 hours since last issuance - Maximum 90 days accumulation **Process**: 1. Calculates days elapsed (max 90) 2. Calculates tokens: dailyRate * daysElapsed 3. Gets beneficiary from NFT system 4. Mints tokens to beneficiary address 5. Updates lastIssuanceTime **Returns**: Amount of tokens issued #### isIssuanceDue ```solidity function isIssuanceDue(uint256 projectId) external view returns (bool) ``` **Description**: Checks if 24 hours passed since last issuance **Access**: Public view **Returns**: Boolean #### getProject ```solidity function getProject(uint256 projectId) external view returns ( uint256 territoryId, uint256 vintageYear, uint256 co2AbsorptionRate, uint256 lastIssuanceTime, uint256 dailyRate, bool active, address tokenAddress ) ``` **Description**: Retrieves complete project data **Access**: Public view **Returns**: Project struct components #### getTerritoryBeneficiary ```solidity function getTerritoryBeneficiary(uint256 territoryId) external view returns (uint256 tokenId, address beneficiaryAddress) ``` **Description**: Gets current beneficiary for territory **Access**: Public view **Logic**: - If beneficiary set → use that NFT - If not set → use territory owner's NFT - Returns current NFT owner address #### setTerritoryBeneficiary ```solidity function setTerritoryBeneficiary( uint256 territoryId, uint256 beneficiaryTokenId ) external whenNotPaused ``` **Description**: Sets token beneficiary for territory **Access**: Territory owner only **Use Case**: Delegate token rights to another NFT #### transferBeneficiary ```solidity function transferBeneficiary( uint256 territoryId, uint256 newBeneficiaryTokenId ) external whenNotPaused ``` **Description**: Transfers beneficiary rights **Access**: Territory owner only **Emits**: BeneficiaryTransferred ### Events ```solidity event ProjectCreated( uint256 indexed projectId, uint256 indexed territoryId, uint256 vintageYear, uint256 co2AbsorptionRate, uint256 dailyRate, address tokenAddress ); event CreditsIssued( uint256 indexed projectId, uint256 indexed territoryId, uint256 amount, address indexed recipient, uint256 timestamp ); event BeneficiarySet( uint256 indexed territoryId, uint256 indexed beneficiaryTokenId ); event BeneficiaryTransferred( uint256 indexed territoryId, uint256 indexed oldBeneficiaryTokenId, uint256 indexed newBeneficiaryTokenId ); event ProjectStatusChanged( uint256 indexed projectId, bool active ); ``` ### Integration Example ```javascript // Create project for verified territory const territoryId = 24; const currentYear = new Date().getFullYear(); const locationName = `Territory ${territoryId} - ${currentYear}`; const createTx = await carbonCreditFactory.createProject( territoryId, currentYear, locationName ); const receipt = await createTx.wait(); const event = receipt.events.find(e => e.event === 'ProjectCreated'); const projectId = event.args.projectId; const tokenAddress = event.args.tokenAddress; const dailyRate = event.args.dailyRate; console.log(`Project created: ID=${projectId}`); console.log(`Token address: ${tokenAddress}`); console.log(`Daily rate: ${ethers.utils.formatEther(dailyRate)} tokens/day`); // Check if issuance is due const isDue = await carbonCreditFactory.isIssuanceDue(projectId); if (isDue) { // Issue accumulated credits const issueTx = await carbonCreditFactory.issueCredits(projectId); const issueReceipt = await issueTx.wait(); const issueEvent = issueReceipt.events.find(e => e.event === 'CreditsIssued'); const amount = ethers.utils.formatEther(issueEvent.args.amount); console.log(`Issued ${amount} carbon credits`); } ``` --- ## 5. TerritoryToken Contract (ERC-20) ### Purpose Individual ERC-20 token contract for each territory's carbon credits. ### Contract Template Each territory/vintage year combination gets unique token contract deployed via TerritoryTokenFactory. ### State Variables ```solidity uint256 public territoryId; uint256 public vintageYear; uint256 public annualAbsorption; // kg CO2/year string public locationName; address public minter; // CarbonCreditFactory address ``` ### Inherited from ERC-20 ```solidity string public name; // "CarbonCore Territory 24 - 2025" string public symbol; // "CCT24-2025" uint8 public decimals = 18; // Standard ERC-20 ``` ### Core Functions #### mint ```solidity function mint(address to, uint256 amount) external onlyMinter whenNotPaused ``` **Description**: Mints new tokens **Access**: Only CarbonCreditFactory **Use**: Automated daily issuance #### burn ```solidity function burn(uint256 amount) external ``` **Description**: Burns tokens (retirement) **Access**: Token holder **Use**: Carbon credit retirement for certificates ### Standard ERC-20 Functions All standard ERC-20 functions available: - `transfer(address to, uint256 amount)` - `approve(address spender, uint256 amount)` - `transferFrom(address from, address to, uint256 amount)` - `balanceOf(address account)` - `totalSupply()` - `allowance(address owner, address spender)` ### Integration Example ```javascript // Get token contract instance const tokenAddress = "0x..."; // from project const tokenABI = [...]; // ERC-20 ABI const token = new ethers.Contract(tokenAddress, tokenABI, signer); // Get token metadata const name = await token.name(); const symbol = await token.symbol(); const territoryId = await token.territoryId(); const vintageYear = await token.vintageYear(); const annualAbsorption = await token.annualAbsorption(); console.log(`Token: ${name} (${symbol})`); console.log(`Territory: ${territoryId}, Vintage: ${vintageYear}`); console.log(`Annual CO2: ${annualAbsorption} kg/year`); // Check balance const balance = await token.balanceOf(walletAddress); console.log(`Balance: ${ethers.utils.formatEther(balance)} tokens`); // Transfer tokens const transferTx = await token.transfer(recipientAddress, amount); await transferTx.wait(); // Burn tokens (retire credits) const burnTx = await token.burn(amountToBurn); await burnTx.wait(); console.log("Credits retired successfully"); ``` --- ## 6-11. Supporting Contracts ### RequestManager (0xE52950D4Baa78C2caE0970F282701350f3681ee0) **Purpose**: Manages onboarding requests and workflow states **Key Functions**: - `createTerritoryOnboardingRequest()` - `updateRequestStatus()` - `getRequest()` ### CommentManager (0x97633F9C80CAD965a2a35AD579Eb4F6060d4cd14) **Purpose**: Stores metadata and comments **Key Functions**: - `addComment()` - `getComments()` ### StandardValidators (0x571436936Ae7b7E6f0bEcc8Ca7E241FA390b67CC) **Purpose**: Validates compliance with standards ### InsuranceManager (0xE441fAD098C71F27dBa8C83E979b30c34e152Ae9) **Purpose**: Manages insurance policies for territories ### OTCMarketInterface (0xDAde447FCC8B2480c76cc8E0be23eb5772966C21) **Purpose**: Semantic layer for OTC trading **Key Functions**: - `createBuyOrder()` - `createSellOrderWithDeposit()` - `executeInstantBuy()` ### OTCMarketIndex (0xd154C16A5d1fB9CE16B88F0c76593D1C28Bd046e) **Purpose**: Indexes all orders for efficient querying --- ## Security Considerations ### Contract Security Features - **ReentrancyGuard**: All state-changing functions protected - **Pausable**: Emergency stop mechanism - **Ownable**: Owner-only critical functions - **SafeMath**: Built-in overflow protection (Solidity 0.8+) ### Access Control Patterns - **Role-Based**: Functions restricted by role - **NFT-Based**: Ownership tied to NFTs, not wallets - **Modifiers**: Custom modifiers for validation ### Best Practices 1. Always check return values 2. Use events for off-chain monitoring 3. Validate input parameters 4. Test gas limits for batch operations 5. Monitor contract paused state --- ## Gas Optimization Tips ### Efficient Contract Interaction ```javascript // ❌ Multiple separate calls const territory = await territoryRegistry.getTerritory(id); const verification = await territoryRegistry.getVerification(id); const govVerification = await territoryRegistry.getGovernmentVerification(id); // ✅ Single multicall (if available) const [territory, verification, govVerification] = await Promise.all([ territoryRegistry.getTerritory(id), territoryRegistry.getVerification(id), territoryRegistry.getGovernmentVerification(id) ]); ``` ### Gas Estimation ```javascript // Always estimate gas before transaction const gasEstimate = await contract.estimateGas.functionName(...args); const gasLimit = gasEstimate.mul(130).div(100); // 30% buffer const tx = await contract.functionName(...args, { gasLimit }); ``` --- ## Error Handling ### Common Revert Reasons ``` "Only territory owner" "Territory must be government verified" "Issuance too soon" (< 24 hours) "Project not active" "Only experts can submit verification" "Invalid role" ``` ### Error Handling Pattern ```javascript try { const tx = await contract.functionName(...args); await tx.wait(); } catch (error) { if (error.code === 4001) { console.log("User rejected transaction"); } else if (error.message.includes("Only territory owner")) { console.log("Not territory owner"); } else { console.error("Transaction failed:", error.message); } } ``` --- ## Contract Deployment ### Deployment Order 1. UserNFT 2. RoleManager (requires UserNFT address) 3. TerritoryRegistry (requires UserNFT, RoleManager) 4. TerritoryTokenFactory 5. CarbonCreditFactory (requires TerritoryRegistry, TerritoryTokenFactory, UserNFT) 6. RequestManager 7. CommentManager 8. OTCMarketInterface (requires RequestManager) 9. OTCMarketIndex 10. StandardValidators 11. InsuranceManager ### Constructor Parameters Example ```javascript // Deploy UserNFT const UserNFT = await ethers.getContractFactory("UserNFT"); const userNFT = await UserNFT.deploy(); // Deploy RoleManager const RoleManager = await ethers.getContractFactory("RoleManager"); const roleManager = await RoleManager.deploy(userNFT.address); // Deploy TerritoryRegistry const TerritoryRegistry = await ethers.getContractFactory("TerritoryRegistry"); const territoryRegistry = await TerritoryRegistry.deploy( roleManager.address, userNFT.address ); ``` --- ## Contract Verification ### Etherscan Verification ```bash npx hardhat verify --network sepolia CONTRACT_ADDRESS "CONSTRUCTOR_ARG1" "CONSTRUCTOR_ARG2" ``` ### Example ```bash npx hardhat verify --network sepolia \ 0xdc06fD25E479D570310bA0D3b555974d6841c076 ``` --- ## Upgradeability ### Current Status Contracts are **non-upgradeable** for security and immutability. ### Future Considerations - Proxy pattern for upgrades (if required) - Multi-signature admin control - Timelock for critical changes --- ## Testing ### Unit Tests ```javascript describe("CarbonCreditFactory", function() { it("Should create project for verified territory", async function() { // Setup: verify territory await territoryRegistry.submitGovernmentVerification(...); // Test: create project const tx = await carbonCreditFactory.createProject(territoryId, 2025, "Location"); const receipt = await tx.wait(); expect(receipt.status).to.equal(1); }); }); ``` ### Integration Tests Test complete workflow from territory registration to token issuance. --- ## Resources ### Contract Source Code - GitHub: `github.com/carboncore/contracts` - Verified on Etherscan Sepolia ### Development Tools - Hardhat: Smart contract development - OpenZeppelin: Secure contract libraries - Ethers.js: Contract interaction ### Documentation - Solidity Docs: `docs.soliditylang.org` - OpenZeppelin Docs: `docs.openzeppelin.com` - Ethers.js Docs: `docs.ethers.org` --- **Document Version**: 2.0 **Last Updated**: January 2025 **Network**: Ethereum Sepolia Testnet **Author**: CarbonCore Development Team For technical support: dev@carboncore.earth