本文目標php
經過逐步的指導和截圖舉證,一步步帶領一個技術小白完成一個數字貨幣(通證,代幣,TOKEN)的發佈演示和上線交易。git
環境前置條件github
參考開發實戰|3步教你在以太坊上開一家寵物店(附流程+代碼),已在本地WIDOWS環境完成MetaMask輕錢包客戶端的安裝和配置;做者建議最好遵循從頭開始的課程學習順序。不過若是你想半途插入實操學習,問題也不大,遇到障礙時反向找對應文章的指導內容便可完成。json
(識別下圖二維碼可回看視頻)瀏覽器
技術收穫安全
從本實踐中,你能夠學習到:微信
ERC20 Token的定義和實踐網絡
使用Remix Solidity IDE編寫智能合約和編譯調試app
使用MetaMask完成錢包帳戶查看函數
使用網頁錢包完成代幣交易演示
定義
ERC20合約是在2015年11月在EIP(https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)上提出的一個合約標準,代幣定義的一個標準。
Token表明數字資產,具備價值,可是並非都符合特定的規範。
基於ERC20的貨幣更容易互換,而且可以在Dapps上相同的工做。
新的標準可讓token更兼容,容許其餘功能,包括投票標記化。操做更像一個投票操做,Token的持有人能夠徹底控制資產,遵照ERC20的token能夠跟蹤任何人在任什麼時候間擁有多少token。基於eth合約的子貨幣,因此容易實施。
ERC20 Token接口說明
方法
注意:調用者必須處理返回false的returns (bool success).調用者絕對不能假設返回false的狀況不存在。
name
返回這個令牌的名字,好比"MyToken".
可選 - 這種方法能夠用來提升可用性,但接口和其餘契約不能期望這些值存在。
function name() constant returns (string name)
symbol
返回令牌的符號,好比HIX.
可選 - 這種方法能夠用來提升可用性,但接口和其餘契約不能期望這些值存在。
function symbol() constant returns (string symbol)
decimals
返回token使用的小數點後幾位, 好比 8,表示分配token數量爲100000000
可選 - 這種方法能夠用來提升可用性,但接口和其餘契約不能期望這些值存在。
function decimals() constant returns (uint8 decimals)
totalSupply
返回token的總供應量。
function totalSupply() constant returns (uint256 totalSupply)
balanceOf
返回地址是_owner的帳戶的帳戶餘額。
function balanceOf(address _owner) constant returns (uint256 balance)
transfer
轉移_value的token數量到的地址_to,而且必須觸發Transfer事件。 若是_from賬戶餘額沒有足夠的令牌來支出,該函數應該被throw。
建立新令牌的令牌合同應該在建立令牌時將_from地址設置爲0x0觸發傳輸事件。
注意 0值的傳輸必須被視爲正常傳輸並觸發傳輸事件。
function transfer(address _to, uint256 _value) returns (bool success)
transferFrom
從地址_from發送數量爲_value的token到地址_to,必須觸發Transfer事件。
transferFrom方法用於提取工做流,容許合同代您轉移token。這能夠用於例如容許合約代您轉讓代幣和/或以子貨幣收取費用。除了_from賬戶已經經過某種機制故意地受權消息的發送者以外,該函數應該throw。
注意 0值的傳輸必須被視爲正常傳輸並觸發傳輸事件。
function transferFrom(address _from, address _to, uint256 _value) returns (bool success)
approve
容許_spender屢次取回您的賬戶,最高達_value金額。 若是再次調用此函數,它將以_value覆蓋當前的餘量。
注意:爲了阻止向量攻擊,客戶端須要確認以這樣的方式建立用戶接口,即將它們設置爲0,而後將其設置爲同一個花費者的另外一個值。雖然合同自己不該該強制執行,容許向後兼容之前部署的合同兼容性。
function approve(address _spender, uint256 _value) returns (bool success)
allowance
返回_spender仍然被容許從_owner提取的金額。
function allowance(address _owner, address _spender) constant returns (uint256 remaining)
Events
Transfer
當token被轉移(包括0值),必須被觸發。
event Transfer(address indexed _from, address indexed _to, uint256 _value)
Approval
當任何成功調用approve(address _spender, uint256 _value)後,必須被觸發。
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
[官網接口說明點擊查看],(https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)
接口文件ERC20Interface.sol以下:
contract ERC20Interface { string public constant name = "Token Name"; string public constant symbol = "SYM"; uint8 public constant decimals = 18; // 18 is the most common number of decimal places // 0.0000000000000000001 個代幣 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 approve(address spender, uint tokens) public returns (bool success); function transfer(address to, 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); }
合約文件TokenERC20.sol以下:
pragma solidity ^0.4.16; interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; } contract TokenERC20 { string public name; string public symbol; uint8 public decimals = 18; // decimals 能夠有的小數點個數,最小的代幣單位。18 是建議的默認值 uint256 public totalSupply; // 用mapping保存每一個地址對應的餘額 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); // 供應的份額,份額跟最小的代幣單位有關,份額 = 幣數 * 10 ** decimals。 balanceOf[msg.sender] = totalSupply; // 建立者擁有全部的代幣 name = tokenName; // 代幣名稱 symbol = tokenSymbol; // 代幣符號 } /** * 代幣交易轉移的內部實現 */ function _transfer(address _from, address _to, uint _value) internal { // 確保目標地址不爲0x0,由於0x0地址表明銷燬 require(_to != 0x0); // 檢查發送者餘額 require(balanceOf[_from] >= _value); // 確保轉移爲正數個 require(balanceOf[_to] + _value > balanceOf[_to]); // 如下用來檢查交易, uint previousBalances = balanceOf[_from] + balanceOf[_to]; // Subtract from the sender balanceOf[_from] -= _value; // Add the same to the recipient balanceOf[_to] += _value; Transfer(_from, _to, _value); // 用assert來檢查代碼邏輯。 assert(balanceOf[_from] + balanceOf[_to] == previousBalances); } /** * 代幣交易轉移 * 從建立交易者帳號發送`_value`個代幣到 `_to`帳號 * * @param _to 接收者地址 * @param _value 轉移數額 */ function transfer(address _to, uint256 _value) public { _transfer(msg.sender, _to, _value); } /** * 帳號之間代幣交易轉移 * @param _from 發送者地址 * @param _to 接收者地址 * @param _value 轉移數額 */ 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; } /** * 設置某個地址(合約)能夠交易者名義花費的代幣數。 * * 容許發送者`_spender` 花費很少於 `_value` 個代幣 * * @param _spender The address authorized to spend * @param _value the max amount they can spend */ function approve(address _spender, uint256 _value) public returns (bool success) { allowance[msg.sender][_spender] = _value; return true; } } /** * 銷燬建立者帳戶中指定個代幣 */ function burn(uint256 _value) public returns (bool success) { require(balanceOf[msg.sender] >= _value); // Check if the sender has enough balanceOf[msg.sender] -= _value; // Subtract from the sender totalSupply -= _value; // Updates totalSupply Burn(msg.sender, _value); return true; } /** * 銷燬用戶帳戶中指定個代幣 * * Remove `_value` tokens from the system irreversibly on behalf of `_from`. * * @param _from the address of the sender * @param _value the amount of money to burn */ function burnFrom(address _from, uint256 _value) public returns (bool success) { require(balanceOf[_from] >= _value); // Check if the targeted balance is enough require(_value <= allowance[_from][msg.sender]); // Check allowance balanceOf[_from] -= _value; // Subtract from the targeted balance allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance totalSupply -= _value; // Update totalSupply Burn(_from, _value); return true; } }
函數的功能參考函數的說明描述和代碼自解釋。
MetaMask錢包聯網
前置條件:做者假設學習者已完成MetaMask的安裝和配置。尚未完成的,參考開發實戰|3步教你在以太坊上開一家寵物店(附流程+代碼),安裝 MetaMask和配置區塊鏈網絡」,在本地WIDOWS環境完成MetaMask輕錢包客戶端的安裝和配置。
打開MetaMask錢包,點擊左上角的「Ropsten Test Network」 鏈接成功。
鏈接成功
查看存量的帳號Account 1,其中ETH餘額顯示爲0。
存量帳號Account 1餘額爲0
點擊「Copy Address to Clipboard」,記錄Account 1錢包地址爲
0xD1F7922e8b78cBEB182250753ade8379d1E09949
點擊MetaMask右上角環形頭像的菜單「Create Account」, 建立一個新錢包帳號Account 8,
新增帳號成功
記錄Account 8的錢包地址爲
0x3D7DfB80E71096F2c4Ee63C42C4D849F2CBBE363
點擊Account 8的"BUY"按鈕,能夠從「Ropsten Test Network」 免費獲取一些測試ETH。
跳轉到BUY ETH頁面
點擊按鈕「ROPSTEN TEST FAUCET」能夠看到贈送頁面
點擊綠色按鈕,等待10秒以上,成功的話每次能夠獲取1個測試ETH。
故障排查
贈送失敗
做者操做時,出現錯誤。從提示看,是因爲用戶交易拒絕。等10秒後再點擊該綠色按鈕則未有錯誤提示了。緣由不明,多是操做頻繁致使。
屢次點擊,偶爾出錯,小編一共從這個測試網站獲取了5個測試ETH用於做爲發幣的GAS燃料。
獲取測試ETH
Remix Solidity IDE調試環境介紹
代碼編寫和編譯
咱們以「Hello World」智能合約爲例,參考下圖可完成編譯和語法錯誤發現。
編譯環境使用方法
合約建立
參考附圖描述,在配置號MetaMask帳號和網絡鏈接的狀況下,確保帳戶有虛擬ETH用於合約建立花銷。最後點擊「Create」按鈕能夠完成合約建立。點擊輸出區的網頁連接(https://ropsten.etherscan.io/tx/0x9ef5b97580cf5350e9deca8f8472117df3983f1bcd0272b15c490528c811f3f8)能夠查看合約的詳細狀況。
支付合約花銷
合約執行
參考附件路徑圖,點擊RUN按鈕能夠執行一次合約。點擊下方的「Say」按鈕,能夠看到合約輸出。在調試輸出窗口能夠看到「call to hello.say」的運行提示。
合約執行
總結
因此說,沒有Ubuntu+Ganache等,直接在WINDOWS環境,也可使用Remix+MetaMask+Ropsten Test Network組合完成一套完整的以太坊測試環境。
編譯ERC20智能合約
CHROME瀏覽器打開Remix Solidity IDE環境(http://remix.ethereum.org/#optimize=false&version=soljson-v0.4.21+commit.dfe3193c.js),打開以前編寫的「TokenERC20.sol」智能合約,而後點擊右側的「start to compile」按鈕。能夠看到,除了一些Warning提示外,智能合約編譯成功。
編譯操做
運行ERC20智能合約
運行頁面
切換到"RUN"頁面,Environment選擇「Injected Web3」, Account自動更新爲MetaMask的Account 8帳號。「Create」按鈕前按照發幣數量(本次發1個億),代幣名稱,代幣符號填寫爲100000000,"ColorBay","CB"。
點擊"Create"按鈕,會彈出一個交易確認框,設置合理的Gas Price,但要確保Max Transaction Fee不會超過Account 8的ETH總數,點「SUBMIT」按鈕。
智能合約部署
部署成功的話,Account8 會產生一條交易記錄,顯示狀態爲「Contract Published」,表示部署成功了。
部署成功
說明:有時點擊帳號,會出現「Retry with a higher gas price here」的提示,通常狀況下再等待10秒看看可否交易成功。萬一仍是不成的話,可考慮該Gas Price大點。
部署確認中
MetaMask加載TOKEN
點擊Account 8的交易記錄(https://ropsten.etherscan.io/tx/0x3dd6f5d88f54dee71c4a3d9f5082e270b01cf3f26e1d3960d2517675745fa80e),能夠跳轉智能合約部署信息顯示頁面:
部署成功
獲取智能合約地址爲0x5eeec41dc08d7caece17c4a349635934637036f1(https://ropsten.etherscan.io/address/0x5eeec41dc08d7caece17c4a349635934637036f1),點擊可查看該交易詳情。
點擊MetaMask的Account 8帳號的TOKENS頁面的「ADD TOKEN」按鈕,把代幣智能合約地址Token Contract Address爲0x5eeec41dc08d7caece17c4a349635934637036f1,代幣標識符Token Symbol爲CB,則能夠建立你的代幣了。
代幣建立成功,一共有1億個CB幣了。此時,點擊100000000的代幣位置,跳轉到代幣查詢頁面(https://ropsten.etherscan.io/token/0x5eeec41dc08d7caece17c4a349635934637036f1), 能夠在etherscan網站看到帳戶的持幣數量了。
1億
TOKEN信息
截止做者發稿時,以太坊的價格爲2559元/個,而你有1億個CB幣,是否是快要走上人生巔峯了呢?哈哈,作個夢而已。真正的區塊鏈應用,要能有生態,能爲人類社會創造價值,而不是講故事,割韭菜!
因爲MetaMask插件沒有提供代幣交易功能,同時考慮到不少人並無以太坊錢包或是被以太坊錢包網絡同步問題折磨,今天我用網頁錢包(https://www.myetherwallet.com/)來說解代幣交易。
1. 進入網頁錢包地址 (https://www.myetherwallet.com/#send-transaction)
第一次進入有一些安全提示須要用戶確認。
2. 進入以後,按照下圖進行設置
網絡配置
3,增長自定義代幣
填寫地址Token Contract 爲0x5eeec41dc08d7caece17c4a349635934637036f1和其餘信息,點擊保存按鈕。
增長自定義TOKEN
配置TOKEN合約地址和代幣符號
配置成功的界面以下:
【說明】若是不成功,則提示爲「Not a valid ERC-20 token CB」,則多是代幣信息填寫不正確或者右上角的網絡選擇錯誤,沒有選擇「Network Ropston(infura.com)」選項引發。
4.轉帳給Account 1
填寫Account 1的地址「0xD1F7922e8b78cBEB182250753ade8379d1E09949」到「發送至地址」輸入框,
選擇CB,不是ETH
轉帳確認
交易確認
交易提示
查看帳戶餘額,Account 8減小800萬個CB幣,而Account 1則增長了800萬個CB幣。
Account 8
Account 1
轉帳交易成功了!
做爲一個古典投資人,用45分鐘完成了TOKEN上線和交易,用4個小時整理了這篇文章。學習就是這麼簡單,只要你對新技術保持飢餓感,高齡開發轉型區塊鏈也不是難事!
本文是站在巨人的肩膀上的操做實踐,感謝如下文章做者的幫助:
一步步教你建立本身的數字貨幣(代幣)進行ICO(https://blog.csdn.net/xilibi2003/article/details/79131924)
代幣標準(https://theethereum.wiki/w/index.php/ERC20_Token_Standard)
Create your own crypto-currency with ethereum
本文來源:簡書
做者:筆名輝哥
課程推薦
課程主題:揭開神祕的數字貨幣交易——2節課創建一個數字貨幣交易所
識別下圖二維碼添加微信,回覆「006」便可報名。
HiBlock區塊鏈社區更多活動點擊**「閱讀原文」**查看