Green Energy Sharing Contract

What it does:
Enables producers of renewable energy (solar, wind) to share or sell excess electricity directly to consumers using on-chain metering and automated settlement.

Why it matters:
Decentralizes energy markets, incentivizes renewable production, reduces grid inefficiencies, and creates transparent, trustless energy transactions.

How it works:

  • Green energy producers register generation sources and payout addresses

  • Smart meters or energy oracles report verified production and consumption data

  • Energy units (kWh) are recorded on-chain as tradable credits

  • Consumers purchase energy credits directly from producers

  • Smart contract settles payments automatically per consumption

  • Excess energy can be shared, sold, or stored as credits

  • All energy flows and payments are auditable for sustainability reporting

      // SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
 * @title GreenEnergySharing
 * @author Nam
 * @notice Peer-to-peer renewable energy credit trading and settlement
 */
contract GreenEnergySharing is Ownable {

    struct Producer {
        bool active;
        uint256 pricePerKWh; // in wei or token units
        uint256 availableKWh;
    }

    mapping(address => Producer) public producers;
    mapping(address => bool) public approvedOracles;

    IERC20 public paymentToken; // address(0) = ETH if extended

    // -------------------- EVENTS --------------------

    event ProducerRegistered(address indexed producer, uint256 pricePerKWh);
    event EnergyReported(address indexed producer, uint256 kWh);
    event EnergyPurchased(address indexed producer, address indexed consumer, uint256 kWh, uint256 totalCost);

    // -------------------- CONSTRUCTOR --------------------

    constructor(address _paymentToken) {
        paymentToken = IERC20(_paymentToken);
    }

    // -------------------- ORACLE MANAGEMENT --------------------

    function approveOracle(address _oracle) external onlyOwner {
        approvedOracles[_oracle] = true;
    }

    function revokeOracle(address _oracle) external onlyOwner {
        approvedOracles[_oracle] = false;
    }

    // -------------------- PRODUCER SETUP --------------------

    function registerProducer(uint256 _pricePerKWh) external {
        require(_pricePerKWh > 0, "Invalid price");

        producers[msg.sender] = Producer({
            active: true,
            pricePerKWh: _pricePerKWh,
            availableKWh: 0
        });

        emit ProducerRegistered(msg.sender, _pricePerKWh);
    }

    // -------------------- ENERGY REPORTING --------------------

    function reportEnergy(address _producer, uint256 _kWh) external {
        require(approvedOracles[msg.sender], "Not authorized oracle");
        require(producers[_producer].active, "Producer inactive");

        producers[_producer].availableKWh += _kWh;
        emit EnergyReported(_producer, _kWh);
    }

    // -------------------- PURCHASE --------------------

    function purchaseEnergy(address _producer, uint256 _kWh) external {
        Producer storage p = producers[_producer];
        require(p.active, "Producer inactive");
        require(p.availableKWh >= _kWh, "Insufficient energy");

        uint256 cost = _kWh * p.pricePerKWh;
        paymentToken.transferFrom(msg.sender, _producer, cost);

        p.availableKWh -= _kWh;
        emit EnergyPurchased(_producer, msg.sender, _kWh, cost);
    }
}