Created
April 21, 2022 18:20
-
-
Save aesthezel/662696ecd4af3f7150bea799860f3ea7 to your computer and use it in GitHub Desktop.
A crowdfunding smart contract example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: GPL-3.0 | |
pragma solidity >=0.7.0 <0.9.0; | |
contract CrowdFunding | |
{ | |
uint private projectIdCounter; | |
struct Contribution | |
{ | |
address contributor; | |
uint ammount; | |
} | |
enum ProjectState {Open, Close} | |
struct Project | |
{ | |
uint id; | |
string name; | |
string description; | |
address payable author; | |
ProjectState state; | |
uint funds; | |
uint goal; | |
} | |
Project[] public projects; | |
mapping(uint => Contribution[]) public contributions; | |
event OnProjectCreated | |
( | |
uint id, | |
string name, | |
string description, | |
uint goal | |
); | |
event OnProjectFounded | |
( | |
uint projectId, | |
uint ammount, | |
ProjectState state | |
); | |
event OnProjectStateChange | |
( | |
uint projectId, | |
ProjectState state | |
); | |
error HandleStateNotDefined(ProjectState exception); | |
// Decorator Pattern | |
modifier isAuthor(uint projectIndex) | |
{ | |
require | |
( | |
msg.sender == projects[projectIndex].author, | |
"Only owner can change the project name" | |
); | |
_; // Continue the wrapped function | |
} | |
modifier isNotAuthor(uint projectIndex) | |
{ | |
require | |
( | |
msg.sender != projects[projectIndex].author, | |
"Founder don't collaborate in own projects" | |
); | |
_; | |
} | |
function createProject(string calldata name, string calldata description, uint goal) public | |
{ | |
bytes memory nameInBytes = bytes(name); | |
require(goal > 0, "Goal must be greater than 0"); | |
require(nameInBytes.length > 0 , "Name can't be empty"); | |
Project memory project = Project(projectIdCounter, name, description, payable(msg.sender), ProjectState.Open, 0, goal); | |
projects.push(project); | |
emit OnProjectCreated(projectIdCounter, name, description, goal); | |
projectIdCounter++; | |
} | |
function fundProject(uint projectIndex) public payable isNotAuthor(projectIndex) | |
{ | |
Project memory project = projects[projectIndex]; | |
require(project.state != ProjectState.Close, "The project is closed! Can't receive more funds..."); | |
require(msg.value > 0, "Fund value most be greater than 0"); | |
project.author.transfer(msg.value); | |
project.funds += msg.value; | |
if(project.funds >= project.goal) | |
{ | |
project.state = ProjectState.Close; | |
} | |
contributions[project.id].push(Contribution(msg.sender, msg.value)); | |
projects[projectIndex] = project; | |
emit OnProjectFounded(project.id, msg.value, project.state); | |
} | |
function changeProjectState(uint projectIndex, ProjectState newState) public isAuthor(projectIndex) | |
{ | |
Project memory project = projects[projectIndex]; | |
require(project.state != newState, "The new state must be different"); | |
if(newState == ProjectState.Open || newState == ProjectState.Close) | |
{ | |
project.state = newState; | |
emit OnProjectStateChange(project.id, project.state); | |
projects[projectIndex] = project; | |
} | |
else | |
{ | |
revert HandleStateNotDefined(newState); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment