您好,登錄后才能下訂單哦!
本篇內容主要講解“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() 允許事件
理解了上面的函數, 下面的代碼,就實現了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的 符號作為參數留出. 在合約初始化時候我們便可以自行定義.
函數體中可見, 我們對貨幣總量, 名稱和 符號進行賦值, 這樣,這些值就永遠的記錄在了我們的合約的區塊數據中了
// 建立映射 地址對應了 uint' 便是他的余額 mapping (address => uint256) public balanceOf; // 地址對應余額 mapping (address => mapping (address => uint256)) public allowance;
這個形式,乍一眼看上去是沒那么好懂. 其實慢慢的 也是理解了, 這里的映射, 通俗的講,就是相當于我們的字典, 是一個鍵值對. 上述的代碼也是建立了一個 address 到 uint類型的映射關系.
balanceOf[msg.sender] = 10000; //msg.sender 是一個地址
到此,相信大家對“ERC20代幣合約如何實現”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。