中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ERC20代幣合約如何實現

發布時間:2021-12-24 17:09:13 來源:億速云 閱讀:217 作者:iii 欄目:互聯網科技

本篇內容主要講解“ERC20代幣合約如何實現”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“ERC20代幣合約如何實現”吧!

ERC20規范

ERC20約定了一個代幣合約需要實現的接口,規范參見ERC20

// 接口標準
  contract ERC20 {
      function totalSupply() constant returns (uint totalSupply);   // 總發行量
      function balanceOf(address _owner) constant returns (uint balance);
      // 代幣分發(注意, 這個只有合約的Creator 可以調用)
      function transfer(address _to, uint _value) returns (bool success);   
      // 這里是擁有者和擁有者之間的代幣轉移
      function transferFrom(address _from, address _to, uint _value) returns (bool success);    

      function approve(address _spender, uint _value) returns (bool success);
      function allowance(address _owner, address _spender) constant returns (uint remaining);

      event Transfer(address indexed _from, address indexed _to, uint _value);
      event Approval(address indexed _owner, address indexed _spender, uint _value);

      // Token信息
      string public constant name = "4FunCoin";
      string public constant symbol = "4FC";
      uint8 public constant decimals = 18;  // token的精度, 大部分都是18
}

上面的代碼是一個標準的ERC20標準的代碼, 規范給出了框架, 我們只需要實現相應的函數就好了, 這里給出函數說明。

接口函數說明

函數的形參是局部有效, 所以前面使用下劃線, 與其他的變量區別開來. 如 _owner.

  • totalSupply() 函數返回這個Token的總發行量;

  • balanceOf() 查詢某個地址的Token數量 , 結合mapping實現

  • transfer() owner 使用這個進行發送代幣

  • transferFrom () token的所有者用來發送token

  • allowance() 控制代幣的交易,如可交易賬號及資產, 控制Token的流通

  • approve() 允許用戶可花費的代幣數;

事件函數說明

這里兩個Event是重點, 事件,可以被前端js代碼捕獲到并進行相應的處理:

  • event Transfer() Token的轉賬事件

  • event Approval() 允許事件

ERC20代幣合約實現

理解了上面的函數, 下面的代碼,就實現了Token合約的函數填充

pragma solidity ^0.4.16;

interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; }  // token的 接受者 這里聲明接口, 將會在我們的ABI里

contract TokenERC20 {
/*********Token的屬性說明************/
    string public name = 4FunCoin;
    string public symbol = 4FC;
    uint8 public decimals = 18;  // 18 是建議的默認值
    uint256 public totalSupply; // 發行量

    // 建立映射 地址對應了 uint' 便是他的余額
    mapping (address => uint256) public balanceOf;   
    // 地址對應余額
    mapping (address => mapping (address => uint256)) public allowance;

     // 事件,用來通知客戶端Token交易發生
    event Transfer(address indexed from, address indexed to, uint256 value);

     // 事件,用來通知客戶端代幣被消耗(這里就不是轉移, 是token用了就沒了)
    event Burn(address indexed from, uint256 value);

    // 這里是構造函數, 實例創建時候執行
    function TokenERC20(uint256 initialSupply, string tokenName, string tokenSymbol) public {
        totalSupply = initialSupply * 10 ** uint256(decimals);  // 這里確定了總發行量

        balanceOf[msg.sender] = totalSupply;    // 這里就比較重要, 這里相當于實現了, 把token 全部給合約的Creator

        name = tokenName;
        symbol = tokenSymbol;
    }

    // token的發送函數
    function _transfer(address _from, address _to, uint _value) internal {

        require(_to != 0x0);    // 不是零地址
        require(balanceOf[_from] >= _value);        // 有足夠的余額來發送
        require(balanceOf[_to] + _value > balanceOf[_to]);  // 這里也有意思, 不能發送負數的值(hhhh)

        uint previousBalances = balanceOf[_from] + balanceOf[_to];  // 這個是為了校驗, 避免過程出錯, 總量不變對吧?
        balanceOf[_from] -= _value; //發錢 不多說
        balanceOf[_to] += _value;
        Transfer(_from, _to, _value);   // 這里觸發了轉賬的事件 , 見上event
        assert(balanceOf[_from] + balanceOf[_to] == previousBalances);  // 判斷總額是否一致, 避免過程出錯
    }

    function transfer(address _to, uint256 _value) public {
        _transfer(msg.sender, _to, _value); // 這里已經儲存了 合約創建者的信息, 這個函數是只能被合約創建者使用
    }

    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        require(_value <= allowance[_from][msg.sender]);     // 這句很重要, 地址對應的合約地址(也就是token余額)
        allowance[_from][msg.sender] -= _value;
        _transfer(_from, _to, _value);
        return true;
    }

    function approve(address _spender, uint256 _value) public
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;   // 這里是可花費總量
        return true;
    }

    function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) {
        tokenRecipient spender = tokenRecipient(_spender);
        if (approve(_spender, _value)) {
            spender.receiveApproval(msg.sender, _value, this, _extraData);
            return true;
        }
    }
    // 正如其名, 這個是燒幣(SB)的.. ,用于把創建者的 token 燒掉
    function burn(uint256 _value) public returns (bool success) {
        require(balanceOf[msg.sender] >= _value);   // 必須要有這么多
        balanceOf[msg.sender] -= _value;
        totalSupply -= _value;
        Burn(msg.sender, _value);
        return true;
    }
    // 這個是用戶銷毀token.....
    function burnFrom(address _from, uint256 _value) public returns (bool success) {
        require(balanceOf[_from] >= _value);        // 一樣要有這么多
        require(_value <= allowance[_from][msg.sender]);    // 
        balanceOf[_from] -= _value;
        allowance[_from][msg.sender] -= _value;
        totalSupply -= _value;
        Burn(_from, _value);
        return true;
    }
}

上面的代碼閱讀難度不大, 也寫了大多處的注釋, 這里簡單介紹幾個要點:

構造函數

// 這里是構造函數, 實例創建時候執行
function TokenERC20(uint256 initialSupply, string tokenName, string tokenSymbol) public {
    totalSupply = initialSupply * 10 ** uint256(decimals);  // 這里確定了總發行量
        balanceOf[msg.sender] = totalSupply;    // 這里就比較重要, 這里相當于實現了, 把token 全部給合約的Creator

        name = tokenName;
        symbol = tokenSymbol;
    }

在Solidity里面, Contract 我們可以直接理解成一個Class吧, 如C++ 一樣, 這里面也存在一個 構造函數而且他們的功能也是近乎相同, 在合約創建的時候執行一次.(沒錯 , 合約整個生命周期里只能執行這樣一次) , 所以他的作用就是實現合約信息的初始化, 一旦數據寫入區塊數據, 將是無法更改的了(永固性).

構造函數的是不能有返回值的(有也無法接受), 但是可以帶參數, 像是此處代碼, 把發行量, token的名稱和token的 符號作為參數留出. 在合約初始化時候我們便可以自行定義.

函數體中可見, 我們對貨幣總量, 名稱和 符號進行賦值, 這樣,這些值就永遠的記錄在了我們的合約的區塊數據中了

映射(mapping)

    // 建立映射 地址對應了 uint' 便是他的余額
    mapping (address => uint256) public balanceOf;   
    // 地址對應余額
    mapping (address => mapping (address => uint256)) public allowance;

這個形式,乍一眼看上去是沒那么好懂. 其實慢慢的 也是理解了, 這里的映射, 通俗的講,就是相當于我們的字典, 是一個鍵值對. 上述的代碼也是建立了一個 address 到 uint類型的映射關系.

balanceOf[msg.sender] = 10000;  //msg.sender 是一個地址

到此,相信大家對“ERC20代幣合約如何實現”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

erc
AI

阳山县| 鹰潭市| 无极县| 潮安县| 德格县| 黎城县| 富阳市| 昌乐县| 德安县| 长岛县| 巢湖市| 碌曲县| 应城市| 庆云县| 浦北县| 兴国县| 三穗县| 天柱县| 垦利县| 海丰县| 娄底市| 东乌珠穆沁旗| 罗江县| 格尔木市| 太白县| 仙居县| 轮台县| 中西区| 济南市| 乃东县| 吉木乃县| 墨脱县| 盈江县| 沾化县| 奈曼旗| 额尔古纳市| 苏尼特右旗| 石渠县| 民和| 永寿县| 云龙县|