想知道更多關於區塊鏈技術知識,請百度【鏈客區塊鏈技術問答社區】 鏈客,有問必答!
這一篇分析一下metacoin的合約代碼。
智能合約是一組數據和代碼的集合,合約部署到鏈上之後會產生一個地址,外部經過該地址調用合約代碼來改變或者查詢合約的數據(狀態)。
metacoin合約是用Solidity語言編寫的,經過solc編譯成字節碼,而後在發生外部訪問時被以太坊虛擬機EVM執行。
Solidity是一種跟Java很相似的語言,因此代碼讀起來也不怎麼費勁。咱們先看一下MetaCoin.sol的代碼,一行一行地看:
pragma solidity ^0.4.18;
第一行是聲明Solidity的版本,保證代碼的兼容性。
import "./ConvertLib.sol";
這一行經過import關鍵字導入外部類庫ConvertLib。
contract MetaCoin {app
mapping (address => uint) balances; event Transfer(address indexed _from, address indexed _to, uint256 _value); ... ...
}
Truffle要求合約的名次必須和文件名一致,而且只能使用contract和library這兩個關鍵字。緊接着聲明瞭兩個全局變量:
● balances:用於存儲全部帳戶的餘額。這個變量是mapping類型,其實就理解爲HashMap,key是address類型,value是uint類型。address類型大小是160bit,用於存儲帳戶地址或者合約地址。
● Transfer:這是一個event類型的變量,該事件會在sendCoin()方法中被觸發。客戶端能夠經過watch()方法來監聽區塊鏈上觸發的事件,用於跟蹤交易。函數
function MetaCoin() public { balances[tx.origin] = 10000; }
接下來就是合約的構造函數了,合約的構造函數只會在建立合約時被調用一次,以後就永遠不會被調用了(能夠理解爲new了一個全局的單例對象)。tx是一個全局變量,表示當前的transaction,也就是建立合約的這個transaction。因此執行這個構造函數就是往合約的創始人帳號裏打了10000個MetaCoin。區塊鏈
function sendCoin(address receiver, uint amount) public returns(bool sufficient) { if (balances[msg.sender] < amount) return false; balances[msg.sender] -= amount; balances[receiver] += amount; Transfer(msg.sender, receiver, amount); return true; }
接下來看sendCoin()函數:參數是接收人地址以及發送代幣的數量,返回是否發送成功。Solidity的語法比較有意思,跟Java相比,Solidity的權限修飾符以及返回值都是寫在右邊的。。。
第一步就是判斷髮送人是否有足夠的餘額。msg也是一個全局變量,msg.sender就是此次調用發起人的地址。這些全局變量能夠獲取和當前transaction相關的一些區塊鏈屬性.ui
接下來的2行很好理解,發送帳號餘額減小,接收帳號餘額增長。緊接着下一行就是觸發Transfer事件,從而外部監聽者能夠收到通知。spa
function getBalanceInEth(address addr) public view returns(uint){ return ConvertLib.convert(getBalance(addr),2); } function getBalance(address addr) public view returns(uint) { return balances[addr]; }
最後兩個函數是查詢接口,返回MetaCoin餘額以及轉換成ETH的餘額。這裏用到剛開始導入的ConvertLib類庫,那咱們就來看看這個ConvertLib.sol:
pragma solidity ^0.4.4;code
library ConvertLib{對象
function convert(uint amount,uint conversionRate) public pure returns (uint convertedAmount) { return amount * conversionRate; }
}
代碼很是簡單,就是把餘額乘上一個轉換率,以前傳的轉換率是2,也就是說一個MetaCoin值2個ETH。
最後咱們看下合約編譯後的輸出:接口