深刻理解Solidity之二---Solidity源代碼文件結構

Solidity源代碼文件結構git

源文件能夠包含任意數量的合約定義,包括指令和編譯指示。github

版本Pragma
源文件能夠(也應該)用所謂的版本註釋來註釋,以拒絕被編譯爲將來可能引入不兼容更改的編譯器版本。 咱們試圖將這種變化保持在絕對最低限度,特別是引入變化的方式是語義的變化也須要語法的變化,但這固然不老是可能的。 所以,至少對於包含重大更改的版本,通讀更新日誌老是一個好主意,這些版本始終具備0.x.0或x.0.0格式的版本。npm

版本附註使用以下:網絡

pragma solidity ^0.4.0;

這樣的源代碼文件不會使用早於版本0.4.0的編譯器進行編譯,而且它也不適用於從版本0.5.0開始的編譯器(第二個條件是使用^添加的)。 這背後的想法是,在版本0.5.0以前不會有任何重大更改,因此咱們始終能夠肯定咱們的代碼將按照咱們打算的方式進行編譯。 咱們不修復編譯器的確切版本,所以bug修復版本仍然有可能。
能夠爲編譯器版本指定更復雜的規則,表達式遵循npm使用的規則。app

導入其餘源文件
語法和語義函數

Solidity支持很是相似於JavaScript中可用的導入語句(來自ES6),儘管Solidity不知道「默認導出」的概念。ui

在全局範圍內,您可使用如下格式的導入語句:命令行

import "filename";

該語句從「文件名」(及其導入的符號)中導入全部全局符號到當前全局做用域(與ES6不一樣,但向後兼容Solidity)。翻譯

import * as symbolName from "filename";

...建立一個新的全局符號symbolName,其成員所有來自「filename」的全局符號。日誌

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

...分別建立新的全局符號aliassymbol2,它們分別從「filename」引用symbol1symbol2

另外一種語法不是ES6的一部分,但可能很方便:

import "filename" as symbolName;

這至關於從import * as symbolName from "filename";

Paths

在上面,filename老是被視爲一個路徑,其中/做爲目錄分隔符。.做爲當前和..做爲父目錄。 何時 ...後跟一個除/之外的字符,它不被視爲當前或父目錄。 全部路徑名都被視爲絕對路徑,除非它們以當前的.或父目錄開頭..

要從與當前文件相同的目錄中導入文件x,請使用import "./x" as x;. 若是使用import "x" as x; 則能夠引用不一樣的文件(在全局「包含目錄」中)。

它取決於編譯器(見下文)如何實際解析路徑。 一般,目錄層次不須要嚴格映射到你的本地文件系統,它也能夠映射到經過例如發現的資源。 ipfs,http或者git。

在實際編譯器中使用

調用編譯器時,不只能夠指定如何發現路徑的第一個元素,但能夠指定路徑前綴從新映射,以便例如 github.com/ethereum/dapp-bin/library被從新映射到/usr/local/dapp-bin/library,編譯器將從那裏讀取文件。 若是能夠應用多重重映射,則首先嚐試使用最長密鑰的那個。 這容許用例如fallback-remapping ""映射到/usr/local/include/solidity

(原文:This allows for a "fallback-remapping" with e.g. "" maps to
> "/usr/local/include/solidity") 翻譯的不太通順。

。 此外,這些從新映射可能取決於上下文,從而容許您配置要導入的包。 不一樣版本的同名圖書館。

solc:
對於solc(命令行編譯器),這些從新映射是做爲context:prefix = target參數提供的,其中context:= target部分都是可選的(在這種狀況下目標缺省爲前綴)。 全部重映射值都是常規文件(包括它們的依賴關係)。 這種機制是徹底向後兼容的(只要沒有文件名包含=或:),所以不是一個突破性的改變。 在導入以prefix開頭的文件的context目錄下的文件中的全部導入都將經過將prefix替換爲target進行重定向。
例如,若是您將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的舊版本在/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;

將來可能會添加其餘源代碼提供者。

Comments
單行註釋(//)和多行註釋(/*...*/)是可用的。

// This is a single-line comment.

/*
This is a
multi-line comment.
*/

此外,還有另外一種類型的註釋稱爲natspec註釋,對此文檔還沒有編寫。 它們用三斜槓(///)或雙星號塊(/ ** ... * /)編寫,它們應該直接用在函數聲明或語句之上。 您能夠在這些註釋中使用Doxygen風格的標籤來記錄函數,爲形式驗證註釋條件,並提供確認文本,當用戶嘗試調用函數時向用戶顯示。

在下面的例子中,咱們記錄了合同的標題,兩個輸入參數和兩個返回值的解釋。

pragma solidity ^0.4.0;

/** @title Shape calculator. */
contract shapeCalculator {
    /** @dev Calculates a rectangle's surface and perimeter.
      * @param w Width of the rectangle.
      * @param h Height of the rectangle.
      * @return s The calculated surface.
      * @return p The calculated perimeter.
      */
    function rectangle(uint w, uint h) returns (uint s, uint p) {
        s = w * h;
        p = 2 * (w + h);
    }
}
相關文章
相關標籤/搜索