Build a decentralized crowdfunding platform where users can create campaigns, contribute funds, and withdraw if goals are met. Learn about handling Ether, time-based conditions, and state management.
Create a crowdfunding contract with campaign management.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Crowdfunding {
struct Campaign {
address creator;
uint256 goal;
uint256 deadline;
uint256 amountRaised;
bool claimed;
mapping(address => uint256) contributions;
}
uint256 public campaignCount;
mapping(uint256 => Campaign) public campaigns;
event CampaignCreated(uint256 indexed id, address creator, uint256 goal, uint256 deadline);
event ContributionMade(uint256 indexed id, address contributor, uint256 amount);
event FundsClaimed(uint256 indexed id, uint256 amount);
event RefundClaimed(uint256 indexed id, address contributor, uint256 amount);
function createCampaign(uint256 _goal, uint256 _duration) external returns (uint256) {
require(_goal > 0, "Goal must be greater than 0");
require(_duration > 0, "Duration must be greater than 0");
uint256 campaignId = campaignCount++;
Campaign storage campaign = campaigns[campaignId];
campaign.creator = msg.sender;
campaign.goal = _goal;
campaign.deadline = block.timestamp + _duration;
emit CampaignCreated(campaignId, msg.sender, _goal, campaign.deadline);
return campaignId;
}
function contribute(uint256 _campaignId) external payable {
Campaign storage campaign = campaigns[_campaignId];
require(block.timestamp < campaign.deadline, "Campaign ended");
require(msg.value > 0, "Must contribute something");
campaign.contributions[msg.sender] += msg.value;
campaign.amountRaised += msg.value;
emit ContributionMade(_campaignId, msg.sender, msg.value);
}
function claimFunds(uint256 _campaignId) external {
Campaign storage campaign = campaigns[_campaignId];
require(msg.sender == campaign.creator, "Not campaign creator");
require(block.timestamp >= campaign.deadline, "Campaign not ended");
require(campaign.amountRaised >= campaign.goal, "Goal not reached");
require(!campaign.claimed, "Already claimed");
campaign.claimed = true;
uint256 amount = campaign.amountRaised;
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
emit FundsClaimed(_campaignId, amount);
}
function claimRefund(uint256 _campaignId) external {
Campaign storage campaign = campaigns[_campaignId];
require(block.timestamp >= campaign.deadline, "Campaign not ended");
require(campaign.amountRaised < campaign.goal, "Goal was reached");
uint256 contribution = campaign.contributions[msg.sender];
require(contribution > 0, "No contribution");
campaign.contributions[msg.sender] = 0;
(bool success, ) = msg.sender.call{value: contribution}("");
require(success, "Refund failed");
emit RefundClaimed(_campaignId, msg.sender, contribution);
}
}Sign up to save your progress and earn 100 points upon completion.