2.4.1 Layout of a Solidity Source File

Layout of a Solidity Source File

本文檔翻譯自 Solidity docs扁瓢。

源文件可以包含任意數(shù)量的 contract定義蜓堕,import 指令和 pragma 指令丙躏。

Pragmas

pragma 關(guān)鍵字可用于啟用某些編譯器功能或檢查谚攒。 pragma指令始終是源文件的本地指令鸡典,因此如果要在所有項(xiàng)目中啟用它,則必須將pragma添加到所有文件中榛丢。如果 import 另一個文件铲球,該文件中的pragma將不會自動應(yīng)用于導(dǎo)入文件。

Version Pragma

源文件可以(并且應(yīng)該)使用所謂的版本編譯指示進(jìn)行注釋晰赞,以拒絕使用可能引入不兼容更改的未來編譯器版本進(jìn)行編譯稼病。我們嘗試將這些更改保持在絕對最小值,尤其是以語義變化也需要更改語法的方式引入更改掖鱼,但這當(dāng)然不總是可行的然走。因此,至少對于包含重大更改的版本來讀取更改日志總是一個好主意戏挡,這些版本將始終具有 0.x.0x.0.0 形式的版本芍瑞。

版本編譯指示使用如下:

pragma solidity ^0.4.0;

這樣的源文件不會使用早于版本0.4.0的編譯器進(jìn)行編譯,并且它也不能在從版本0.5.0開始的編譯器上工作(通過使用 ^ 添加第二個條件)褐墅。這背后的想法是在版本 0.5.0 之前不會有任何重大更改拆檬,因此我們始終可以確保我們的代碼將按照我們的預(yù)期方式進(jìn)行編譯。我們沒有修復(fù)編譯器的確切版本妥凳,因此仍然可以使用bugfix版本竟贯。

可以為編譯器版本指定更復(fù)雜的規(guī)則,表達(dá)式遵循 npm 使用的表達(dá)式猾封。

Note

使用版本編譯指示不會更改編譯器的版本澄耍。它也不會啟用或禁用編譯器的功能。它只是指示編譯器檢查其版本是否與pragma所需的版本匹配晌缘。如果不匹配齐莲,編譯器將發(fā)出錯誤。

Experimental Pragma

第二個pragma是實(shí)驗(yàn)性的pragma磷箕。它可用于啟用默認(rèn)情況下尚未啟用的編譯器或語言的功能选酗。目前支持以下實(shí)驗(yàn)編譯指示:

ABIEncoderV2

新的ABI編碼器能夠?qū)θ我馇短椎臄?shù)組和結(jié)構(gòu)進(jìn)行編碼和解碼。它產(chǎn)生的優(yōu)化代碼不太理想(這部分代碼的優(yōu)化器仍在開發(fā)中)并且沒有像舊編碼器那樣接收到太多的測試岳枷。您可以使用 pragma experimental ABIEncoderV2; 激活它芒填。

SMTChecker

構(gòu)建Solidity編譯器時必須啟用此組件,因此它不適用于所有Solidity二進(jìn)制文件空繁。構(gòu)建說明解釋了如何激活此選項(xiàng)殿衰。它在大多數(shù)版本中為Ubuntu PPA版本激活,但不適用于solc-js盛泡,Docker鏡像闷祥,Windows二進(jìn)制文件或靜態(tài)構(gòu)建的Linux二進(jìn)制文件。

如果您使用 pragma experimental SMTChecker;傲诵,那么您將獲得通過查詢SMT求解器獲得的其他安全警告凯砍。該組件尚不支持Solidity語言的所有功能箱硕,可能會輸出許多警告。如果報告不支持的功能悟衩,分析可能不完整剧罩。

Importing other Source Files

Syntax and Semantics

Solidity支持與JavaScript中可用的導(dǎo)入語句非常相似的語句(來自ES6),盡管Solidity不知道“默認(rèn)導(dǎo)出”的概念座泳。

在全局級別惠昔,您可以使用以下形式的import語句:

import "filename";

此語句將所有全局符號從“filename”(以及在那里導(dǎo)入的符號)導(dǎo)入當(dāng)前全局范圍(與ES6不同,但向后兼容Solidity)钳榨。建議不要使用這種簡單的形式舰罚,因?yàn)樗鼤圆豢深A(yù)測的方式污染命名空間:如果在“filename”中添加新的頂級項(xiàng),它們將自動出現(xiàn)在所有從“filename”導(dǎo)入的文件中薛耻。最好明確導(dǎo)入特定符號营罢。

以下示例創(chuàng)建一個新的全局符號 symbolName,其成員是 “filename” 中的所有全局符號饼齿。

import * as symbolName from "filename";

如果存在命名沖突饲漾,您還可以在導(dǎo)入時重命名符號。此代碼創(chuàng)建新的全局符號 aliassymbol2缕溉,它們分別從 “filename” 中引用 symbol1symbol2考传。

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

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

import "filename" as symbolName;

等價于 import * as symbolName from "filename";证鸥。

Note

如果使用 import “filename.sol” 作為 moduleName;僚楞,則從 “filename.sol” 中作為 moduleName.C 訪問名為 C 的合約,而不是直接使用 C.

Paths

在上面枉层,filename 始終被視為帶 / 作為目錄分隔符的路徑泉褐。. 作為當(dāng)前和 .. 作為父目錄。什么時候 ... 后跟一個字符鸟蜡,除了 /膜赃,它不被視為當(dāng)前或父目錄。所有路徑名都被視為絕對路徑揉忘,除非它們以當(dāng)前路徑 . 開頭跳座,或者父目錄 ..

要從與當(dāng)前文件相同的目錄導(dǎo)入文件 x泣矛,請使用 import "./x" as x;疲眷。如果使用 import "x" as x; 相反,可能引用不同的文件(在全局 “include director” 中)您朽。

這取決于編譯器(見下文)如何實(shí)際解析路徑咪橙。通常,目錄層次結(jié)構(gòu)不需要嚴(yán)格映射到本地文件系統(tǒng),它也可以映射到通過發(fā)現(xiàn)的資源美侦,例如 ipfs,http或git魂奥。

Note

始終使用 `import "./filename.sol";` 之類的相對導(dǎo)入菠剩;并避免在路徑說明符中使用 `..`。在后一種情況下耻煤,最好使用全局路徑并設(shè)置重映射具壮,如下所述。

Use in Actual Compilers

調(diào)用編譯器時哈蝇,您可以指定如何發(fā)現(xiàn)路徑的第一個元素以及路徑前綴重映射棺妓。例如,您可以設(shè)置重映射炮赦,以便從您的本地目錄 /usr/local/dapp-bin/library 中實(shí)際讀取從虛擬目錄 github.com/ethereum/dapp-bin/library 導(dǎo)入的所有內(nèi)容怜跑。如果應(yīng)用多個重映射,則首先嘗試具有最長密鑰的那個吠勘。不允許使用空前綴性芬。重映射可以取決于上下文,允許您配置要導(dǎo)入的包剧防,例如植锉,同名庫的不同版本。

solc:

對于solc(命令行編譯器)峭拘,您將這些路徑重映射提供為 context:prefix=target arguments俊庇,其中 context:= target 部分都是可選的(在這種情況下,target 默認(rèn)為 prefix)鸡挠。編譯常規(guī)文件的所有重映射值(包括它們的依賴關(guān)系)辉饱。

這種機(jī)制是向后兼容的(只要沒有文件名包含 =:),因此不會發(fā)生重大變化宵凌。導(dǎo)入以 prefix 開頭的文件的 context 目錄中或下面的所有文件都通過將 prefix 替換為 target 來重定向鞋囊。

例如,如果將 github.com/ethereum/dapp-bin/ 本地克隆到 /usr/local/dapp-bin瞎惫,則可以在源文件中使用以下內(nèi)容:

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

然后運(yùn)行編譯器:

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

作為一個更復(fù)雜的示例溜腐,假設(shè)您依賴于使用您簽出到 /usr/local/dapp-bin_old 的舊版dapp-bin的模塊,那么您可以運(yùn)行:

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 中的所有導(dǎo)入都指向舊版本瓜喇,但 module1 中的導(dǎo)入指向新版本挺益。

Note

`solc` 只允許您包含某些目錄中的文件。它們必須位于其中一個顯式指定的源文件的目錄(或子目錄)中乘寒,或者位于重映射目標(biāo)的目錄(或子目錄)中望众。如果要允許直接絕對包含,請?zhí)砑又赜成?`/=/`。

如果存在多個導(dǎo)致有效文件的重映射烂翰,則選擇具有最長公共前綴的重映射夯缺。

Remix:

Remix 為GitHub提供自動重映射,并通過網(wǎng)絡(luò)自動檢索文件甘耿。您可以導(dǎo)入上面的可迭代映射踊兜,例如

::

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

Remix可能會在將來添加其他源代碼提供程序。

Comments

可以使用單行注釋 (//) 和多行注釋 (/.../)佳恬。

// This is a single-line comment.

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

Note

單行注釋由utf8編碼中的任何unicode行終止符(LF捏境,VF,F(xiàn)F毁葱,CR垫言,NEL,LS或PS)終止倾剿。注釋后終結(jié)符仍然是源代碼的一部分筷频,因此如果它不是ascii符號(這些是NEL,LS和PS)柱告,則會導(dǎo)致解析器錯誤截驮。

此外,還有另一種稱為natspec注釋的注釋际度,其文檔尚未編寫葵袭。它們使用三斜杠 (///) 或雙星號塊 (/** ... */) 編寫,它們應(yīng)直接在函數(shù)聲明或語句之上使用乖菱。您可以在這些注釋中使用 Doxygen樣式 的標(biāo)記來記錄函數(shù)坡锡,注釋形式驗(yàn)證的條件,并提供在用戶嘗試調(diào)用函數(shù)時向用戶顯示的確認(rèn)文本窒所。

在下面的示例中鹉勒,我們記錄了合約的標(biāo)題,兩個函數(shù)參數(shù)的說明和兩個返回變量吵取。

pragma solidity >=0.4.0 <0.6.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) public pure returns (uint s, uint p) {
        s = w * h;
        p = 2 * (w + h);
    }
}

項(xiàng)目源代碼

項(xiàng)目源代碼會逐步上傳到 Github禽额,地址為 https://github.com/windstamp/dapp

Contributor

  1. Windstamp, https://github.com/windstamp

Reference

  1. https://solidity.readthedocs.io/en/v0.5.0/
  2. https://solidity-cn.readthedocs.io/zh/develop/
  3. https://solidity.readthedocs.io/en/latest/layout-of-source-files.html
  4. https://docs.npmjs.com/misc/semver
  5. https://remix.ethereum.org/#optimize=false
  6. https://en.wikipedia.org/wiki/Doxygen
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末皮官,一起剝皮案震驚了整個濱河市脯倒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌捺氢,老刑警劉巖藻丢,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異摄乒,居然都是意外死亡悠反,警方通過查閱死者的電腦和手機(jī)残黑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斋否,“玉大人梨水,你說我怎么就攤上這事∫鸪簦” “怎么了冰木?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長笼恰。 經(jīng)常有香客問我,道長歇终,這世上最難降的妖魔是什么社证? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮评凝,結(jié)果婚禮上追葡,老公的妹妹穿的比我還像新娘。我一直安慰自己奕短,他們只是感情好宜肉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著翎碑,像睡著了一般谬返。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上日杈,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天遣铝,我揣著相機(jī)與錄音,去河邊找鬼莉擒。 笑死酿炸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的涨冀。 我是一名探鬼主播填硕,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鹿鳖!你這毒婦竟也來了扁眯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤栓辜,失蹤者是張志新(化名)和其女友劉穎恋拍,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藕甩,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡施敢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年周荐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片僵娃。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡概作,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出默怨,到底是詐尸還是另有隱情讯榕,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布匙睹,位于F島的核電站愚屁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏痕檬。R本人自食惡果不足惜霎槐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望梦谜。 院中可真熱鬧丘跌,春花似錦、人聲如沸唁桩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荒澡。三九已至报辱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仰猖,已是汗流浹背捏肢。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饥侵,地道東北人鸵赫。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像躏升,于是被迫代替她去往敵國和親辩棒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容