本文將通過一個簡單的合約程式碼範例,對代碼結構進行說明。
程式碼範例
如下代碼所示,這是螞蟻區塊鏈合約平台對積分管理方案的簡單實現,主要實現了積分的發放、轉賬和查詢三個方法。
pragma solidity ^0.4.0;
contract CreditManager {
int256 creditLimit = 1000000000; // the issue limit
int256 issueAmount = 0; // the issue total amount
identity admin; // the administrator in contract
mapping(identity=>int256) credit;
event IssueEvent(identity indexed to, int256 indexed value);
event TransferEvent(identity indexed from, identity indexed to, int256 indexed value);
function CreditManager() {
admin = msg.sender;
}
// modifier
modifier onlyAdmin() {
require(msg.sender == admin,"Permission denied");
_;
}
// issue credit and only admin can
function Issue(identity account, int256 value) public onlyAdmin returns(bool) {
// the value should bigger than 0, and issueAmount add value should small than issueAmount
require(issueAmount + value <= creditLimit && issueAmount + value > issueAmount && value > 0, "Invalid value!");
credit[account] += value;
issueAmount += value;
IssueEvent(account,value);
return true;
}
function Transfer(identity account,int256 value) public returns(bool) {
require(credit[msg.sender] >= value, "balance not enough!");
require(value > 0 && value <= creditLimit, "Invalid value!");
credit[msg.sender] -= value;
credit[account] += value;
TransferEvent(msg.sender,account,value);
return true;
}
function Query(identity account) public returns(int256) {
return credit[account];
}
}程式碼分析
聲明合約版本
首先,合約需要聲明其版本,合約具體實現以 contract 關鍵字聲明開始。
如下代碼所示(截取自上述程式碼範例,下同),螞蟻區塊鏈合約平台基於 Solidity 的 0.4.24 版本進行了修改與設計,支援 0.4.24 版本之前的各種特性。
pragma solidity ^0.4.0;
contract CreditManager {聲明變數
本合約樣本中,定義了兩個變數來儲存積分的總量(creditLimit)和目前發放的數量(issueAmount),並使用 identity 類型來標註每一個使用者的身份,如合約的管理員(admin)賬戶,identity 的長度為 32 位元組,每個 identity 在區塊鏈上具有唯一性,所以合約通過 identity 來標註使用者的積分。
int256 creditLimit = 1000000000; // the isuue limit
int256 issueAmount = 0; // the issue total amount
identity admin; // the administrator in contract
mapping(identity=>int256) credit;聲明事件
本合約樣本中,聲明了兩個事件來記錄對應的方法執行的情況,一個是積分發放的事件記錄(IssueEvent),另一個則是積分轉賬的事件記錄(TransferEvent)。
event IssueEvent(identity indexed to, int256 indexed value);
event TransferEvent(identity indexed from, identity indexed to, int256 indexed value);建構函式
在建構函式中,設定合約管理員(admin)賬戶 ID,再使用關鍵字 modifier 設定管理員權限。關鍵字的具體說明參見合約關鍵字。
function CreditManager() {
admin = msg.sender;
}
// modifier,when mas.sender != admin, the contract will show "Permission denied" in output
modifier onlyAdmin() {
require(msg.sender == admin,"Permission denied");
_;
}定義實現方法
本樣本中,合約實現了積分的發放、轉賬和查詢方法。
如下代碼所示,在調用積分發放方法中,通過 onlyAdmin 來保證發放操作只能通過管理員來進行,然後向使用者傳入的賬戶中增加相應的積分,發放過程中需要注意積分的溢出問題,發放完畢後,可以觸發積分發放事件,使用者可以在調用合約發放方法結果的日誌中看到該事件記錄。
// issue credit and only admin can
function Issue(identity account, int256 value) public onlyAdmin returns(bool) {
// the value should bigger than 0, and issueAmount add value should small than issueAmount
require(issueAmount + value <= creditLimit && issueAmount + value > issueAmount && value > 0, "Invalid value!");
credit[account] += value;
issueAmount += value;
IssueEvent(account,value);
return true;
}合約的轉賬與發放類似,但是轉賬不需要有管理員權限即可執行,查詢積分也是一樣。