序列5 Solidity与web3.js - 智能合约的编写、编译、部署与执行

有兴趣朋友也可以进一步关注公众号“架构之道与术”, 获取原文。 或扫描如下二维码: 序列5 Solidity与web3.js - 智能合约的编写、编译、部署与执行_第1张图片

在序列4 EVM,Solidity和其它各种编程语言中,我们介绍了EVM和Solidity语言。这1节,详细来介绍Solidity语言的语法,以及如何部署、执行智能合约。

整体介绍
在整个过程中,涉及到Solidity和web3.js 2个东西。

首先用Solidity语言编写源代码(相应的IDE编辑工具很多,比如Remix,大家可以自己百度之)。

编写完成之后,用Solc编译器,把源代码编译成Byte Code + ABI(关于什么是ABI,后面有机会再详细介绍。此处可以简单的看成智能合约对外的接口,Application Binary Interface,跟我们通常说的API相对应)。

有了ByteCode + ABI,接下来就是web3.js上场了。

web3.js是以太坊对外提供的1套json rpc接口,通俗点讲:你把web3.js当作客户端,把整个以太坊网络当作服务器,这套接口就是用来实现客户端和服务器之间的各种交互。

web3.js就是一个普通的js文件,你可以在node.js中执行,也可以用浏览器的插件(网上可以自己百度之)。

通过web3.js,我们实现智能合约的部署、调用,下面会详细来讲。

总结一下,整个的编写、编译、部署、执行过程如下:

智能合约编写 – Solidity语法详细介绍
前面说了,Solidity语言类似Java/C++,所以也就具有面向对象语言的各种特征,下面逐个介绍:
contract关键字
前面说过,contract关键字,就类似于Java/C++中的 class 关键字,就是定义了1个类。然后接下来,我们会用web3.js实例化这个类,new1个对象出来。

各种数据类型:整形,布尔,字符串。。。struct结构体、枚举类型、内置数据类型

上面的结构体中, address是个内置数据类型,就是账号的地址;
还有很多其他内置数据类型,比如string, 此处不一一列举。

下面定义了一个枚举类型:

函数、表达式、控制语句
表达式和控制语句(if-else, for循环)此处就不列举了,和Java/C++中类似。
关于函数,也是由各种不同的修饰符,private/public, external/internal。。

函数的修饰符,后面结合案例来逐个讲解,此处不一一列举。

继承、接口、抽象类、多态
Solidity支持多重继承,关键字是is,也可以定义接口或者抽象类(其语法和Java中类似,就是没有实现的contract,此处不详细列举)

library 关键字
library关键字是Solidity的一个新的关键字,其作用就类似于我们在Java/C++中的,一个类里面,没有成员变量,全部是静态成员函数。
library中没有成员变量,全部是函数,其实就是我们常说的“工具类”。比如下面的代码,展示了一个集合的“工具类”:

using for 关键字
solidity中特有的语法,using A for B。
其中A是一个library,B是我们定义的一个数据类型。其作用就是把A中的函数,附加到B上,作为B的成员函数。

为什么可以这么写呢? 因为A是一个library,本身是无状态的,A里面的函数,自然可以作为1个“附加的”东西,添加到任何一个自定义的类型B上面。

Events
上面大致介绍了Solidity语言的全部特征(也是任何一种面向对象的语言通常都有的特征),下面介绍最后1个东西Events。

下面的代码,定义了一个名字叫做Deposit的event。然后在一个函数里面,发射了这个event,关键字是emit。

有人发射,就有人接收。那是谁在接收呢?

是下面的web3.js代码。用了event.watch函数,监听这个event。

关于event的整个原理,以及为什么要设立这样的机制,后面会在专门的章节来介绍。

智能合约编译
写好了上面的智能合约代码,也就是1个xxx.sol文件(后缀是sol),接下来就是用solc来编译成Byte Code + ABI。

可以用Remix这种在线的编辑、编译工具,写完代码,点一下按钮,就生成对应的ByteCode + ABI。

也可以像下面的web3.js代码一样:它把一个叫做nameContract.sol的源文件,编译成了abi + bytecode(摘自web3.js的官方文档)

智能合约部署 – web3.js
智能合约编写好了,也编译了,下面就是通过web3.js 这套接口来部署、执行了。

前面说了,web3.js类似1个客户端,和以太坊这个服务器来交互。具体来说,就是把web3.js 连到1个以太坊的节点,这个节点呢,可以是你自己部署一个节点(比如用Geth),或者你自己不部署节点,连到公网上愿意提供服务的一个以太坊节点,比如https://node.duolian.io/

下面的代码,展示了如何通过web3.js部署一个智能合约:
2步:第1步,定义了一个nameContract变量,其输入参数是用solc编译出来的abi。你可以认为,这里的nameContract其实也是个“类”(和其对应的是Solidity中的contract,只不过1个是Solidity语言编写,1个是web3.js写的,2种不同的表达方式而已)

第2步:用这个“类” new了一个对象出来,输入的关键1个参数,就是data字段,也就是Solidity代码对应的ByteCode。

把这段js执行之后,这个对象,就会被注入到整个以太坊网络存储下来,也就是把这个合约部署了

智能合约的执行
部署之后,智能合约这个对象,就存在了以太坊网络上,接下来,就是调用其ABI接口,执行这个智能合约里面的某些函数。
执行的方式有很多,
可以是在web3.js里面模拟调用;
也可能是1个智能合约调用另1个智能合约;
也可以是1个外部账户发送了1笔交易,触发了某个智能合约的执行,这个智能合约的执行,又触发了其他智能合约。。。

这部分比较绕,要讲清楚,需要对交易、message call、EVM的整个原理有更好的理解,后面会花专门的章节来分析这个。

相关链接:
《序列4 EVM,Solidity和其它各种编程语言》

你可能感兴趣的:(以太坊)