区块链智能合约编程六:代币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);
    
}
发布了7 篇原创文章 · 获赞 7 · 访问量 5352

猜你喜欢

转载自blog.csdn.net/qq_42247900/article/details/82720403
今日推荐