實現一個簡單的眾籌(ICO)合約
阿新 • • 發佈:2018-11-10
代幣的程式碼在我的另一篇文章:https://blog.csdn.net/qq_34493908/article/details/81842920,這裡的眾籌合約需要結合代幣合約,一個非常典型的眾籌專案是EOS,大家可以去搜一下。
實現一個眾籌合約需要分為以下幾步:
- 設定眾籌的時間,目標金額,兌換的價格,指定受益人
- 實現以太幣和代幣的轉換
- (受益人,一般是合約建立者)提款或者(投資者)退款
下面的眾籌合約都有詳細的註釋,這裡不多說,詳細講解可看該視訊http://edu.51cto.com/course/14173.html:
pragma solidity ^0.4 .20;
interface token{
function transfer(address _to,uint amount) external;
}
contract Ico{
uint public fundingGoal; //眾籌的目標價格
uint public deadline; //眾籌的截止時間
uint public price; //以太幣和代幣的兌換價格
address beneficiary; //眾籌的受益人,這裡設定為合約的建立者
uint funAmount; //當前募集的總額
token public tokenReward;//定義一個合約型別
mapping(address => uint256) public balanceOf; //定義一個mapping來記錄每個人打入的以太幣
event FundTransfer(address backer,uint amount); //定義一個事件,記錄每次募集的記錄
event GoadReached(bool success); //定義眾籌完成時的事件
//建構函式
constructor(uint fundingGoalInEthers,
uint durationMinutes,
uint etherCostofEachToken,
address addresOfToken){
fundingGoal = fundingGoalInEthers * 1 ether;
deadline = now + durationMinutes * 1 minutes;
price =etherCostofEachToken * 1 ether;// 1eth = 10**18 wei
tokenReward = token(addresOfToken); //把一個地址強制轉換為一個合約型別,這個地址其實就是合約地址
beneficiary = msg.sender; //受益人預設是合約的建立者
}
//定義一個回退函式,回退函式沒有函式名,並且定義的型別為payable,這樣在有以太幣打來這個合約時,就會觸發這個函式來來計算使用者打過來的以太幣。
function() public payable{
require(now<deadline);//判斷現在的時間是否小於截止日期,否的話就觸發異常,捐贈時間必須小於截止時間
//拿到使用者傳送過來的以太幣
uint amount = msg.value; //單位為:wei
uint tokenAmount = amount / price; //單位為:eth
balanceOf[msg.sender] += amount; //記錄使用者自己每次眾籌累積的以太幣數量
funAmount += amount; //記錄當前募集的總額
tokenReward.transfer(msg.sender,tokenAmount);//返回相應代幣給捐贈者
emit FundTransfer(msg.sender,amount); //觸發記錄事件
}
//提款函式
function withDrawal() public{
require(now >= deadline);//提款時間必須大於截止時間
if (funAmount >= fundingGoal){
//眾籌的金額達到目標金額,受益人可轉走
if (beneficiary==msg.sender){
beneficiary.transfer(funAmount);
}
}else{
//如果還沒有達到目標金額,其他使用者可以轉走自己之前捐的金額
uint amount=balanceOf[msg.sender];
if (amount>0){
msg.sender.transfer(amount);
balanceOf[msg.sender]=0;
}
}
}
//檢測眾籌是否完成的函式
function checkGoadReached() public{
require(now >= deadline);
if (funAmount>=fundingGoal){
emit GoadReached(true);
}
}
}