本文主要介紹如何編寫(xiě)以太坊ERC20的代幣,并且在以太坊測(cè)試網(wǎng)絡(luò)部署。
為什么需要先在測(cè)試網(wǎng)絡(luò)進(jìn)行測(cè)試合約?因?yàn)槿绻苯影押霞s部署到主網(wǎng),測(cè)試不充分的情況下消耗的是真實(shí)的ETH,而測(cè)試環(huán)境ETH都是免費(fèi)的。
1.以太坊ERC20代幣規(guī)范
官方ERC20規(guī)范文檔:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
首先需要編寫(xiě)代幣智能合約,必須遵從ERC20標(biāo)準(zhǔn)接口:
contract Token{
uint256 public totalSupply; //代幣發(fā)行總數(shù)
//查詢(xún)某個(gè)地址下代幣數(shù)量
function balanceOf(address _owner) public constant returns (uint256 balance);
//向其他地址發(fā)送代幣
function transfer(address _to, uint256 _value) public returns (bool success);
//從一個(gè)地址提取代幣到另外一個(gè)地址
function transferFrom(address _from, address _to, uint256 _value) public returns
(bool success);
//授權(quán)允許從一個(gè)地址到另外一個(gè)地址轉(zhuǎn)代幣
function approve(address _spender, uint256 _value) public returns (bool success);
//查詢(xún)某個(gè)地址允許從另外一個(gè)地址轉(zhuǎn)走代幣的數(shù)量
function allowance(address _owner, address _spender) public constant returns
(uint256 remaining);
//當(dāng)向其他地址發(fā)送代幣觸發(fā)
event Transfer(address indexed _from, address indexed _to, uint256 _value);
//當(dāng)從一個(gè)代碼提取代幣到另外一個(gè)地址時(shí)觸發(fā)
event Approval(address indexed _owner, address indexed _spender, uint256
_value);
}
實(shí)現(xiàn)這些接口:
contract Token{
uint256 public totalSupply;
function balanceOf(address _owner) public constant returns (uint256 balance);
function transfer(address _to, uint256 _value) public returns (bool success);
function transferFrom(address _from, address _to, uint256 _value) public returns
(bool success);
function approve(address _spender, uint256 _value) public returns (bool success);
function allowance(address _owner, address _spender) public constant returns
(uint256 remaining);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256
_value);
}
contract TokenTemplate is Token {
string public name;//代幣名稱(chēng),如BitShare
uint8 public decimals;//代幣精度,即小數(shù)點(diǎn)后幾位
string public symbol;//代幣簡(jiǎn)稱(chēng),如bts
address owner;
mapping (address => uint256) balances;
mapping (address => mapping (address => uint256)) allowed;
//如果希望合約能夠正常接受eth
function () payable{
}
//創(chuàng)建合約時(shí),初始化總代幣數(shù),名稱(chēng)等相關(guān)信息
function TokenTemplate(uint256 _initialAmount, string _tokenName, uint8 _decimalUnits, string _tokenSymbol) public {
totalSupply = _initialAmount * 10 ** uint256(_decimalUnits);
balances[msg.sender] = totalSupply;
name = _tokenName;
decimals = _decimalUnits;
symbol = _tokenSymbol;
owner = msg.sender;
}
function transfer(address _to, uint256 _value) public returns (bool success) {
require(balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]);
require(_to != 0x0);
balances[msg.sender] -= _value;
balances[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns
(bool success) {
require(balances[_from] >= _value && allowed[_from][msg.sender] >= _value);
balances[_to] += _value;
balances[_from] -= _value;
allowed[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
return true;
}
function balanceOf(address _owner) public constant returns (uint256 balance) {
return balances[_owner];
}
function approve(address _spender, uint256 _value) public returns (bool success)
{
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
function destory(){
if (owner == msg.sender) {
selfdestruct(owner);
}
}
}
2.連接測(cè)試網(wǎng)絡(luò)并且部署代幣
2.1 安裝MetaMask
編寫(xiě)完合約,現(xiàn)在需要連接上以太坊的測(cè)試環(huán)境,我們需要使用以太坊輕錢(qián)包MetaMask。它是chrome上的一個(gè)插件錢(qián)包,安裝非常簡(jiǎn)單。
2.2 通過(guò)MetaMask連接測(cè)試網(wǎng)絡(luò)
打開(kāi)MetaMask后點(diǎn)擊圖標(biāo)右側(cè)可以選擇連接的網(wǎng)絡(luò),可以看到Main主網(wǎng),Ropsten、Kovan、Rinkeby均為測(cè)試網(wǎng)絡(luò),這里選擇Rinkeby。

可以通過(guò)Create Account隨意創(chuàng)建ETH賬戶:

2.3 如何在測(cè)試網(wǎng)絡(luò)中獲得ETH
創(chuàng)建完ETH賬戶發(fā)現(xiàn)賬戶的ETH余額均為0,部署合約和調(diào)用合約方法都需要花費(fèi)gas,我們需要一定的ETH在測(cè)試網(wǎng)絡(luò)進(jìn)行測(cè)試。
下面介紹如何獲取測(cè)試網(wǎng)絡(luò)的免費(fèi)ETH:
- 打開(kāi):https://faucet.rinkeby.io/

可以看到需要通過(guò)三種社交賬號(hào)來(lái)獲得ETH,這里介紹Google + 方式。
- 打開(kāi):https://plus.google.com/ 并登錄自己的google賬號(hào)

將自己的ETH地址填寫(xiě)上去點(diǎn)擊“發(fā)布”:

發(fā)布完成后點(diǎn)擊:

將打開(kāi)的頁(yè)面的URL復(fù)制下來(lái):

- 將URL復(fù)制到https://faucet.rinkeby.io/ 點(diǎn)擊“Give me Ether”,有幾種金額選擇,3個(gè)ETH是最快的,只需要幾十秒。

提交完之后過(guò)一會(huì)可以看到我的地址正在充值中,loading完畢再看到metemask就可以看到金額到賬了。

2.4 將合約部署到測(cè)試網(wǎng)絡(luò)
- 打開(kāi)IDE:http://remix.ethereum.org/ 編譯代幣合約合約,選擇Injected Web3 連接錢(qián)包。

- 輸入創(chuàng)建合約的參數(shù),點(diǎn)擊create創(chuàng)建合約

點(diǎn)擊“create”后metamask會(huì)自動(dòng)彈出進(jìn)行支付gas,用默認(rèn)的就可以了,直接submit

等待礦工打包完成后,合約創(chuàng)建成功,在Remix IDE界面上可以看到合約已經(jīng)生成,并能查看到合約地址。

點(diǎn)擊IDE 控制臺(tái)輸出的url,可查看這次部署合約的交易信息。

- 在etherscan驗(yàn)證你的合約,打開(kāi)https://rinkeby.etherscan.io/輸入你的合約地址,點(diǎn)擊“Verify And Pulish”,建議翻墻后操作,不然后續(xù)驗(yàn)證可能會(huì)失敗。

輸入相關(guān)信息

點(diǎn)擊“Verify And Pulish”

驗(yàn)證成功!

- 在etherscan查看代幣合約的信息
調(diào)用合約的transfer方法,將部分代幣發(fā)送到其他地址,完成后打開(kāi)https://rinkeby.etherscan.io/token-search 輸入代幣的合約地址點(diǎn)擊“Search”,可以看我的代幣的相關(guān)信息。

再點(diǎn)擊合約地址可以看到該合約的轉(zhuǎn)賬記錄,和持幣的情況:

