區塊鏈智能合約編程六:代幣ICO的實現

何爲代幣ICO

ICO是英文Initial Coin Offering,意思是代幣首次發行,其概念源自於股票市場的IPO :Initial Coin Offering,首次公開募資。在以太坊網絡中,以太幣Eth是最原始的代幣,也是除了比特幣之後公衆最爲認可、以太坊網絡價值最高的代幣。代幣ICO實際上就是項目方以一定的實際項目爲基礎,向公衆募集以太幣資金,並把自己項目代幣作爲獎勵。(本質上就是代幣跟以太幣的比例兌換)

通俗來講,就如龍泉劍商家在平臺上發起衆籌,募集指定目標資金如40萬,完成之後爲每個參與者鑄劍作爲獎勵的過程。

代幣ICO的核心三要素:

衆籌時間

衆籌價格

衆籌受益人

代幣ICO的實現流程:

一:設定衆籌時間、目標、價格、受益人

二:實現以太幣與代幣之間的交換

三:實現受益人提款(衆籌成功)、投資者退款(衆籌失敗)

​
​
​
pragma solidity ^0.4.24;

contract SafeMath {//用來安全計算的合約,防止加乘溢出
  function safeMul(uint256 a, uint256 b) internal returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function safeDiv(uint256 a, uint256 b) internal returns (uint256) {
    assert(b > 0);
    uint256 c = a / b;
    assert(a == b * c + a % b);
    return c;
  }

  function safeSub(uint256 a, uint256 b) internal returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function safeAdd(uint256 a, uint256 b) internal returns (uint256) {
    uint256 c = a + b;
    assert(c>=a && c>=b);
    return c;
  }

  function assert(bool assertion) internal {
    if (!assertion) {
      throw;
    }
  }
}

interface token{//這裏是提供調用ERC20代幣的接口
    function transfer(address _to, uint256 _value) external;
}
contract ICO{
    uint public  goal;//發行目標,也就是募集以太幣的數量
    uint public  price;//發行價格
    uint public duration;//截至時間
    address public beneficial;//受益人(提款人)
    token public tokenReword;//用來調用的ERC20合約
    
    //構造函數
    constructor( uint _goal,uint _price, uint _duration, address _token) public {
        goal=_goal;
        price=_price * 1 ether;//指定價格爲一個單位以太幣,10的18次方WEI
        duration=now + _duration * 60 days;//截至時間爲現在+60天。
        tokenReword=token(_token);//把合約地址轉爲token對象
        beneficial=msg.sender;//指定受益人爲智能合約發佈者    
    }
    
   
    
}

​

​

​

這裏要說明一下 interface token,在衆籌之前首先是把ERC20代幣部署到以太坊主網中,然後我們在部署衆籌合約。兩個合約之間可以互相調用函數,這稱之爲消息調用。在衆籌項目中,我們是要把自己項目代幣作爲獎勵返回給投資者的,也就是說調用transfer函數把代幣打入到投資者賬戶,而我們的賬戶則是用來接收以太幣的。

第二步:實現以太幣與代幣之間的交換

​
mapping (address => uint) refund;//用來記錄投資者投資了多少個以太幣 

function () public payable{//這裏是一個fallback函數,當投資者調用這個函數,打入以太幣時自動執行
       require(now <duration);
       uint amount =msg.value /price;//計算以太幣與代幣兌換比例,這裏爲簡單計算,採用1:1兌換
       safeAdd(refund[msg.sender],amount);
       tokenReword.transfer(msg.sender,amount);
       emit FundingTransfer(msg.sender,amount);
       
       
   }
  //記錄向投資者轉入多少個代幣事件
   event FundingTransfer(address _to,uint amount);

​

第三步實現提款、退款

 uint realmount;//用來記錄投資者打入的eth總和
function () public payable{
       require(now <duration);
       uint amount =msg.value /price;
       refund[msg.sender]=safeAdd(refund[msg.sender],amount);
       realamount=safeAdd(realamount,amount);//增加投資者打入的eth總和
       tokenReword.transfer(msg.sender,amount);
       emit FundingTransfer(msg.sender,amount);
       
       
   }

function withdrawl() public {//提款、退款函數
       require(now >=duration);判斷當前時間要大於截止時間
       if(realamount>=goal){//投資者打入的eth總和要大於目標數量
           require(beneficial==msg.sender);
           beneficial.transfer(realamount);//受益人提款
       }else{
           msg.sender.transfer(refund[msg.sender]);//投資者退款
           refund[msg.sender]=0;
       }
     
   }
  //判斷是否實現衆籌函數
   function checkIsReachGoal() public{
        require(now >=duration);
        if(realamount>=goal){
            emit ReachGoal(true);
        }
   }
   //判斷是否實現衆籌事件
   event ReachGoal(bool);

最後代碼如下:

pragma solidity ^0.4.24;

interface token{
    function transfer(address _to, uint256 _value) external;
}


contract SafeMath {
  function safeMul(uint256 a, uint256 b) internal returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function safeDiv(uint256 a, uint256 b) internal returns (uint256) {
    assert(b > 0);
    uint256 c = a / b;
    assert(a == b * c + a % b);
    return c;
  }

  function safeSub(uint256 a, uint256 b) internal returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function safeAdd(uint256 a, uint256 b) internal returns (uint256) {
    uint256 c = a + b;
    assert(c>=a && c>=b);
    return c;
  }

  function assert(bool assertion) internal {
    if (!assertion) {
      throw;
    }
  }
}


contract ICO is SafeMath{
    uint public  goal;
    uint public realamount;
    uint public  price;
    uint public duration;
    address public beneficial;
    token public tokenReword;
    
    mapping (address => uint) refund;
    
    constructor( uint _goal,uint _price, uint _duration, address _token) public {
        goal=_goal;
        price=_price * 1 ether;
        duration= now + _duration * 60 days;
        tokenReword=token(_token);
        beneficial=msg.sender;    
    }
    
   function () public payable{
       require(now <duration);
       uint amount =msg.value /price;
       refund[msg.sender]=safeAdd(refund[msg.sender],amount);
       realamount=safeAdd(realamount,amount);
       tokenReword.transfer(msg.sender,amount);
       emit FundingTransfer(msg.sender,amount);
       
       
   }
   event FundingTransfer(address _to,uint amount);
   
   function withdrawl() public {
       require(now >=duration);
       if(realamount>=goal){
           require(beneficial==msg.sender);
           beneficial.transfer(realamount);
       }else{
           msg.sender.transfer(refund[msg.sender]);
           refund[msg.sender]=0;
       }
     
   }
   function checkIsReachGoal() public{
        require(now >=duration);
        if(realamount>=goal){
            emit ReachGoal(true);
        }
   }
   
   event ReachGoal(bool);
    
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章