Learn Solidity - Build Decentralized Application in Ethereum

Learn Solidity: Complete Example: Crowd Funding Smart Contract

In this post, we will go through the complete example of a sample crowd funding smart contract. This is a fully working smart contract for crowd sale. [pastacode lang=”javascript” manual=”pragma%20solidity%200.4.8%3B%0A%0Acontract%20CrowdFunder%20%7B%0A%20%20%20%20%0A%20%20%20%20address%20public%20creator%3B%0A%20%20%20%20address%20public%20fundRecipient%3B%20%2F%2F%20creator%20may%20be%20different%20than%20recipient%0A%20%20%20%20uint%20public%20minimumToRaise%3B%20%2F%2F%20required%20to%20reach%20at%20least%20this%20much%2C%20else%20everyone%20gets%20refund%0A%20%20%20%20string%20campaignUrl%3B%20%0A%20%20%20%20byte%20constant%20version%20%3D%201%3B%0A%0A%20%20%20%20%2F%2F%20Data%20structures%0A%20%20%20%20enum%20State%20%7B%0A%20%20%20%20%20%20%20%20Fundraising%2C%0A%20%20%20%20%20%20%20%20ExpiredRefund%2C%0A%20%20%20%20%20%20%20%20Successful%2C%0A%20%20%20%20%20%20%20%20Closed%0A%20%20%20%20%7D%0A%0A%20%20%20%20struct%20Contribution%20%7B%0A%20%20%20%20%20%20%20%20uint%20amount%3B%0A%20%20%20%20%20%20%20%20address%20contributor%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20State%20variables%0A%20%20%20%20State%20public%20state%20%3D%20State.Fundraising%3B%20%2F%2F%20initialize%20on%20create%0A%20%20%20%20uint%20public%20totalRaised%3B%0A%20%20%20%20uint%20public%20currentBalance%3B%0A%20%20%20%20uint%20public%20raiseBy%3B%0A%20%20%20%20uint%20public%20completeAt%3B%0A%20%20%20%20Contribution%5B%5D%20contributions%3B%0A%0A%20%20%20%20event%20LogFundingReceived(address%20addr%2C%20uint%20amount%2C%20uint%20currentTotal)%3B%0A%20%20%20%20event%20LogWinnerPaid(address%20winnerAddress)%3B%0A%20%20%20%20event%20LogFunderInitialized(%0A%20%20%20%20%20%20%20%20address%20creator%2C%0A%20%20%20%20%20%20%20%20address%20fundRecipient%2C%0A%20%20%20%20%20%20%20%20string%20url%2C%0A%20%20%20%20%20%20%20%20uint%20_minimumToRaise%2C%20%0A%20%20%20%20%20%20%20%20uint256%20raiseby%0A%20%20%20%20)%3B%0A%0A%20%20%20%20modifier%20inState(State%20_state)%20%7B%0A%20%20%20%20%20%20%20%20if%20(state%20!%3D%20_state)%20throw%3B%0A%20%20%20%20%20%20%20%20_%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20modifier%20isCreator()%20%7B%0A%20%20%20%20%20%20%20%20if%20(msg.sender%20!%3D%20creator)%20throw%3B%0A%20%20%20%20%20%20%20%20_%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Wait%201%20hour%20after%20final%20contract%20state%20before%20allowing%20contract%20destruction%0A%20%20%20%20modifier%20atEndOfLifecycle()%20%7B%0A%20%20%20%20%20%20%20%20if(!((state%20%3D%3D%20State.ExpiredRefund%20%7C%7C%20state%20%3D%3D%20State.Successful)%20%26%26%20completeAt%20%2B%201%20hours%20%3C%20now))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20_%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20CrowdFunder(%0A%20%20%20%20%20%20%20%20uint%20timeInHoursForFundraising%2C%0A%20%20%20%20%20%20%20%20string%20_campaignUrl%2C%0A%20%20%20%20%20%20%20%20address%20_fundRecipient%2C%0A%20%20%20%20%20%20%20%20uint%20_minimumToRaise)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20creator%20%3D%20msg.sender%3B%0A%20%20%20%20%20%20%20%20fundRecipient%20%3D%20_fundRecipient%3B%0A%20%20%20%20%20%20%20%20campaignUrl%20%3D%20_campaignUrl%3B%0A%20%20%20%20%20%20%20%20minimumToRaise%20%3D%20_minimumToRaise%20*%201000000000000000000%3B%20%2F%2Fconvert%20to%20wei%0A%20%20%20%20%20%20%20%20raiseBy%20%3D%20now%20%2B%20(timeInHoursForFundraising%20*%201%20hours)%3B%0A%20%20%20%20%20%20%20%20currentBalance%20%3D%200%3B%0A%20%20%20%20%20%20%20%20LogFunderInitialized(%0A%20%20%20%20%20%20%20%20%20%20%20%20creator%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20fundRecipient%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20campaignUrl%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20minimumToRaise%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20raiseBy)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20contribute()%0A%20%20%20%20public%0A%20%20%20%20inState(State.Fundraising)%20payable%20returns%20(uint256)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20contributions.push(%0A%20%20%20%20%20%20%20%20%20%20%20%20Contribution(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20amount%3A%20msg.value%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20contributor%3A%20msg.sender%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D)%20%2F%2F%20use%20array%2C%20so%20can%20iterate%0A%20%20%20%20%20%20%20%20%20%20%20%20)%3B%0A%20%20%20%20%20%20%20%20totalRaised%20%2B%3D%20msg.value%3B%0A%20%20%20%20%20%20%20%20currentBalance%20%3D%20totalRaised%3B%0A%20%20%20%20%20%20%20%20LogFundingReceived(msg.sender%2C%20msg.value%2C%20totalRaised)%3B%0A%0A%20%20%20%20%20%20%20%20checkIfFundingCompleteOrExpired()%3B%0A%20%20%20%20%20%20%20%20return%20contributions.length%20-%201%3B%20%2F%2F%20return%20id%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20checkIfFundingCompleteOrExpired()%20%7B%0A%20%20%20%20%20%20%20%20if%20(totalRaised%20%3E%20minimumToRaise)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20state%20%3D%20State.Successful%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20payOut()%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20could%20incentivize%20sender%20who%20initiated%20state%20change%20here%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(%20now%20%3E%20raiseBy%20)%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20state%20%3D%20State.ExpiredRefund%3B%20%2F%2F%20backers%20can%20now%20collect%20refunds%20by%20calling%20getRefund(id)%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20completeAt%20%3D%20now%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20payOut()%0A%20%20%20%20%20%20%20%20public%0A%20%20%20%20%20%20%20%20inState(State.Successful)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(!fundRecipient.send(this.balance))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20state%20%3D%20State.Closed%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20currentBalance%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20LogWinnerPaid(fundRecipient)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20getRefund(uint256%20id)%0A%20%20%20%20%20%20%20%20public%0A%20%20%20%20%20%20%20%20inState(State.ExpiredRefund)%20%0A%20%20%20%20%20%20%20%20returns%20(bool)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(contributions.length%20%3C%3D%20id%20%7C%7C%20id%20%3C%200%20%7C%7C%20contributions%5Bid%5D.amount%20%3D%3D%200%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20uint%20amountToRefund%20%3D%20contributions%5Bid%5D.amount%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20contributions%5Bid%5D.amount%20%3D%200%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if(!contributions%5Bid%5D.contributor.send(amountToRefund))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20contributions%5Bid%5D.amount%20%3D%20amountToRefund%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20else%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20totalRaised%20-%3D%20amountToRefund%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20currentBalance%20%3D%20totalRaised%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20true%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20removeContract()%0A%20%20%20%20%20%20%20%20public%0A%20%20%20%20%20%20%20%20isCreator()%0A%20%20%20%20%20%20%20%20atEndOfLifecycle()%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20selfdestruct(msg.sender)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20creator%20gets%20all%20money%20that%20hasn’t%20be%20claimed%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20()%20%7B%20throw%3B%20%7D%0A%20%20%20%20%7D” message=””…
Read More