全部產品
Search
文件中心

:Solidity合約初識

更新時間:Jul 06, 2024

本文將通過一個簡單的合約程式碼範例,對代碼結構進行說明。

程式碼範例

如下代碼所示,這是螞蟻區塊鏈合約平台對積分管理方案的簡單實現,主要實現了積分的發放、轉賬和查詢三個方法。

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;
    }

合約的轉賬與發放類似,但是轉賬不需要有管理員權限即可執行,查詢積分也是一樣。