Renewable Energy Credit System
What it does:
Creates, tracks, and trades Renewable Energy Credits (RECs) on-chain, where each credit represents a verified unit of renewable electricity generated.
Why it matters:
Prevents double-counting of green energy, increases trust in sustainability claims, and enables open, global markets for renewable energy credits.
How it works:
-
Renewable energy producers register generation facilities on-chain
-
Verified oracles submit energy production data (kWh / MWh)
-
Smart contract mints REC tokens based on verified output
-
Credits can be transferred, traded, or retired (burned) to offset emissions
-
Corporations or individuals retire RECs to prove green energy usage
-
All issuance, transfers, and retirements are transparent and auditable
-
Integrates with carbon markets, ESG reporting, and energy DAOs
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title RenewableEnergyCredit
* @author Nam
* @notice On-chain Renewable Energy Credit (REC) issuance and retirement
*/
contract RenewableEnergyCredit is ERC20, Ownable {
mapping(address => bool) public approvedProducers;
mapping(address => bool) public approvedOracles;
uint256 public creditsPerMWh; // tokens per MWh
// -------------------- EVENTS --------------------
event ProducerApproved(address producer);
event OracleApproved(address oracle);
event CreditsMinted(address indexed producer, uint256 amount);
event CreditsRetired(address indexed account, uint256 amount);
// -------------------- CONSTRUCTOR --------------------
constructor(uint256 _creditsPerMWh)
ERC20("Renewable Energy Credit", "REC")
{
creditsPerMWh = _creditsPerMWh;
}
// -------------------- ROLE MANAGEMENT --------------------
function approveProducer(address _producer) external onlyOwner {
approvedProducers[_producer] = true;
emit ProducerApproved(_producer);
}
function approveOracle(address _oracle) external onlyOwner {
approvedOracles[_oracle] = true;
emit OracleApproved(_oracle);
}
// -------------------- CREDIT ISSUANCE --------------------
function mintCredits(
address _producer,
uint256 _mwhGenerated
) external {
require(approvedOracles[msg.sender], "Not authorized oracle");
require(approvedProducers[_producer], "Not approved producer");
require(_mwhGenerated > 0, "Invalid amount");
uint256 credits = _mwhGenerated * creditsPerMWh;
_mint(_producer, credits);
emit CreditsMinted(_producer, credits);
}
// -------------------- CREDIT RETIREMENT --------------------
function retireCredits(uint256 _amount) external {
require(balanceOf(msg.sender) >= _amount, "Insufficient credits");
_burn(msg.sender, _amount);
emit CreditsRetired(msg.sender, _amount);
}
}