编译器
0.8.28+commit.7893614a
文件 1 的 2:Crowdfunding.sol
pragma solidity ^0.8.0;
contract Crowdfunding {
string public name;
string public description;
uint256 public goal;
uint256 public deadline;
address public owner;
bool public paused;
enum CampaignState {Active,Successful,Failed}
CampaignState public state;
struct Tier {
string name;
uint256 amount;
uint256 backers;
}
struct Backer{
uint256 totalContribution;
mapping(uint256 => bool) fundedTiers;
}
Tier[] public tiers;
mapping(address => Backer) public backers;
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_;
}
modifier campaignOpen(){
require(state == CampaignState.Active,"Campaign is not active");
_;
}
modifier notPaused(){
require(!paused, "Contract is paused");
_;
}
constructor (
address _owner,
string memory _name,
string memory _description,
uint256 _goal,
uint256 _duratyionInDays
){
name = _name;
description = _description;
goal = _goal;
deadline = block.timestamp + (_duratyionInDays * 1 days);
owner = _owner;
state = CampaignState.Active;
}
function checkAndUpdateCampaignState() internal {
if(state == CampaignState.Active){
if(block.timestamp >= deadline){
state = address(this).balance >= goal ? CampaignState.Successful : CampaignState.Failed;
}else {
state = address(this).balance >= goal ? CampaignState.Successful : CampaignState.Active;
}
}
}
function fund(uint256 _tierIndex) public payable {
require(_tierIndex < tiers.length,"Invalid tierIndex");
require(msg.value == tiers[_tierIndex].amount, "Invalid value");
checkAndUpdateCampaignState();
}
function adddTier(
string memory _name,
uint256 _amount
) public onlyOwner {
require(_amount > 0, "Amount must be greater than 0.");
tiers.push(Tier(_name,_amount, 0));
}
function removeTier(uint256 _index) public onlyOwner {
require(_index < tiers.length, "Tier does not exist");
tiers[_index] = tiers[tiers.length - 1];
tiers.pop();
}
function withdraw() public onlyOwner {
checkAndUpdateCampaignState();
require(state == CampaignState.Successful, "CampaignState is not successful");
uint256 balance = address(this).balance;
require(balance > 0, "No balance to withdraw");
payable(owner).transfer(balance);
}
function getContractBalance() public view returns (uint256) {
return address(this).balance;
}
function refund() public {
checkAndUpdateCampaignState();
require(state == CampaignState.Failed, "Refunds not state");
uint256 amount = backers[msg.sender].totalContribution;
require(amount > 0, "No contribution to refund");
backers[msg.sender].totalContribution = 0;
payable(msg.sender).transfer(amount);
}
function hasFundedTier(address _backer, uint256 _tierIndex) public view returns (bool){
return backers[_backer].fundedTiers[_tierIndex];
}
function getTiers() public view returns (Tier[] memory){
return tiers;
}
}
文件 2 的 2:CrowdfundingFactory.sol
pragma solidity ^0.8.0;
import {Crowdfunding} from "./Crowdfunding.sol";
contract CrowdfundingFactory{
address public owner;
bool public paused;
struct Campaign {
address campaignAddress;
address owner;
string name;
uint256 creationTime;
}
Campaign[] public campaigns;
mapping(address => Campaign[]) public userCampaigns;
modifier onlyOwner() {
require(msg.sender == owner, "Not owner.");
_;
}
modifier notPaused(){
require(!paused, "Factory is paused");
_;
}
constructor(){
owner = msg.sender;
}
function coreateCampaign(
string memory _name,
string memory _description,
uint256 _goal,
uint256 _durationInDays
)external notPaused{
Crowdfunding newCampaign = new Crowdfunding(
msg.sender,
_name,
_description,
_goal,
_durationInDays
);
address campaignAddress = address(newCampaign);
Campaign memory campaign = Campaign({
campaignAddress:campaignAddress,
owner:msg.sender,
name:_name,
creationTime:block.timestamp
});
campaigns.push(campaign);
userCampaigns[msg.sender].push(campaign);
}
function getUserCampaigns(address _user) external view returns (Campaign[] memory){
return userCampaigns[_user];
}
function getAllCampaigns() external view returns (Campaign[] memory){
return campaigns;
}
function togglePause() external onlyOwner{
paused = !paused;
}
}
{
"compilationTarget": {
"src/CrowdfundingFactory.sol": "CrowdfundingFactory"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@thirdweb-dev/=node_modules/@thirdweb-dev/",
":forge-std/=lib/forge-std/src/"
]
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"campaigns","outputs":[{"internalType":"address","name":"campaignAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"creationTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_description","type":"string"},{"internalType":"uint256","name":"_goal","type":"uint256"},{"internalType":"uint256","name":"_durationInDays","type":"uint256"}],"name":"coreateCampaign","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllCampaigns","outputs":[{"components":[{"internalType":"address","name":"campaignAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"creationTime","type":"uint256"}],"internalType":"struct CrowdfundingFactory.Campaign[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserCampaigns","outputs":[{"components":[{"internalType":"address","name":"campaignAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"creationTime","type":"uint256"}],"internalType":"struct CrowdfundingFactory.Campaign[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"togglePause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userCampaigns","outputs":[{"internalType":"address","name":"campaignAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"creationTime","type":"uint256"}],"stateMutability":"view","type":"function"}]