Warning: This contract will compile on the /future/ Glow release.
How does crowdfunding.glow work?
In this day and age, crowdfunding campaigns are well known. Platforms like kickstarter.com and GoFund.me have made the crowdfunding model well known across the world as an excellent way to bring together the resources of several parties that do not know each other and yet are willing to contribute some money towards a common goal.
Glow code
1 data Action = Pledge(TokenAmount) | Close | Reclaim(TokenAmount);23 let platformCommission amount = quotient(amount, 100);45 @interaction6 let crowdfunding = (target: TokenAmount,7 expirationTime : Timestamp) => {8 require! expirationTime > currentTime();910 let rec crowdfund = (ledger : Table(TokenAmount <- Participant),11 totalPledged: TokenAmount) => {12 assert! totalPledged == totalAmount(ledger);13 choice {14 | ForAllParticipant (NewPledger) {15 @NewPledger amount =16 input(["Enter next pledge"], TokenAmount);17 publish! NewPledger -> Pledge(amount);18 deposit! NewPledger -> amount;19 require! currentTime() < expirationTime;20 crowdfund(Table.add(ledger, NewPledger, amount),21 totalPledged + amount);2223 | publish! Organizer -> Success;24 require! currentTime() >= expirationTime;25 require! totalPledged >= target;26 let commission = platformCommission(totalPledged);27 withdraw! Platform <- commission;28 withdraw! Organizer <- totalPledged - commission;2930 | ForAllParticipant(Pledger)31 publish! Pledger -> Reclaim(amount);32 require! currentTime() >= expirationTime;33 require! totalPledged < target;34 require! Table.get(ledger, Pledger) == amount;35 withdraw! Pledger <- amount; //(ref: return_amount_to_pledger)36 crowdfund(Table.remove(ledger, Pledger), //(ref: remove_pledger_from_ledger)37 totalPledged - amount);38 }39 crowdfund({}, 0);40 }
- When creating a campaign, there is a goal and an expiration time.
- We create a
ledger
where we record thePledgers
and the total amoun the campaign has raised so far
Now three things can happen:
- There is a new pledge
- The campaign was a successor
- A pledger reclaims a refund
Let's look at all three in detail.
Dealing with a new pledge
- Any participant can pledge.
- The
NewPledger
mustdeposit!
her amount to the contract. - And the pledge is stored in the
Ledger
Campaign is successful
- When the organizer declares the campaign a success.
- We must make sure the deadline for the campaign has passed and
- The
totalPledged
surpassed thetarget
.
Pledger requests a reimbursement
- When a pledger requests a reimbursement.
- We check that the expiration date has passed
- that the goal wasn't achieved
- Then we check that the amount that is reclaiming is the same we have stored in the Ledger.
- We return the amount to the Pledger and remove it from the Ledger.
Lessons learned
- Explicit timeout
- Unrestricted open set of participants
- Choice restricted to timeouts and open participation
Challenge
Can you write a version of this contract that does the following: a) Automatically decides if the campaign was successful or not (given the timeout). b) Reimburses all the pledges automatically.