智能合约

EVM智能合约

引言

编写目的

设计Chainsql中智能合约的实现方案,通过此文档可对Chainsql中的智能合约有深入的了解。

背景

基于以下技术实现:

  • ChainSQL 的区块链技术实现

  • Ethereum客户端C++实现

  • 虚拟机EVM

总体说明

系统架构

SmartContractDesign

基本功能

合约部署

  • 支持通过chainsql节点部署智能合约,通过api进行操作的步骤如下:

    1. 用户编写solidity合约。

    2. 编译solidity代码,得到可执行字节码。

    3. 调用chainsql提交部署智能合约交易,并订阅交易状态。

    4. 交易共识通过触发回调,合约部署成功。

    5. 通过查询合约交易信息,获得合约地址。

合约调用

  • 合约部署成功后,api层可调用合约对象中的方法(与solidity中的定义一致)来调用合约,合约的调用方式分为两种:

    1. set方法,改变合约状态,这种方法需要以发送交易的方式进行调用。

    2. get方法,不改变合约状态,这种方法可直接调用chainsql提供的接口来获取返回结果。

给合约地址转账

  • 与其它账户地址不同,合约地址在Chainsql网络中是可以是没有ZXC余额的。

  • 不能通过Payment类型的交易给合约地址转账。

  • Api层提供了payToContract接口对合约地址进行转账。

  • 合约中必须提供payable修饰的fallback函数,不然合约地址无法接受转账。

Gas

  • Chainsql中的智能合约执行是需要消耗Gas的。

  • Chainsql中用户不可以设置GasPrice,只可以设置GasLimit,交易出现排队时,根据交易中Fee字段的值排列优先级。

  • Chainsql中的GasPrice由系统决定,并且会随当前网络负载而变化。

  • GasPrice初始值为10drop(1e-5 ZXC),最大值为20drop。

支持表操作

  • 支持在智能合约中进行表的各种操作。

支持网关配置数字资产、数字资产流通。

  • 支持智能合约中进行网关设置、信任网关、数字资产的转账等。

实现

LedgerNode修改:AccountRoot

  • 合约地址生成使用原有地址计算规则,以部署合约帐户与帐户当前交易序号为原像,合约只有地址,无公私钥。

  • 合约在Chainsql中也是以AccountRoot这种LedgerNode的形式存在。

  • AccountRoot增加了下面的可选字段:

字段名

类型

说明

StorageOverlay

STMap256(存储当前合约存储树的树根哈希)

合约中的存储

ContractCode

STBlob

合约中的字节码,调用合约时使用

StorageExtension

STMap256

合约扩展存储,内部使用

增加交易类型Contract

  • Chainsql中智能合约的部署、修改状态的方法调用,都要通过Contract类型的交易进行。

  • 交易中的字段说明(略过常规字段如AccountSequence等):

字段名

类型

是否必填

说明

ContractOpType

UINT16

必填

操作类型,1为合约部署,2为合约调用

ContractData

STBlob

必填

部署合约/调用合约时的输入值

Gas

UINT32

必填

部署/调用合约交易时,需设置的Gas上限

ContractAddress

STACCOUNT

选填

合约地址,调用合约时填写

ContractValue

STAMOUNT

选填

本次交易要给合约地址转账的金额

增加接口contract_call

  • Chainsql中不修改合约状态的方法调用,需要通过contract_call接口来实现。

  • 接口中的字段说明:

字段名

类型

说明

account

字符串

调用合约的地址

contract_address

字符串

合约地址

contract_data

字符串

合约数据

自定义数据类型STMap256

  • key与value均为uint256类型的map,用于存储合约中的状态。

WASM智能合约

ChainSQL中已初步支持 Wasm 智能合约,这里主要介绍一下ChainSQL中对 Wasm 智能合约的支持方式,当前的进度以及尚未解决的问题