EOS智能合约分析
EOS智能合约是由一系列action组成,每个action代表一条合约条款,实现了条款中的具体规则。智能合约的执行基于C/S通信架构,分为制作智能合约、部署智能合约和调用智能合约三部分。
1.制作智能合约
智能合约的代码放在eos/contracts/目录下,每个智能合约对应一个独立目录,主要包含cpp文件、hpp文件、abi文件,例如,token合约目录结构如下:
其中,hpp头文件主要包含类定义、全局变量、宏定义等等;cpp源文件主要包含合约函数的实现细节;abi文件全名叫做“Application Binary Interface”(应用程序二进制接口),通过abi接口转换层,用户可以通过JSON格式直接调用智能合约里面的action函数。
2.部署智能合约
用户需要将智能合约C++代码编译成WASM格式(一种面向web的二进制格式,也是区块链唯一能够识别的格式),例如,编写一个用来打印hello world的智能合约:
hello/hello.cpp:
其中,每个智能合约必须实现一个apply()函数,用来将action请求映射到具体的处理函数,具体的实现细节封装在EOSIO_ABI宏里面。这样,开发者只需要专注合约业务逻辑的开发,而不必关注底层技术细节,简化了智能合约开发的工作。
将合约代码变成WASM格式,用于存储在区块链上:
# eosiocpp -o hello.wast hello.cpp
生成abi文件,为其它用户提供一个友好的action调用接口:
# eosiocpp -g hello.abi hello.cpp
Generated hello.abi
abi文件内容:
通过客户端工具cleos,将智能合约发送给服务器,由服务器持久化部署在区块链上,随后可以被其它用户调用执行该合约:
3.调用智能合约
由客户端通过cleos命令发送action请求给服务器。服务器会根据action请求信息,去区块链上找到对应的智能合约代码,并将代码加载到内存中执行,最后将执行结果返回给客户端,下面的命令调用了hello.code智能合约的hi函数,并将“user”作为参数传入:
# cleos push action hello.code hi '["user"]' -p user
hello.code
>> Hello, user
Action处理流程
cleos会将一组action封装成一个transaction数据包发送给服务器。这里借用了数据库事务的概念,一个transaction代表一个事务,在事务内的action要么全部执行,要么都不执行,必须保证事务的原子性。Transaction可以包含一个action,也可以包含多个action,用json格式表示,例如:
服务器接收到大量的action请求,然后将action派发到对应的智能合约。每个智能合约都会实现一个apply()函数,用来处理各个action请求。apply()函数包含3个参数,receiver表示处理请求的账号,code表示合约名称,action表示action名称,例如:
action在运行之前,EOSIO会为action创建一个运行环境,也叫做Action “Apply” Context,提供程序运行所需的CPU和内存资源,具体的资源申请量取决与账户持有的股权比例,也就是EOS代币。
每个服务器都有一个action处理函数集合副本,当客户端发起action请求后,所有服务器会在本地运行action处理函数,并相互校验结果,最后将确认结果返回给客户端,具体流程如下:
智能合约的通信模型
智能合约中所谓的智能概念,就是智能合约不但可以和人交互通信,而且可以和其它智能合约进行交互通信。例如,当本次智能合约的transaction中可以调用其它智能合约的action来完成一些工作,或者在未来某个时刻触发其它智能合约的transaction。
EOSIO支持两种基本的通信模型,inline和deferred。其中,inline模型是指在当前的transaction中完成对其它智能合约action的调用,可以简单的认为是transaction的嵌套调用,内部的action失败会导致transaction整体做回退。Deferred模型是指延迟一段时间,或者满足一定条件后才执行,也就是说不能保证一定被执行到。
领取专属 10元无门槛券
私享最新 技术干货