# 1.3 智能合约的编写与调试

## 1.3.1 智能合约的基本原理

由于智能合约必须是由计算机或计算系统执行，所以当我们具体讨论智能合约的编写，运行等技术实现时必须指定智能合约所依赖的运行环境。在本节中，我们所讨论的智能合约的编写，运行等都是特指以太坊（Ethereum）中的智能合约。

以太坊的智能合约可以理解为代码和数据的结合，存在于以太坊区块链的合约账户中。智能合约在编写完成后，要经过编译，变成以太坊虚拟机（EVM）能识别的字节码（bytecode），然后字节码会在以太坊虚拟机上被执行。

## 1.3.2 智能合约语言

在以太坊中智能合约可以用多种语言进行编写。常见的有Solidity，Serpent，LLL和Mutan。其中Mutan语言已经不再维护，不建议继续使用。在Solidity，Serpent和LLL中，最流行也是目前使用最广，使用人数最多的是Solidity（<http://solidity.readthedocs.io/en/latest/）。Solidity是一种类似Javascript的语言，由以太坊联合创始人Gavin> Wood博士发明。

## 1.3.2 智能合约的结构

用Solidity编写的智能合约一般来说都有自己的通用结构。这个合约就像其它面向对象编程语言中的一个类（class），其中包含状态变量（state variable），函数（function），函数修饰器（function modifier），事件（event），结构（structure），枚举（enum）等。合约也像类一样支持继承，接口，多态等。

## 1.3.3 智能合约的集成开发环境（IDE）

智能合约集成开发环境简称为IDE，是为方便用户开发智能合约由以太坊官方或第三方公司发布的开发工具。

目前市面上的IDE很多。以太坊官方出品的IDE有Mix IDE（<https://github.com/ethereum/wiki/wiki/Mix:-The-DApp-IDE）以及基于浏览器的IDE> Remix Solidity（<http://remix.ethereum.org）。Remix可以让用户直接在浏览器中编写智能合约。> 当用户在IDE中编写好智能合约后可以用以太坊开发框架Truffle给它添加界面并直接打包成去中心化应用DAPP。关于以太坊开发框架Truffle的使用以及DAPP将在后面的章节中介绍。

## 1.3.4 使用IDE Remix编写智能合约

在这里，我们使用浏览器IDE Remix来编写智能合约。具体步骤如下：

第一步：打开IDE Remix。

&#x20;打开任何一个浏览器（比如google chrome），在浏览器地址栏输入：[http://remix.ethereum.org](http://remix.ethereum.org/)，然后回车，会看到如下界面：

![](https://2212368770-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fvyper-smart-contracts%2F-LpKU14f-HKk5cg1QFuq%2F-LpKVLDJ45cCnEKoIuk9%2F0.png?generation=1569097608934764\&alt=media)

在这个页面我们会看到一个缺省已经写好的智能合约。为了让读者快速上手，我们编写一个更简单的合约。

第二步：编写自己的合约。

&#x20;将下面一段代码输入到Remix的窗体。

pragma solidity ^0.4.0;

contract StoreData {

&#x20;uint storedData;

&#x20;function setData(uint inputData) {

&#x20;storedData = inputData;

&#x20;}

&#x20;function getData() public constant returns (uint retVal) {

&#x20;return storedData;

&#x20;}

}

&#x20;这是个功能非常简单的智能合约，它的功能是往合约中存入或读取一个数值。在Remix主窗体输入合约后所见如下图所示。

![](https://2212368770-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fvyper-smart-contracts%2F-LpKU14f-HKk5cg1QFuq%2F-LpKVLDKKjJv9foIxaEH%2F1.png?generation=1569097608907190\&alt=media)

第三步：编译智能合约。

&#x20;首先点击页面右上角“Compile”，然后再点击“Start to compile”开始编译该智能合约，如下图所示。

![](https://2212368770-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fvyper-smart-contracts%2F-LpKU14f-HKk5cg1QFuq%2F-LpKVLDLDVhDmtDDQzZ_%2F2.png?generation=1569097608934890\&alt=media)

## 1.3.5 调试智能合约

&#x20;如果智能合约编译完后，有警告信息或错误信息，会看到如下界面。

![](https://2212368770-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fvyper-smart-contracts%2F-LpKU14f-HKk5cg1QFuq%2F-LpKVLDMb9IvGJm2G8rz%2F3.png?generation=1569097608906945\&alt=media)

&#x20;这里的警告信息提示我们的SetData函数没有定义可见性，并在函数名所在的第五行显示了黄色标记。针对这个警告信息，我们在该函数后加上可见性定义符“public”，即把第五行“function setData(uint inputData)”改成“function setData(uint inputData) public”,然后再编译。这次编译完后系统不再显示任何警告或错误信息，合约编译成功，系统显示合约名。所见界面如下图所示。

![](https://2212368770-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fvyper-smart-contracts%2F-LpKU14f-HKk5cg1QFuq%2F-LpKVLDNC-n8S8zS30j4%2F4.png?generation=1569097608917623\&alt=media)
