iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 29
1
影片教學

Smart Contract 實戰教學系列 第 29

ICO Contract

  • 分享至 

  • xImage
  •  

講了那麼多的 ERC20 Token 的實作,怎麼可以最後沒提到 ICO Contract 要怎麼做呢XD 今天就讓我們來談談 ICO Contract 要怎麼寫吧!

本日合約:
ICOToken.sol

pragma solidity ^0.4.25;

import "browser/SafeMath.sol";
import "browser/IERC20.sol";

contract ICOToken is IERC20 {
    //=== Library =============================================================
    using SafeMath for uint256;
    //=========================================================================
    
    //=== State Variables =====================================================
    string mName = "ICOToken";
    uint8 mDecimals = 18;
    string mSymbol = "ICO";
    uint256 mTotalSupply = 0;
    mapping(address => uint256) mBalances;
    mapping(address => mapping(address => uint256)) mApprove;
    //=========================================================================
    
    
    
    //=== Constructor =========================================================
    constructor(
        string pName,
        uint8 pDecimals,
        string pSymbol,
        uint256 pTotalSupply)
        public
    {
        mName = pName;
        mDecimals = pDecimals;
        mSymbol = pSymbol;
        mTotalSupply = pTotalSupply;
        mBalances[msg.sender] = mBalances[msg.sender].add(mTotalSupply);
        emit Transfer(address(this), msg.sender, mTotalSupply);
    }
    //=========================================================================
    
    
    //=== ERC20 Functions =====================================================
    // 所有存在的 Token 數量
    function totalSupply() external view returns (uint256) {
        return mTotalSupply;
    }
    
    // 讀取 tokenOwner 這個 address 所持有的 Token 數量
    // address => uint256
    function balanceOf(address tokenOwner) external view returns (uint256 balance) {
        return mBalances[tokenOwner];
    }
    
    // 從 msg.sender 轉 tokens 個 Token 給 to 這個 address
    // msg.sender ---tokens---> to 
    function transfer(address to, uint256 tokens) external returns (bool success) {
        return _transfer(msg.sender, to, tokens);
    }
    
    // 得到 tokenOwner 授權給 spender 使用的 Token 剩餘數量
    function allowance(address tokenOwner, address spender) external view returns (uint256 remaining) {
        return mApprove[tokenOwner][spender];
    }
  
    // tokenOwner -> spender -> tokens
    // address => address => uint256
    // msg.sender 授權給 spender 可使用自己的 tokens 個 Token
    function approve(address spender, uint256 tokens) external returns (bool success) {
        mApprove[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        return true;
    }

    // 將 tokens 個 Token 從 from 轉到 to
    function transferFrom(address from, address to, uint256 tokens) external returns (bool success) {
        mApprove[from][msg.sender] = mApprove[from][msg.sender].sub(tokens);
        
        return _transfer(from, to, tokens);
    }
    
    function _transfer(address from, address to, uint256 tokens) internal returns (bool success) {
        mBalances[from] = mBalances[from].sub(tokens);
        mBalances[to] = mBalances[to].add(tokens);
        emit Transfer(from, to, tokens);
        return true;
    }
    //=========================================================================
    
    
    //=== ERC20 Detail information ============================================
    function name() public constant returns (string) {
        return mName;
    }
    
    function decimals() public constant returns (uint8) {
        return mDecimals;
    }
    
    function symbol() public constant returns (string) {
        return mSymbol;
    }
    //=========================================================================
}

ICOContract.sol

pragma solidity ^0.4.25;

import "browser/ICOToken.sol";

contract ICO {
    //=== Library =============================================================
    using SafeMath for uint;
    //=========================================================================
    
    
    //=== Enum ================================================================
    enum ICOState {INITIAL, START, END}
    //=========================================================================
    
    
    //=== State Variables =====================================================
    address private owner = 0x0;
    address public mTokenAddress = 0x0;
    uint256 mCaps = 0;
    uint256 mCurrentFund = 0;
    ICOState mICOState = ICOState.INITIAL;
    //=========================================================================
    
    
    //=== Modifiers ===========================================================
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }
    modifier beforICOStart() {
        require(mICOState == ICOState.INITIAL);
        _;
    }
    modifier whenICOStart() {
        require(mICOState == ICOState.START);
        _;
    }
    modifier whenICOEnd() {
        require(mICOState == ICOState.END);
        _;
    }
    //=========================================================================
    
    
    //=== Constructor =========================================================
    constructor() public {
        owner = msg.sender;
        string memory name = "HYDAIToken";
        uint8 decimals = 18;
        string memory symbol = "HYT";
        uint256 totalSupply = 1000*(10**18);
        mCaps = totalSupply;
        mTokenAddress = new ICOToken(name, decimals, symbol, totalSupply);
        mICOState = ICOState.INITIAL;
    }
    //=========================================================================
    
    
    //=== Functions ===========================================================
    function startICO() public onlyOwner beforICOStart {
        mICOState = ICOState.START;
    }
    function endICO() public onlyOwner whenICOStart {
        mICOState = ICOState.END;
        owner.transfer(address(this).balance);
        IERC20(mTokenAddress).transfer(owner, mCaps.sub(mCurrentFund));
    }
    //=========================================================================
    
    
    //=== Fallback Function ===================================================
    function() public payable whenICOStart {
        require(msg.value > 0);
        require(mCaps >= mCurrentFund + msg.value);
        mCurrentFund = mCurrentFund.add(msg.value);
        IERC20(mTokenAddress).transfer(msg.sender, msg.value);
    }
    //=========================================================================
}

本日影片:
https://youtu.be/a51xrVIT--Q

Smart Contract 實戰教學播放清單:
https://www.youtube.com/playlist?list=PLHmOMPRfmOxSJcrlwyandWYiuP9ZAMYoF


上一篇
Example - ERC20 Token Exchange
下一篇
結語 - One more thing...
系列文
Smart Contract 實戰教學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言