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