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";
...分別建立新的全局符號alias
和symbol2
,它們分別從「filename
」引用symbol1
和symbol2
。
另外一種語法不是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); } }