2.4.1 Layout of a Solidity Source File

Layout of a Solidity Source File

本文档翻译自 Solidity docs

源文件可以包含任意数量的 contract定义import 指令和 pragma 指令。

Pragmas

pragma 关键字可用于启用某些编译器功能或检查。 pragma指令始终是源文件的本地指令,因此如果要在所有项目中启用它,则必须将pragma添加到所有文件中。如果 import 另一个文件,该文件中的pragma将不会自动应用于导入文件。

Version Pragma

源文件可以(并且应该)使用所谓的版本编译指示进行注释,以拒绝使用可能引入不兼容更改的未来编译器版本进行编译。我们尝试将这些更改保持在绝对最小值,尤其是以语义变化也需要更改语法的方式引入更改,但这当然不总是可行的。因此,至少对于包含重大更改的版本来读取更改日志总是一个好主意,这些版本将始终具有 0.x.0x.0.0 形式的版本。

版本编译指示使用如下:

pragma solidity ^0.4.0;

这样的源文件不会使用早于版本0.4.0的编译器进行编译,并且它也不能在从版本0.5.0开始的编译器上工作(通过使用 ^ 添加第二个条件)。这背后的想法是在版本 0.5.0 之前不会有任何重大更改,因此我们始终可以确保我们的代码将按照我们的预期方式进行编译。我们没有修复编译器的确切版本,因此仍然可以使用bugfix版本。

可以为编译器版本指定更复杂的规则,表达式遵循 npm 使用的表达式。

Note

使用版本编译指示不会更改编译器的版本。它也不会启用或禁用编译器的功能。它只是指示编译器检查其版本是否与pragma所需的版本匹配。如果不匹配,编译器将发出错误。

Experimental Pragma

第二个pragma是实验性的pragma。它可用于启用默认情况下尚未启用的编译器或语言的功能。目前支持以下实验编译指示:

ABIEncoderV2

新的ABI编码器能够对任意嵌套的数组和结构进行编码和解码。它产生的优化代码不太理想(这部分代码的优化器仍在开发中)并且没有像旧编码器那样接收到太多的测试。您可以使用 pragma experimental ABIEncoderV2; 激活它。

SMTChecker

构建Solidity编译器时必须启用此组件,因此它不适用于所有Solidity二进制文件。构建说明解释了如何激活此选项。它在大多数版本中为Ubuntu PPA版本激活,但不适用于solc-js,Docker镜像,Windows二进制文件或静态构建的Linux二进制文件。

如果您使用 pragma experimental SMTChecker;,那么您将获得通过查询SMT求解器获得的其他安全警告。该组件尚不支持Solidity语言的所有功能,可能会输出许多警告。如果报告不支持的功能,分析可能不完整。

Importing other Source Files

Syntax and Semantics

Solidity支持与JavaScript中可用的导入语句非常相似的语句(来自ES6),尽管Solidity不知道“默认导出”的概念。

在全局级别,您可以使用以下形式的import语句:

import "filename";

此语句将所有全局符号从“filename”(以及在那里导入的符号)导入当前全局范围(与ES6不同,但向后兼容Solidity)。建议不要使用这种简单的形式,因为它会以不可预测的方式污染命名空间:如果在“filename”中添加新的顶级项,它们将自动出现在所有从“filename”导入的文件中。最好明确导入特定符号。

以下示例创建一个新的全局符号 symbolName,其成员是 “filename” 中的所有全局符号。

import * as symbolName from "filename";

如果存在命名冲突,您还可以在导入时重命名符号。此代码创建新的全局符号 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 始终被视为带 / 作为目录分隔符的路径。. 作为当前和 .. 作为父目录。什么时候 ... 后跟一个字符,除了 /,它不被视为当前或父目录。所有路径名都被视为绝对路径,除非它们以当前路径 . 开头,或者父目录 ..

要从与当前文件相同的目录导入文件 x,请使用 import "./x" as x;。如果使用 import "x" as x; 相反,可能引用不同的文件(在全局 “include director” 中)。

这取决于编译器(见下文)如何实际解析路径。通常,目录层次结构不需要严格映射到本地文件系统,它也可以映射到通过发现的资源,例如 ipfs,http或git。

Note

始终使用 `import "./filename.sol";` 之类的相对导入;并避免在路径说明符中使用 `..`。在后一种情况下,最好使用全局路径并设置重映射,如下所述。

Use in Actual Compilers

调用编译器时,您可以指定如何发现路径的第一个元素以及路径前缀重映射。例如,您可以设置重映射,以便从您的本地目录 /usr/local/dapp-bin/library 中实际读取从虚拟目录 github.com/ethereum/dapp-bin/library 导入的所有内容。如果应用多个重映射,则首先尝试具有最长密钥的那个。不允许使用空前缀。重映射可以取决于上下文,允许您配置要导入的包,例如,同名库的不同版本。

solc:

对于solc(命令行编译器),您将这些路径重映射提供为 context:prefix=target arguments,其中 context:= target 部分都是可选的(在这种情况下,target 默认为 prefix)。编译常规文件的所有重映射值(包括它们的依赖关系)。

这种机制是向后兼容的(只要没有文件名包含 =:),因此不会发生重大变化。导入以 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

作为一个更复杂的示例,假设您依赖于使用您签出到 /usr/local/dapp-bin_old 的旧版dapp-bin的模块,那么您可以运行:

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 中的导入指向新版本。

Note

`solc` 只允许您包含某些目录中的文件。它们必须位于其中一个显式指定的源文件的目录(或子目录)中,或者位于重映射目标的目录(或子目录)中。如果要允许直接绝对包含,请添加重映射 `/=/`。

如果存在多个导致有效文件的重映射,则选择具有最长公共前缀的重映射。

Remix:

Remix 为GitHub提供自动重映射,并通过网络自动检索文件。您可以导入上面的可迭代映射,例如

::

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,FF,CR,NEL,LS或PS)终止。注释后终结符仍然是源代码的一部分,因此如果它不是ascii符号(这些是NEL,LS和PS),则会导致解析器错误。

此外,还有另一种称为natspec注释的注释,其文档尚未编写。它们使用三斜杠 (///) 或双星号块 (/** ... */) 编写,它们应直接在函数声明或语句之上使用。您可以在这些注释中使用 Doxygen样式 的标记来记录函数,注释形式验证的条件,并提供在用户尝试调用函数时向用户显示的确认文本。

在下面的示例中,我们记录了合约的标题,两个函数参数的说明和两个返回变量。

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

项目源代码

项目源代码会逐步上传到 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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容