Education Crowdfunding Platform

What it does:
Allows students, educators, or institutions to raise funds for educational projects, scholarships, or course development on-chain.

Why it matters:
Enables transparent fundraising, reduces intermediaries, builds trust between backers and recipients, and ensures funds are used as intended.

How it works:

  • Campaign creator sets up a crowdfunding project with funding goal, deadline, and purpose

  • Backers contribute funds directly to the contract

  • Smart contract tracks contributions and ensures total does not exceed goal

  • Funds are released to the recipient when the funding goal is met

  • If funding goal is not reached by the deadline, contributors can claim refunds

  • Contribution and withdrawal history are fully auditable on-chain

  • Can integrate with scholarships, tuition, or learn-to-earn contracts for automated disbursement

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

/**
 * @title EducationCrowdfunding
 * @author Nam
 * @notice Decentralized platform for funding educational projects
 */
contract EducationCrowdfunding {

    struct Campaign {
        address payable recipient;
        string description;
        uint256 goal;
        uint256 pledged;
        uint256 deadline;
        bool completed;
        bool refunded;
    }

    uint256 public campaignCount;
    mapping(uint256 => Campaign) public campaigns;
    mapping(uint256 => mapping(address => uint256)) public contributions;

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

    event CampaignCreated(uint256 indexed campaignId, address indexed recipient, uint256 goal, uint256 deadline);
    event ContributionMade(uint256 indexed campaignId, address indexed backer, uint256 amount);
    event FundsReleased(uint256 indexed campaignId, uint256 amount);
    event RefundIssued(uint256 indexed campaignId, address indexed backer, uint256 amount);

    // -------------------- CAMPAIGN MANAGEMENT --------------------

    function createCampaign(address payable _recipient, string calldata _description, uint256 _goal, uint256 _duration) external {
        require(_recipient != address(0), "Invalid recipient");
        require(_goal > 0, "Goal must be >0");
        require(_duration > 0, "Duration must be >0");

        campaignCount += 1;
        campaigns[campaignCount] = Campaign({
            recipient: _recipient,
            description: _description,
            goal: _goal,
            pledged: 0,
            deadline: block.timestamp + _duration,
            completed: false,
            refunded: false
        });

        emit CampaignCreated(campaignCount, _recipient, _goal, block.timestamp + _duration);
    }

    function contribute(uint256 _campaignId) external payable {
        Campaign storage c = campaigns[_campaignId];
        require(block.timestamp  0, "Contribution must be >0");
        require(!c.completed, "Campaign completed");

        c.pledged += msg.value;
        contributions[_campaignId][msg.sender] += msg.value;

        emit ContributionMade(_campaignId, msg.sender, msg.value);

        if (c.pledged >= c.goal) {
            c.completed = true;
            c.recipient.transfer(c.pledged);
            emit FundsReleased(_campaignId, c.pledged);
        }
    }

    function claimRefund(uint256 _campaignId) external {
        Campaign storage c = campaigns[_campaignId];
        require(block.timestamp > c.deadline, "Campaign still active");
        require(!c.completed, "Campaign successful");
        uint256 amount = contributions[_campaignId][msg.sender];
        require(amount > 0, "No contribution");

        contributions[_campaignId][msg.sender] = 0;
        payable(msg.sender).transfer(amount);

        emit RefundIssued(_campaignId, msg.sender, amount);
    }

    receive() external payable {}
}