接下來我們就可以一步步的建立我們的加密代币項目了。
代币合約扮演的角色相當于銀行的角色。使用者在代币合約中,用自己的<code>以太币帳戶位址</code>當作銀行帳戶,可以透過代币合約執行轉賬(<code>transfer</code>,将代币由一個帳戶轉到另一個帳戶),查詢餘額(<code>balanceOf</code>,查詢指定帳戶中擁有的代币)等原本由銀行負責的工作。因為合約部署在公開區塊鍊上,所有的交易都是公開透明,可供檢驗的。
終端執行<code>truffle create contract EncryptedToken</code>指令建立<code>EncryptedToken.sol</code>合約。
将下面的合約代碼拷貝,替換<code>EncryptedToken.sol</code>檔案的代碼。
<code>pragma solidity ^0.4.4</code>中的<code>0.4.4</code>代表<code>solidity</code>的版本,<code>^</code>代表<code>0.4.4 ~ 0.4.9</code>之間的<code>solidity</code>都可以正常編譯目前版本的合約。
<code>contract</code>相當于其他語言中的<code>class</code>,<code>EncryptedToken</code>相當于<code>類</code>的名字。<code>contract EncryptedToken</code>可以了解為<code>class EncryptedToken extends Contract</code>。
<code>uint256 INITIAL_SUPPLY = 666666</code>聲明了一個變量<code>INITIAL_SUPPLY</code>,初始化存儲了一個<code>666666</code>的整數作為部署目前合約的錢包位址的代币數。
<code>mapping(address => uint256) balances;</code>,<code>balances</code>是一個<code>key</code>類型為<code>address</code>,<code>value</code>類型為<code>uint256</code>的鍵值對(mapping),相當于Java中的<code>map</code>、iOS中的<code>NSDictionary</code>。
<code>function EncryptedToken()</code>函數是<code>EncryptedToken</code>合約的構造函數(contructor),當<code>EncryptedToken</code>合約調用時,會先執行它的構造函數。
在構造函數中,會以目前部署合約的錢包位址為<code>key</code>,以<code>INITIAL_SUPPLY</code>為<code>value</code>初始化一個鍵值對。
<code>transfer</code>函數是聲明用來從轉賬到指定錢包位址的函數,<code>_to</code>代表轉賬的目的地位址,<code>_amount</code>代表轉賬金額。
<code>assert(balances[msg.sender] < _amount)</code>,這句代碼中,我聲明了一個斷言,當<code>balances[msg.sender] < _amount</code>,即目前錢包餘額小于要轉賬的額度時,就會抛出異常。
<code>balances[msg.sender] -= _amount;</code>從目前錢包額度中減去<code>_amount</code>。
<code>balances[_to] += _amount;</code>,将目标位址的額度增加<code>_amount</code>。
<code>balanceOf(address _owner)</code>函數是用來查詢指定錢包位址的餘額,<code>_owner</code>即是指定的錢包位址,<code>returns (uint256)</code>代表傳回值的類型為<code>uint256</code>,<code>constant</code>關鍵字的作用是,當我們調用<code>balanceOf</code>函數時,它會自動調用<code>call()</code>方法,表明隻是讀書資料,而不需要往區塊鍊寫入資料,調用這個方法,不需要花費手續費。
在<code>migrations/</code>目錄下建立一個名字叫做<code>3_deploy_contract.js</code>的檔案。檔案中的内容為:
接下來執行<code>compile</code>和<code>migrate</code>指令:
如上所示,我們已經将<code>EncryptedToken</code>代币合約部署到了<code>testrpc</code>上。
合約部署完成後,我們通過<code>truffle console</code>開啟<code>console</code>控制台,在這個控制台中對已經部署的合約進行驗證。
在<code>testrpc</code>啟動時,系統會給我們配置設定10個錢包位址,如上圖所示我們可以通過<code>web3.eth.coinbase</code>或者<code>web3.eth.accounts[0]</code>擷取首個錢包位址,當然也可以根據索引擷取其他的錢包位址。
接下來聲明一個合約變量存儲<code>EncryptedToken</code>合約執行個體。
驗證<code>web3.eth.coinbase</code>和<code>web3.eth.accounts[1]</code>中的餘額。
經驗證,第0個錢包位址中的代币餘額為<code>666666</code>,第1個錢包位址中的代币餘額為<code>0</code>。
下一步,我們将從第0個賬号中向第1個賬号轉賬<code>666</code>個代币。
如上所示,轉賬過程中出現了異常,轉賬失敗,仔細檢查一下,不難發現是因為在我們合約代碼<code>EncryptedToken.sol</code>中有這麼一句代碼<code>assert(balances[msg.sender] < _amount);</code>,也就是說隻有當<code>balances[msg.sender]</code>小于<code>_amount</code>時,才不會出現異常,是以我們應該将<code><</code>符号換成<code>></code>符号,即當<code>balances[msg.sender]</code>餘額不足時抛出異常。
代碼修改後,需要重新編譯,部署。
備注:編譯時,一定要先将<code>build</code>檔案夾删除,其次在部署合約時,一定要添加<code>--reset</code>,否則修改後的合約沒法部署成功。
打開控制台,按照如下操作進行驗證。
如上所示,代币轉賬成功。
在這篇文章中,隻是簡單介紹了代币系統的邏輯,并沒有對安全進行相關操作,比如:餘額不夠的處理、位址合不合法的處理等等。當然,通過這篇文章的學習,你再回頭看我們初始項目中的<code>MetaCoin</code>代碼時,你就應該能看懂了。
比特币:1FcbBw62FHBJKTiLGNoguSwkBdVnJQ9NUn
以太坊:0xF055775eBD516e7419ae486C1d50C682d4170645
區塊鍊技術交流QQ群:348924182
「區塊鍊部落」官方公衆号