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

&#x20;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”。

&#x20;还有一种用法，可能会更符合多数程序员的习惯：

&#x20;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”

&#x20;重映射依赖于源代码的上下文。当同一个库文件有不同的版本时，用户可以利用这个特性定义具体使用哪个版本。我们以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;

&#x20;然后用下列命令进行编译：

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

&#x20;下面我们看一个更复杂的例子。加入用户要使用的一个模块，这个模块会用到一个很老版本的dapp-in。这个dapp-in的路径为/usr/local/dapp-bin\_old，可以用如下命令：

solc module1:github.com/ethereum/dapp-bin/=/usr/local/dapp-bin/ \\

&#x20;module2:github.com/ethereum/dapp-bin/=/usr/local/dapp-bin\_old/ \\

&#x20;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 {

&#x20;/\*\* @dev Calculates a rectangle's surface and perimeter.

&#x20;\* @param w Width of the rectangle.

&#x20;\* @param h Height of the rectangle.

&#x20;\* @return s The calculated surface.

&#x20;\* @return p The calculated perimeter.

&#x20;\*/

&#x20;function rectangle(uint w, uint h) returns (uint s, uint p) {

&#x20;s = w \* h;

&#x20;p = 2 \* (w + h);

&#x20;}

}
