Solidity 建立自己的數字貨币 (ERC20代币)
本文從技術角度詳細介紹如何基于以太坊ERC20建立代币的流程.
合約位址:
0xe70c8efb6e4899974a622e6a37f27f07247e38a4
以太坊測試網浏覽器檢視合約詳情
文章目錄
- Solidity 建立自己的數字貨币 (ERC20代币)
-
- 簡介
- 代币Token
- ERC20 Token
- 編寫代币合約代碼
- 部署
- 代币交易
簡介
本文所講的代币是使用以太坊智能合約建立。
需要知識體系:
- 以太坊
- 智能合約
- ERC20
代币Token
如果不那麼追求精确的定義,代币就是數字貨币,比特币、以太币就是一個代币。
利用以太坊的智能合約可以輕松編寫出屬于自己的代币,代币可以代表任何可以交易的東西,如:積分、财産、證書等等。
是以不管是出于商業,還是學習很多人想建立一個自己的代币,先貼一個圖看看建立的代币是什麼樣子。

ERC20 Token
也許你經常看到 ERC20 和代币一同出現, ERC20 是以太坊定義的一個代币标準。
要求我們在實作代币的時候必須要遵守的協定,如指定代币名稱、總量、實作代币交易函數等,隻有支援了協定才能被以太坊錢包支援。
其接口如下:
contract ERC20Interface {
string public constant name = "Token Name";
string public constant symbol = "LYU";
uint8 public constant decimals = 18;
function totalSupply() public constant returns (uint);
function balanceOf(address tokenOwner) public constant returns (uint balance);
function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
function transfer(address to, uint tokens) public returns (bool success);
function approve(address spender, uint tokens) public returns (bool success);
function transferFrom(address from, address to, uint tokens) public returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
- 簡單說明一下:
名字 | 說明 |
---|---|
name | 代币名稱 |
symbol | 代币符号 |
decimals | 代币小數點位數,代币的最小機關, 18 表示我們可以擁有 .0000000000000000001 機關個代币。 |
totalSupply() | 發行代币總量。 |
balanceOf() | 檢視對應賬号的代币餘額。 |
transfer() | 實作代币轉賬交易,用于給使用者發送代币(從我們的賬戶裡)。 |
transferFrom() | 給被授權的使用者使用,他可以從我們(參數 from)的賬戶裡發送代币給其他使用者(參數 to)。 |
allowance() | 傳回授權花費的代币數。 |
approve() | 授權使用者可代表我們花費的代币數。 |
編寫代币合約代碼
pragma solidity 0.4.16;
interface tokenRecipient {
function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external;
}
contract TokenERC20{
string public name = "LYU Name";
string public symbol = "LYU";
uint8 public decimals = 18; // 18 is the most common number of decimal places
uint256 public totalSupply=10000000000;
mapping (address => uint256) public balanceOf; //
mapping (address => mapping (address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 value);
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;
name = tokenName;
symbol = tokenSymbol;
}
function _transfer(address _from, address _to, uint _value) internal {
require(_to != 0x0);
require(balanceOf[_from] >= _value);
require(balanceOf[_to] + _value > balanceOf[_to]);
uint previousBalances = balanceOf[_from] + balanceOf[_to];
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
Transfer(_from, _to, _value);
assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
}
function transfer(address _to, uint256 _value) public returns (bool) {
_transfer(msg.sender, _to, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_value <= allowance[_from][msg.sender]); // Check allowance
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;
}
}
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;
}
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;
}
}
部署
在開發測試智能合約時,MetaMask 和 Remix Solidity IDE 是兩個非常好用的工具,今天就用他們來完成部署。
1、安裝和配置 MetaMask 請參考開發、部署第一個去中心化應用,不同的上本文選擇了以太坊的測試網絡 Ropsten,如果你沒有餘額請點選購買 buy,進入的網站可以送一些測試以太币給你,配置好之後,界面應該如下:
2.浏覽器打開 Remix Solidity IDE,複制以上源碼粘貼上,在右側選項參考如圖的設定:
3.打開 Metamask 界面,切換到 TOKENS,點添加合約,出現如下對話框:
填入剛剛複制的位址,點 ADD,這時你就可以看到你建立的代币了,如圖:
說明:你已經完成了代币的建立和部署
将手中的代币分發到其他使用者的手中;
代币交易
由于 MetaMask 插件沒有提供代币交易功能,同時考慮到很多人并沒有以太坊錢包或是被以太坊錢包網絡同步問題折磨,今天我用網頁錢包來講解代币交易。
1.進入網頁錢包位址, 第一次進入有一些安全提示需要使用者确認。
2.進入之後,按照下圖進行設定:
3.連接配接上之後,如圖
需要添加代币,填入代币合約位址。
4.進行代币轉賬交易
在接下來的交易确認也,點選确認即可。
5.交易完成後,可以看到 MetaMask 中代币餘額減少了。
代币交易是不是很簡單,隻要明白了交易流程,使用其他的錢包也是一樣的道理。