HECO火币生态链智能合约dapp系统开发部署方案详细介绍

简介: HECO火币生态链智能合约dapp系统开发部署方案详细介绍

火币生态链 Huobi ECO Chain(HECO)是一个去中心化高效节能公链,也是火币开放平台推出的首个产品,在支撑高性能交易得基础上,实现智能合约的兼容。

Heco是火币开放平台的公链基础设施,heco链智能合约dapp系统开发唯+hkkf5566,未来将成为承载用户、资产和应用的基础平台。火币开放平台是基于火币集团的技术资源、流量资源和生态资源,向区块链行业陆续全面开放的基础设施统一平台。这就说明Heco的使命不仅仅是一条公链,它还将成为创新技术、创新业务的发源地。

概述
RISC-V service 为 Huobi Chain 提供了一个支持 RISC-V 指令集的虚拟机服务。 用户可以通过该服务自行部署和运行合约,实现强大的自定义功能。

一个 RISC-V 合约的本质是一个 Linux 的 ELF 可执行文件,使用虚拟机运行该合约等同于 Linux 环境下在单核 CPU 下运行这个可执行文件。

理论上任何提供了 RISC-V 后端的语言均可以用来开发合约。就生成代码的体积和质量(运行过程中 cycle 的消耗)而言,目前最成熟的工具是 riscv-gcc。

本文将以 C 语言开发的一个 ERC20 Token 和 Bank 合约为例,为你展示如何编写、部署、调用、测试一个 RISC-V 合约。

Echo 合约示例
我们首先来看一个简单的 echo 合约:

include <pvm.h>

int main() {

char args[100] = {0};
uint64_t args_len = 0;
pvm_load_args(args, &args_len);

pvm_ret(args, args_len);
return 0;

}
该合约的作用是将参数的内容原样返回。

将该 C 代码通过 riscv-gcc 编译生成的二进制文件即为我们的合约。

运行合约时,从 main 函数开始。当 main 函数返回值为 0 时,认为合约执行成功,否则合约执行失败。

注意,这个合约中我们引入了 pvm.h,使用了其中的 pvm_load_args 和 pvm_ret 函数。 pvm.h 这个文件中包含了我们与链交互所需要的所有函数。这些函数是通过系统调用实现的,我们将在下节进行详细讲解。

pvm
pvm 支持合约向 ckb-vm 外部发起调用的系统函数集合。在 ckb-vm 内部,你无法直接向链发起任何调用,包括获取 Block,Receipt 这样常用的方法。 所有的对链请求,都必须经过 ckb-vm 的 ecall 指令集完成。pvm 替开发者封装了所有对链请求的逻辑,导出为 C 函数,供合约调用

系统调用
由于 CKB-VM 只是一个 RISC-V 指令集解释器。要实现合约的复杂逻辑,必然要与链进行交互,如解析参数,返回结果,获取链/交易上下文,操作合约状态等。因此我们在 risc-v service 中用系统调用实现了这些交互功能。

下面是 pvm_load_args 函数的实现。调用该函数时,虚拟机会根据寄存器的状态,调用虚拟机外部对应功能的实现函数,并将实现结果通过寄存器和内存写回虚拟机。例如下面的 pvm_load_args 调用时,会将交易中的合约调用参数写到虚拟机内部的内存,然后将内存起始地址和参数长度写到对应的寄存器。

static inline long
__internal_syscall(long n, long _a0, long _a1, long _a2, long _a3, long _a4, long _a5)
{

register long a0 asm("a0") = _a0;
register long a1 asm("a1") = _a1;
register long a2 asm("a2") = _a2;
register long a3 asm("a3") = _a3;
register long a4 asm("a4") = _a4;
register long a5 asm("a5") = _a5;
register long syscall_id asm("a7") = n;
asm volatile ("scall": "+r"(a0) : "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(syscall_id));
return a0;

}

define syscall(n, a, b, c, d, e, f) \

__internal_syscall(n, (long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))

int pvm_load_args(uint8_t data, uint64_t len)
{

return syscall(SYSCODE_LOAD_ARGS, data, len, 0, 0, 0, 0);

}
RISC-V service 中提供的系统调用有 4 类:

debug 工具。pvm_debug 提供了虚拟机内部的 debug 工具,用户可以打印一段任意的 bytes,方便合约进行调试
入参出参。pvm_load_args 和 pvm_ret 分别提供了合约的入参和出参功能,用户通过前者获取合约调用参数,通过后者返回合约执行结果。合约的入参和出参均为任意的 bytes
获取交易上下文。例如通过 pvm_caller 获取调用该函数的地址,pvm_block_height 获取当前块高度。
链操作:
pvm_set_storage 和 pvm_get_storage 可以用来操作合约的状态空间。每个合约拥有独立的地址,在该地址下拥有独立的状态空间,可以把这个状态空间理解成一个 kv 数据库,用户可以在里面保存任意的数据。合约只能访问和修改自己状态空间内的数据。可以把这个状态空间类比理解成以太坊的 contract storage。
pvm_contract_call 可以用来调用其它 RISC-V 合约,pvm_service_call 可以用来调用 huobi-chain 的其它 build-in service。
所有的系统调用函数都在 pvm.h 文件中,里面有详细的函数文档,读者可以自行查阅。

ERC20 和 Bank 合约代码
理解了系统调用后,我们来看一个真实的 ERC20 合约和 Bank 合约的例子。

我们将源码放到了 GitHub 上,读者可以将示例代码下载到本地进行查看和交互。

$ git clone https://github.com/nervosnetwork/riscv-contract-tutorials.git
$ cd riscv-contract-tutorials/bank
ERC20 合约 是一个符合 ERC20 标准的 token 合约。本合约仅作为说明合约功能之用,读者如有发行自定义资产的需求,建议使用 huobi-chain 的原生资产模块,asset service。

Bank 合约实现了存钱、取钱、查余额等功能,展示了合约如何与其它合约相互操作(例如存钱时需要调用 ERC20 合约的 transfer_from 功能),该合约本身并没有什么现实意义,但可以很容易扩展成一个类似 EtherDelta 这样的 DEX 合约。

合约说明:

序列化:由于合约的入参出参均为任意的 bytes,对于功能复杂的合约,我们可能需要引入一些序列化方法。在上述的代码中,我们使用的是 JSON 格式,因为 JSON 使用广泛,无 schema 限制,且可读性较好。用户也可以根据自己的需求(速度、可读性、大小),选择适合的序列化方案,如 rlp,protobuf,thrift,msgpack 等。
函数分发:合约执行的统一入口为 main 函数,用户如想在一个合约中实现许多不同的功能,可以自行在 main 函数中进行函数分发。上述示例中,即是通过 method 字段的内容来路由到不同的函数进行处理。
除了系统合约外,我们还用到了很多其他的 C 语言库来帮助开发,具体内容可以参见 deps 文件夹。
编译
我们使用 riscv-gcc 来将 C 源码编译成二进制文件。由于 riscv-gcc 工具编译较为复杂,我们提供了打包好的 docker 镜像供读者使用。编译示例如下:

读者可以在 bank 文件夹中运行:

$ make bin_docker
命令来使用 docker 进行编译,在 bin 文件夹下得到的两个二进制文件即为我们的合约。
交互
RISC-V service 提供了两种 exec 和 call 两个交互接口。前者为写接口,可以操作链上数据,需要通过发交易,打包执行,后者为查询接口,可以通过链的 query 功能直接调用。

示例(继续使用刚才的 client):

查询接口

await client.queryService({ serviceName: 'riscv', method: 'call', payload: JSON.stringify({ address, args: JSON.stringify({method: 'total_supply'}) })})
{ isError: false, ret: '"1000000000"' }

发交易

payload = JSON.stringify({ address, args: JSON.stringify({method: 'transfer', recipient: '0000000000000000000000000000000000000000', amount: 100})})
tx = await client.composeTransaction({ method: 'exec', payload, serviceName: 'riscv' })
txHash = await client.sendTransaction(account.signTransaction(tx))
receipt = await client.getReceipt(txHash)
{ txHash:
'9f18a395972012817c68611e86e182af72f33964ec86c629c8727a9ec1a79daa',
height: '0000000000000386',
cyclesUsed: '0000000000072306',
events: [],
stateRoot:
'7f95c8a6d338fbd64de764cdf1870cc60696c4e69af1656de279d7cded6026ed',
response:
{ serviceName: 'riscv',
 method: 'exec',
 response:{
         code:'0x00',
         succeed_data:'',
         error_message:''
 }

}
}

相关文章
|
安全 区块链
DAPP公链合约系统开发技术原理丨DAPP公链合约系统开发详细源码及案例
智能合约dapp系统开发是基于链游技术开发的应用程序,它利用智能合约来实现去中心化的应用。智能合约是一种程序,它可以在链游上运行,根据指定的条件自动执行。智能合约dapp系统开发的核心在于智能合约的开发,智能合约的开发需要具备一定的链游技术知识和编程技能
|
11月前
|
算法 安全 区块链
趣玩联盟合约系统开发方案
区块链是一种去中心化的分布式账本技术,它将数据按照一定的规则以区块的形式链接在一起
|
存储 算法 区块链
DAPP智能合约系统软件开发案例 | 币安智能链模式系统开发
币安链和其它许多项目类似,比如EOS。它具有高吞吐量和高性能的底层匹配引擎,可以同时迅速的支持和处理大量交易。但是不够灵活性,无法支持许多复杂的DAPP。
|
存储 运维 安全
怎么开发DAPP区块链 | 去中心化应用模式系统搭建
 DAPP的优势在于区/块链特有的数据确权、价值传递功能,DAPP在用户认证流程变更、J易安全、行业生产关系变更、减少运维成本、降低技术开发成本等方面具有较大的优势,也能大幅提升用户体验。
|
算法 区块链 数据安全/隐私保护
区块链去中心化交易所系统开发成熟技术|开发指南与流程
Web3算法革命将会在多个领域产生深远的影响。首先,它将会对数据安全和隐私保护产生积极的作用
|
存储 安全 算法
dapp公链游戏链上合约系统开发技术详细/案例开发/方案逻辑/成熟技术
  随着区块链技术的不断发展和普及,越来越多的游戏开发商开始将区块链技术应用于游戏中。区块链游戏系统开发可以带来许多好处,例如提高游戏的安全性、透明度、公正性等,同时还可以让玩家拥有更好的游戏体
|
JavaScript 前端开发 Go
区块链Dapp智能合约系统开发(开发功能)丨dapp/defi代币合约项目系统开发成熟案例版及源码部署
The following are important technical points in the development process of smart contract DApp:
|
存储 开发框架 前端开发
BSC链Defiswap丨IPPswap丨NFTswap丨OMNIswap智能合约去中心化项目系统开发成熟技术/项目案例/源码说明
  区块链是一个分布式账本,使用密码学原理来记录数据,并且按照时间顺序进行记录。在区块链中,数据可以进行高度地分散,因为数据分布在不同的节点上。当一个区块链被添加到一个新的区块上时,它将包含以前的所有交易记录。
下一篇
无影云桌面