手记

第一行代码:以太坊(2)-使用Solidity语言开发和测试智能合约

智能合约是以太坊的核心之一,用户可以利用智能合约实现更灵活的代币以及其他DApp。不过在深入讲解如何开发智能合约之前,需要先介绍一下以太坊中用于开发智能合约的Solidity语言,以及相关的开发和测试环境。

智能合约就是运行在以太坊上的程序。客户端可以通过Web3.js API调用智能合约,而智能合约本身又可以直接访问以太坊网络,也就是说,智能合约前面连接着客户端,后面连接着以太坊网络,起到了承前启后的作用,而且通过智能合约,可以让整个以太坊网络更灵活,可控性更强。其实智能合约的作用相当于微软Office中的VBA,一个功能强大的领域脚本语言。智能合约的开发语言是Solidity,那么Solidity是什么呢?应该如何在以太坊网络上运行用Solidity语言编写的智能合约呢?本文将会揭晓这些问题的答案。

1. 什么是Solidity语言

Solidity是一种用于编写智能合约的高级语言,运行在Ethereum虚拟机(以太坊虚拟机,EVM)之上。那么Solidity到底是怎样一种编程语言呢?或者说Solidity语言的主要特性是什么呢?请继续往下看。

Solidity语言的语法接近于JavaScript,是一种面向对象的语言。但作为一种真正意义上运行在网络上的去中心智能合约,它又有很多的不同,下面列举一些Solidity语言的主要特性。

  • 以太坊底层是基于帐户的,因此在Solidity语言中有一个特殊的Address数据类型。用于定位用户,定位合约,定位合约的代码(合约本身也是一个帐户)。

  • 由于Solidity语言内嵌框架是支持支付的,所以提供了一些关键字,如payable,可以在语言层面直接支持支付。

  • Solidity语言可以将数据存储在区块链上,数据的每一个状态都可以永久存储,所以需要确定变量使用的是内存,还是区块。

  • 运行环境是在去中心化的网络上,会比较强调合约或函数执行的调用的方式。因为原来一个简单的函数调用变为了一个网络上的节点中的代码执行。

  • 最后一个非常大的不同则是Solidity语言的异常机制,一旦出现异常,所有的执行都将会被回撤,这主要是为了保证智能合约执行的原子性,以避免中间状态出现的数据不一致。有点类似于数据库中的事务回滚。

2. 用Solidity语言开发智能合约

Solidity是一种图灵完备的编程语言,所以编程的方式与Java、C++类似。不过Solidity语言中并没有类的概念,但有一个合约的概念,用关键字contract表示。任何一个Solidity程序,都必须至少有一个合约(contract)。在合约中可以编写Solidity函数,类似于类中的方法。Solidity源代码文件的扩展名是sol,下面的例子给出了一个简单的使用Solidity语言编写的智能合约的例子,以便读者对Solidity语言和智能合约有一个感性的认识。

下面的例子给出了一个名为Calc的智能合约程序,在该智能合约中有一个add函数,用于将两个无符号整数相加,并返回相加的结果。

pragma solidity ^0.4.0;
contract Calc{    function add(uint a,uint b) returns (uint){        return a + b;
    }
}

尽管现在还没有正式讲解Solidity语言和智能合约,不过从这段简单的智能合约代码也可以了解Solidity语言的结构。首先,智能合约的第1行需要使用pragma solidity指定Solidity编译器的最低版本,本例是0.4.0,也就是说,要编译这段Solidity程序,Solidity编译器的版本不能低于0.4.0。要记住,在版本号前面要加上“^”。

接下来就是用contract关键字声明智能合约,语法与类非常接近,智能合约的名字跟在contract关键字后面,智能合约中的代码用一对花括号括起来。

最后是在智能合约中声明若干个函数,函数的语法与JavaScript类似(都是使用function关键字声明函数),不过也不完全相同,因为Solidity是强类型的编程语言,而JavaScript是弱类型的编程语言。也就是说,声明Solidity变量需要指定数据类型,如本例的uint,表示无符号整数类型。函数的返回值类型需要在函数声明的结尾通过returns关键字指定。如本例的returns(uint),函数返回值与C风格的编程语言相同,仍然使用return语句指定函数返回值。Solidity语言的每一条语句后面都要跟分号(;)。

3. 使用Remix运行智能合约

学习编写智能合约最重要的一步就是运行智能合约,否则无法知道我们编写的智能合约程序是否正确。在正常情况下,应该将智能合约部署在以太坊网络上,然后通过以太坊客户端调用,不过现在还没有讲如何将智能合约部署到以太坊网络上,以及如何调用智能合约。所以目前只能使用最简单的方式测试智能合约。以太坊官方提供了一个在线的智能合约编写和测试环境:Remix,通过这个工具,可以用不同的方式测试智能合约。
在浏览器地址栏输入如下的Url后,会进入Remix页面。

https://remix.ethereum.org

Remix页面主要包含如下4部分。

  • 智能合约列表区域,位于Remix页面的左侧,如果第一次使用Remix,这个区域只有browser和config两个节点,如果以前使用Remix创建过智能合约,会在browser节点下方显示曾经创建过的智能合约文件(.sol文件)。

  • 代码区域,位于Remix页面的中上部,用于编写智能合约代码。

  • 日志区域,位于Remix页面的中下部,运行智能合约后,会将日志信息输出到这一区域。

  • 设置区域,位于Remix页面右侧,在这一区域可进行各种设置,如将智能合约部署在以太坊网络上,运行智能合约等。

除了这4部分外,在Remix页面左上角还有一排按钮,其中最左侧的加号按钮用于新建智能合约,最右侧的加号和减号按钮分别用于增加和减少智能合约代码的字号。Remix页面的整体布局如下图所示。

接下来单击Remix页面左上角的加号按钮,会弹出一个如下图所示的页面,在“File Name”文本框输入“Calc.sol”,然后单击“OK”按钮创建新的智能合约。

将上一节给出的智能合约代码输入代码区域,可以点击加号和减号按钮将代码字体调整到自己感觉舒服的程度,效果如下图所示。在设置区域会出现一些警告,并不需要管它们。

在设置区域切换到“Run”页面,所有的设置保持默认值即可,然后点击中间的“Deploy”部署Calc合约。成功部署Calc合约后,会在“Run”页面下方根据Calc合约中的函数显示相应的按钮,如本例中只有一个add函数,并且该函数有两个参数,所以在“Run”页面下方会出现一个“add”按钮,在按钮旁边的文本框输入“3,4”,表示add函数的两个参数值,如下图所示。

最后单击“add”按钮执行add函数,会在日志区域显示相应的信息,然后单击日志区域输出信息的向下箭头,会在日志区域显示一个表格,在“decoded output”行会显示add函数的返回值(计算结果),如下图所示。

通过本节的若干步骤,终于成功运行了Calc智能合约的add函数,并获得了add函数的返回值(本例是7),不过这个智能合约程序并没有部署在以太坊网络上,而是在本地运行的,也就是说,本节其实是通过模拟的方式运行了本地合约,这种运行方式只能测试智能合约中的函数的逻辑是否正确,并不能将以太坊客户端、以太坊网络和智能合约放到一起联调,所以在实际的场景中,需要将智能合约部署到以太坊网络上才能完整地对其进行测试。


6人推荐
随时随地看视频
慕课网APP