1.6.1 典型Solidity源文件包含的组成部分

Solidity是以太坊创始人之一的Gavin Wood博士发明的以太坊智能合约编程语言,它是一个面向合约的高级语言,其语法类似Javascript,运行在以太坊虚拟机中。

Solidity是静态类型的编程语言,编译期间会检查其数据类型,它支持继承,类和复杂的用户定义类型。

本节我们将会分门别类介绍Solidity语言的各个特性。本章所有内容基于Solidity 0.4.24版本,其参考网址为:https://solidity.readthedocs.io/en/v0.4.24/

1.6.1 典型Solidity源文件包含的组成部分

一个Solidity源文件可以包含任意的智能合约定义,标识符及编译标识。

1.6.1.1 Pragma版本

Solidity源文件可以包含标识符所指定的编译器版本。如果不指定编译器版本,系统可能调用不兼容的编译器来编译源文件,从而产生编译错误。

编译器标识符的使用方式如下:

pragma solidity ^0.4.0;

经过这样定义,系统编译该文件时,就不会调用早于0.4.0和晚于(包括)0.5.0的编译器编译。也可以使用npm定义更复杂的编译选项。

1.6.1.2 导入源文件

1.6.1.2.1 语义及语法

和javascript类似,Solidity可以导入其它源文件。

可以在全局作用域导入其它源文件,比如:

import “filename”;

该语句将在此源文件中包含进”filename”的全部内容。

import * as symbolName from "filename";

上面这条语句创建了新的标识“symbolName”,这个新的标识文件名将包含“filename”的所有内容。

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

上面这条语句将把“filename”中的“symbol1”标识为“alias”,“symbol2”标识为“symbol2”。

还有一种用法,可能会更符合多数程序员的习惯:

import "filename" as symbolName;

它等价于 import * as symbolName from "filename";

1.6.1.2.2 路径

在上述定义中“filename”总是被定义为以“/”为分隔符的路径名。“.”表示当前目录,“..”表示当前目录的上一层目录。所有的“filename”定义都会被视为绝对路劲,除非定义以“.”或“..”开头。

1.6.1.2.3 重映射在编译器中的用法

当调用编译器时,不仅可以定义如何找到路径中的第一个目录在哪里,还可以重新映射路径。比如:

github.com/ethereum/dapp-bin/library

可以被重新映射为:

/usr/local/dapp-bin/library

这样编译器就会从“/usr/local/dapp-bin/library”读取文件。如果定义了多个重映射,则包含最长字符的那个会被首先作为重映射。这种用法可用于“回退重映射”(“fallback-remapping”),比如:

“”

可被重新映射为:

“/usr/local/include/solidity”

重映射依赖于源代码的上下文。当同一个库文件有不同的版本时,用户可以利用这个特性定义具体使用哪个版本。我们以Solc和Remix这两个编译器为例看具体的使用方法。

1)solc编译器

Solc是个命令行编译器。在solc中,重映射可作为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-in。这个dapp-in的路径为/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里面使用的就是老版本的dapp-bin_old,而module1里使用的就是新版本的dapp-in。

2)Remix编译器

Remix能自动把github重映射,自动从github读取文件,用户可以导入迭代映射,如下所示:

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

1.6.1.3 注释

Solidity支持单行注释“//”和多行注释“/*…*/”。

// 这是单行注释

/*

这是

多行注释

*/

另外,还有一种注释符,称为“natspec”注释,这种注释方式并没有正式地出现在官方文档中。这种方式用三个斜杠表示“///”或“/**…*/”。这种注释方式必须紧跟在函数声明或定义之前。用户可以在注释内描述函数的功能,注释函数的判断条件等。在下例中,我们注释了合约名,两个输入参数和两个返回值。

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

}

}