深度分析智能合约DAPP系统开发及源码详解

供应商
微三云大数据科技有限公司
认证
电商模式设计
183****0056
经理
李志英
所在地
松山湖园区瑞和路1号2栋304室
更新时间
2023-07-11 07:00

详细介绍

1.动态调用

所谓动态调用,是指调用者合约不需要提前知道被调用合约的接口,只需要在调用时,告诉调用者被调合约的方法签名即可。调用者合约不需要事前绑定被调者的接口,可以在调用时,指定任意被调用合约及其方法,更加灵活。


动态调用示例


合约dynamic_call.sol。software development: i35 case 7o98development o7i8,部署caller合约后,可以调用任意solidity合约及其方法,不限定接口。


// spdx-license-identifier: gpl-3.0pragma solidity >=0.8.0;contract caller {    string[10] x;   string[8] params;    function cross_call(address callee,string calldata method, string calldata key, int256 value) public {//注意,method必须为方法签名格式,且方法签名的参数间不能有空格,例如"save(string,int256)"   callee.call((abi.encodewithsignature(method, key,value));    }}


如示例所示,调用者合约caller可以调用任意合约的任意方法,只需要将被调用合约的地址、方法签名和参数传给调用者合约即可。


注意,被调合约的方法必须是方法签名样式,且方法签名的参数间不能有空格,如示例中注释所示,否则无法编译为准确的abi类型的calldata,evm将无法识别。


2.异构调用

异构调用是指,solidity合约调用其他虚拟机类型的合约,比如wasm、docker-go,v+mrsfu123等,只要在chainmaker支持范围内,都可以异构调用。


solidity执行跨合约调用时,会将参数编码为abi格式的calldata。但,对其他虚拟机合约来说,它们的参数并不需要abi编码,也没有abi文件,所以无法解析从调用者solidity合约那里传递来的参数。针对这种情况,chainmaker单独实现了一套异构调用逻辑。


1 作为调用者的solidity合约需要在合约内声明一个string数组类型的状态变量,用做异构调用的参数缓冲区;


2 在异构调用之前,需要将带传递的参数按顺序写入参数缓冲区;


3 参数缓冲区的第一个元素(下标为0)必须是**”crossvmcall”**字符串,用于让chainmakerevm识别这是跨虚拟机的异构合约调用;


4 参数缓冲区的第二个元素必须是待调用的方法名(此方法名不需要方法签名格式);


5从第三个参数开始,每两个元素一组,标识一个待传递参数,前一个元素为参数的类型或key(视被调合约而定),后一个元素为参数的值。


关于进一步理解异构调用的内容,可以参考接下来的异构调用示例。


异构调用示例


合约cross_vm_call.sol。部署crosscall合约后,可以通过cross_call方法调用其他虚拟机类型的合约。。


// spdx-license-identifier: gpl-3.0pragma solidity >=0.8.0;contract crosscall {    string[10] x;   string[8] params;  //参数缓冲区 //address类型的参数callee为被调用合约地址   function cross_call(address callee, string calldata method,string calldata time, string calldata name, string calldata hash)public {         //crossvmcall is reservedkey word        params[0] ="crossvmcall";//crossvmcall为固定值,第一个参数必须是此值       params[1] = method;      //方法名,例如"save"        params[2] ="time";       //参数1的类型或key       params[3] = time;        //参数1的value        params[4] ="file_name";  //参数2的类型或key       params[5] = name;        //参数2的value        params[6] ="file_hash";  //参数3的类型或key       params[7] = hash;        //参数2的value     callee.call("");//跨虚拟机调用callee合约,callee.call的参数为空,evm虚拟机会从参数缓冲区读取对应的参数   }}


如示例所示,solidity跨虚拟机异构调用时,必须提供被调合约的地址,而不能是方法名,因为合约调用方法call是solidity语法中,地址类型的成员方法,使用合约名则无法识别。


3. 其他虚拟机跨合约调用

相比于solidity,chainmaker的其他虚拟机类型合约,都不支持合约创建合约,只支持合约调用合约。但同构异构都支持,且相比solidity也更加简单,只需要调用该类型合约所提供的跨合约调用接口即可。


调用示例


合约go_cross_call_evm.go 为go语言合约跨虚拟机调用soldity合约示例。


/*spdx-license-identifier: apache-2.0*/package main//exportinit_contractfunc initcontract() {}//export upgradefunc upgrade(){}//export crosscallevmcontractfunc crosscallevmcontract() { ctx :=newsimcontext() // 获取参数 name, _ := ctx.argstring("name") method, _:= ctx.argstring("method") calldata, _ := ctx.arg("calldata")params := make(map[string][]byte, 1) params["data"] = calldata//执行跨虚拟机低啊用 if result, resultcode := ctx.callcontract(name, method,params); resultcode != success { // 返回结果 ctx.errorresult("failed tocross call evm contract: " + name) } else { // 返回结果ctx.successresultbyte(result) // 记录日志 ctx.log("cross call evmcontract result:" + string(result)) }}func main() {}


如示例所示,go合约调用solidity合约时,只需要调用go合约内置的simcontext.callcontract接口即可。对于被调用者合约来说,传递合约名或合约地址均可,而不必像solidity合约那样限制必须使用地址。


DAPP,火币,上链,Dapp,比原链,智能合约开发搭建Dapp,软件开发,广东山东上海重庆

展开全文

我们其他产品
我们的新闻
优质商家推荐 拨打电话