深刻理解Solidity之源文件及合約結構——Solidity中文文檔(4)

image

寫在前面:HiBlock區塊鏈社區成立了翻譯小組,翻譯區塊鏈相關的技術文檔及資料,本文爲Solidity文檔翻譯的第四部分《深刻理解Solidity之源文件及合約結構》,特發佈出來邀請solidity愛好者、開發者作公開的審校,您能夠添加微信baobaotalk_com,驗證輸入「solidity」,而後將您的意見和建議發送給咱們,也能夠在文末「留言」區留言,有效的建議咱們會採納及合併進下一版本,同時將送一份小禮物給您以示感謝。git

Solidity 源文件結構github

源文件中能夠包含任意多個合約定義、導入指令和雜注指令。npm

1

版本雜注

爲了不將來被可能引入不兼容變動的編譯器所編譯,源文件能夠(也應該)被所謂的版本 雜注pragma所註解。  咱們力圖把這類變動作到儘量小,特別是,咱們須要以一種當修改語義時必須同步修改語法的方式引入變動,固然這有時候也難以作到。 所以,至少對含重大變動的版本,通讀變動日誌永遠是好辦法。 這些版本的版本號始終是 0.x.0 或者 x.0.0 的形式。編程

版本雜注使用以下:微信

pragma solidity ^0.4.0;網絡

這樣,源文件將既不容許低於 0.4.0 版本的編譯器編譯, 也不容許高於(包含) 0.5.0 版本的編譯器編譯(第二個條件因使用 ^ 被添加)。 這種作法的考慮是,編譯器在 0.5.0 版本以前不會有重大變動,因此可確保源代碼始終按預期被編譯。 上面例子中不固定編譯器的具體版本號,所以編譯器的補丁版也可使用。app

可使用更復雜的規則來指定編譯器的版本,表達式遵循 npm 版本語義。編程語言

image

2

導入其餘源文件

語法與語義函數

雖然 Solidity 不知道 "default export" 爲什麼物, 可是 Solidity 所支持的導入語句,其語法同 JavaScript(從 ES6 起)很是相似。工具

image

在全局層面上,可以使用以下格式的導入語句:

import "filename";

此語句將從 「filename」 中導入全部的全局符號到當前全局做用域中(不一樣於 ES6,Solidity 是向後兼容的)。

import * as symbolName from "filename";

...建立一個新的全局符號 symbolName,其成員均來自 "filename" 中全局符號。

import {symbol1 as alias, symbol2} from "filename";

...建立新的全局符號 alias 和 symbol2,分別從 "filename" 引用 symbol1 和 symbol2 。

另外一種語法不屬於 ES6,但或許更簡便:

import "filename" as symbolName;

這條語句等同於

import * as symbolName from "filename";

路徑

上文中的 filename 老是會按路徑來處理,以 / 做爲目錄分割符、以 . 標示當前目錄、以 .. 表示父目錄。 當 . 或 .. 後面跟隨的字符是 / 時,它們才能被當作當前目錄或父目錄。 只有路徑以當前目錄 . 或父目錄 .. 開頭時,才能被視爲相對路徑。

用 import "./x" as x; 語句導入當前源文件同目錄下的文件 x 。 若是用 import "x" as x; 代替,可能會引入不一樣的文件(在全局 include directory 中)。

最終導入哪一個文件取決於編譯器(見下文)究竟是怎樣解析路徑的。 一般,目錄層次沒必要嚴格映射到本地文件系統, 它也能夠映射到能經過諸如 ipfs,http 或者 git 發現的資源。

在實際的編譯器中使用

當運行編譯器時,它不只能指定如何發現路徑的第一個元素,還可指定路徑前綴 重映射remapping。 例如,github.com/ethereum/dapp-bin/library 會被重映射到 /usr/local/dapp-bin/library , 此時編譯器將從重映射位置讀取文件。若是重映射到多個路徑,優先嚐試重映射路徑最長的一個。 這容許將好比 "" 被映射到 "/usr/local/include/solidity" 來進行「回退重映射」。 同時,這些重映射可取決於上下文,容許你配置要導入的包,好比同一個庫的不一樣版本。

solc:

對於 solc(命令行編譯器),這些重映射以 context:prefix=target 形式的參數提供。 其中,context: 和 =target 部分是可選的(此時 target 默認爲 prefix )。 全部重映射的值都是被編譯過的常規文件(包括他們的依賴),這個機制徹底是向後兼容的(只要文件名不包含 = 或 : ), 所以這不是一個破壞性修改。 在 content 目錄或其子目錄中的源碼文件中,全部導入語句裏以 prefix 開頭的導入文件都將被用 target 替換 prefix 來重定向。

舉個例子,若是你已克隆 github.com/ethereum/dapp-bin/ 到本地 /usr/local/dapp-bin , 可在源文件中使用:

import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;

而後運行編譯器:

solc github.com/ethereum/dapp-bin/=/usr/local/dapp-bin/ source.sol

舉個更復雜的例子,假設你依賴了一些使用了很是舊版本的 dapp-bin 的模塊。 舊版本的 dapp-bin 已經被 checkout 到 /usr/local/dapp-bin_old ,此時你可以使用:

solc module1:github.com/ethereum/dapp-bin/=/usr/local/dapp-bin/ \

module2:github.com/ethereum/dapp-bin/=/usr/local/dapp-bin_old/ source.sol

這樣, module2 中的全部導入都指向舊版本,而 module1 中的導入則獲取新版本。

注意, solc 只容許包含來自特定目錄的文件:它們必須位於顯式地指定的源文件目錄(或子目錄)中,或者重映射的目標目錄(或子目錄)中。 若是你想直接用絕對路徑來包含文件,只需添加劇映射 =/。

若是有多個重映射指向一個有效文件,那麼具備最長公共前綴的重映射會被選用。

Remix:

Remix 提供一個爲 github 源代碼平臺的自動重映射,它將經過網絡自動獲取文件: 好比,你可使用

import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;

導入一個 map 迭代器。

將來, Remix 可能支持其餘源代碼平臺。

3

注  釋

可使用單行註釋(//)和多行註釋(/.../)

// 這是一個單行註釋。

/*

這是一個多行註釋。

*/

此外,有另外一種註釋稱爲 natspec 註釋,其文檔還還沒有編寫。 它們是用三個反斜槓(///)或雙星號開頭的塊(/** ... */)書寫,它們應該直接在函數聲明或語句上使用。 可在註釋中使用 Doxygen 樣式的標籤來文檔化函數、 標註形式校驗經過的條件,和提供一個當用戶試圖調用一個函數時顯示給用戶的 確認文本

在下面的例子中,咱們記錄了合約的標題、兩個入參和兩個返回值的說明:

pragma solidity ^0.4.0;

/@title 形狀計算器。 /

*contract shapeCalculator {   * / @dev 求矩形代表面積與周長。    

*   * @param w 矩形寬度。    *

*   * @param h 矩形高度。    *

*   * @return s 求得表面積。   *

*   * @return p 求得周長。    *

*   /    function rectangle(uint w, uint h) returns (uint s, uint p) {        s = w ***** h;        p** =** 2 ***** (w + h);    }

}

合約結構

在 Solidity 中,合約相似於面向對象編程語言中的類。 每一個合約中能夠包含 狀態變量、 函數、 函數修飾器、事件、 結構類型、 和 枚舉類型 的聲明,且合約能夠從其餘合約繼承。

1 狀態變量

狀態變量是永久地存儲在合約存儲中的值。

pragma solidity ^0.4.0;

contract SimpleStorage {  **  uint** storedData; // 狀態變量    // ...

}

有效的狀態變量類型參閱 類型 章節, 對狀態變量可見性有可能的選擇參閱 Visibility and Getters 。

2 函  數

函數是合約中代碼的可執行單元。

pragma solidity ^0.4.0;

contract SimpleAuction {    function bid() public payable { // 函數        // ...    }

}

Function Calls 可發生在合約內部或外部,且函數對其餘合約有不一樣程度的可見性( Visibility and Getters)。

3 函數修飾器

函數修飾器能夠用來以聲明的方式改良函數語義(參閱合約章節中 Function Modifiers)。

pragma solidity ^0.4.11;

**contract **Purchase {    address public seller;

   **modifier **onlySeller() { // 修飾器        require(msg.sender == seller);        _;    }

  ** function** abort() **public **onlySeller { // Modifier usage        // ...    }

}

4 事  件

事件是與以太坊虛擬機日誌工具的方便接口。

pragma solidity ^0.4.0;

**contract **SimpleAuction {

   event HighestBidIncreased(address bidder, uint amount);* // 事件*

  ** function** bid() public payable {        // ...        HighestBidIncreased(msg.sender, msg.value); // 觸發事件    }

}

有關如何聲明事件和如何在 dapp 中使用事件的信息,參閱合約章節中的 Events。

5 結構類型

結構是能夠將幾個變量分組的自定義類型(參閱類型章節中的 Structs)。

pragma solidity ^0.4.0;

**contract **Ballot {   ** struct Voter { // 結構        uint weight;        bool voted;        address delegate;        uint vote;    }

}

6 枚舉類型

枚舉可用來建立有必定數量的值的自定義類型(參閱類型章節中的 Enums)。

pragma solidity ^0.4.0;

contract Purchase {    enum State { Created, Locked, Inactive } // 枚舉

}

本文內容來源於HiBlock區塊鏈社區翻譯小組,感謝全體譯者的辛苦工做。

:本文爲solidity翻譯的第四部分《深刻理解Solidity之源文件及合約結構》,特發佈出來邀請solidity愛好者、開發者作公開的審校,您能夠添加微信baobaotalk_com,驗證輸入「solidity」,而後將您的意見和建議發送給咱們,也可在文末「留言」區留言,或經過原文連接訪問咱們的Github。有效的建議咱們會收納並及時改進,同時將送一份小禮物給您以示感謝。

課程回放:(識別圖中二維碼便可觀看視頻)

image

如下是咱們的社區介紹,歡迎各類合做、交流、學習:)

image

相關文章
相關標籤/搜索