Using your governance token, you can create a crowdsale contract to raise funds to bring your project to life.
Since your ZK Rollup is EVM-compatible, dApps should be written in Solidity. If you are new to this programming language, please learn more about it here.
Write a Crowdsale smart contract
It turns out that writing the Crowdsale smart contract is very simple. Here is a basic contract to provide decentralized crowdfunding on Bitcoin Virtual Machine.
// SPDX-License-Identifier: MITpragmasolidity ^0.8.17;interface IERC20 {functiontransfer(address,uint) externalreturns (bool);functiontransferFrom(address,address,uint) externalreturns (bool);}contract CrowdSale {eventLaunch(uint id,addressindexed creator,uint goal,uint32 startAt,uint32 endAt );eventCancel(uint id);eventPledge(uintindexed id, addressindexed caller, uint amount);eventUnpledge(uintindexed id, addressindexed caller, uint amount);eventClaim(uint id);eventRefund(uint id, addressindexed caller, uint amount);structCampaign {// Creator of campaignaddress creator;// Amount of tokens to raiseuint goal;// Total amount pledgeduint pledged;// Timestamp of start of campaignuint32 startAt;// Timestamp of end of campaignuint32 endAt;// True if goal was reached and creator has claimed the tokens.bool claimed; } IERC20 publicimmutable token;// Total count of campaigns created.// It is also used to generate id for new campaigns.uintpublic count;// Mapping from id to Campaignmapping(uint=> Campaign) public campaigns;// Mapping from campaign id => pledger => amount pledgedmapping(uint=>mapping(address=>uint)) public pledgedAmount;constructor(address_token) { token =IERC20(_token); }functionlaunch(uint_goal,uint32_startAt,uint32_endAt) external {require(_startAt >= block.timestamp,"start at < now");require(_endAt >= _startAt,"end at < start at");require(_endAt <= block.timestamp +90days,"end at > max duration"); count +=1; campaigns[count] =Campaign({ creator: msg.sender, goal: _goal, pledged:0, startAt: _startAt, endAt: _endAt, claimed:false });emitLaunch(count, msg.sender, _goal, _startAt, _endAt); }functioncancel(uint_id) external { Campaign memory campaign = campaigns[_id];require(campaign.creator == msg.sender,"not creator");require(block.timestamp < campaign.startAt,"started");delete campaigns[_id];emitCancel(_id); }functionpledge(uint_id,uint_amount) external { Campaign storage campaign = campaigns[_id];require(block.timestamp >= campaign.startAt,"not started");require(block.timestamp <= campaign.endAt,"ended"); campaign.pledged += _amount; pledgedAmount[_id][msg.sender] += _amount; token.transferFrom(msg.sender,address(this), _amount);emitPledge(_id, msg.sender, _amount); }functionunpledge(uint_id,uint_amount) external { Campaign storage campaign = campaigns[_id];require(block.timestamp <= campaign.endAt,"ended"); campaign.pledged -= _amount; pledgedAmount[_id][msg.sender] -= _amount; token.transfer(msg.sender, _amount);emitUnpledge(_id, msg.sender, _amount); }functionclaim(uint_id) external { Campaign storage campaign = campaigns[_id];require(campaign.creator == msg.sender,"not creator");require(block.timestamp > campaign.endAt,"not ended");require(campaign.pledged >= campaign.goal,"pledged < goal");require(!campaign.claimed,"claimed"); campaign.claimed =true; token.transfer(campaign.creator, campaign.pledged);emitClaim(_id); }functionrefund(uint_id) external { Campaign memory campaign = campaigns[_id];require(block.timestamp > campaign.endAt,"not ended");require(campaign.pledged < campaign.goal,"pledged >= goal");uint bal = pledgedAmount[_id][msg.sender]; pledgedAmount[_id][msg.sender] =0; token.transfer(msg.sender, bal);emitRefund(_id, msg.sender, bal); }}
Crowdsale ERC20 token:
User creates a campaign.
Users can pledge, transferring their token to a campaign.
After the campaign ends, campaign creator can claim the funds if total amount pledged is more than the campaign goal.
Otherwise, campaign did not reach it's goal, users can withdraw their pledge.
Clone the smart contract examples
We've prepared a few different examples for you to get started.
Once the contracts are deployed, you can interact with them. We've prepared a few hardhat tasks to make it easy for you to interact with the contracts.