前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >佛萨奇DAPP开发丨佛萨奇2.0系统开发详情丨佛萨奇2.0智能合约系统开发原理及源码

佛萨奇DAPP开发丨佛萨奇2.0系统开发详情丨佛萨奇2.0智能合约系统开发原理及源码

原创
作者头像
VX_I357O98O7I8
发布2022-12-15 15:22:32
4290
发布2022-12-15 15:22:32
举报
文章被收录于专栏:商业模式策划

8.1. solidity合约内创建合约

ChainMaker evm虚拟机支持solidity合约静态创建solidity合约,solidity合约动态创建solidity合约,以及solidity合约动态创建其他类型合约。

8.1.1. 静态创建

所谓静态创建,是指在合约创建之前,创建者合约必须掌握被创建合约的代码。二者在编译之前就已经被绑定,并一同编译生成可部署的字节码,不能在运行时改变被创建者。

静态创建示例

合约static_create.sol,实现功能:

1、部署Creator合约后,可调用Creator合约的createSalted方法创建Creature合约;

2、创建时,可通过name参数,为Creature合约指定合约名。注:部署合约时,ChainMaker会根据合约名计算合约地址,并将地址返回给用户,合约部署完成后,用户即可使用合约名调用合约,也可使用合约地址调用合约。

代码语言:javascript
复制
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

//被创建合约
contract Creature {
    uint public x;
    constructor(uint a) payable {
        x = a;
    }

    function get() public view returns(uint){
        return x;
    }
}

//创建者合约
contract Creator {
    function bytesCopy(bytes memory src, bytes memory dst, uint begin) internal pure returns (bytes memory){
        uint len = src.length < 31 ? src.length : 31;
        for(uint i = 0; i < len; i++){
            dst[begin + i] = src[i];
        }
        return dst;
    }

    function createSalted(uint arg, string calldata name) public {
	    bytes memory bytesname = bytes(name);
        bytes memory custom = new bytes(32);

        uint8 rtTypeEvm = 5;                      //evm的虚拟机类型是5,所以该值必须是5
        custom[0] = bytes1(rtTypeEvm);            //虚拟机类型必须放入custom的首字节,custom将赋值给创建选项salt
        custom = bytesCopy(bytesname, custom, 1); //将合约名拷贝到后31字节内

        bytes32 n;
	      assembly{
	        n := mload(add(custom, 32))
	      }

				//花括号内的salt为创建选项,salt为solidity语法关键字,赋值类型为byte32数据的值
				//如果不指定为salt选项,写法为: Creature d = new Creature(arg)
        Creature d = new Creature{salt: n}(arg);
    }
}

如示例所示,创建者合约与被创建者合约位于同一文件内(也可以import导入),一同编译,执行创建动作时,无法更改被创建合约。

创建时,可通过salt选项指定被创建合约名,salt为byte32类型,但第一个字节必须赋值为evm虚拟机类型的枚举值5,后31字节才用于赋值合约名,所以合约名长度不得超过31字节。evm虚拟机会根据合约名计算地址,对于Chainmaker来说,所有类型的合约,都同时支持通过合约名和合约地址两种方式调用。

创建时,如果不指定salt选项,则evm虚拟机将为被创建者合约自动生成合约名和合约地址。

8.1.2. 动态创建

所谓动态创建,是指创建者合约不需要提前知道被创建合约的代码,只需要在创建时,告诉创建者被创建合约编译后的字节码即可,相比静态创建,动态创建更加灵活。

动态创建示例

合约dynamic_create.sol,实现功能:

1、部署Factory合约后,可调用Factory合约的create方法创建任意合约;

2、创建时,可指定合约虚拟机类型和合约名,并根据提供的合约字节码创建合约。

代码语言:javascript
复制
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.0;

contract Factory {

    function bytesCopy(bytes memory src, bytes memory dst, uint begin) internal pure returns (bytes memory){
        uint len = src.length < 31 ? src.length : 31;
        for(uint i = 0; i < len; i++){
            dst[begin + i] = src[i];
        }
        return dst;
    }

    function create(uint8 rtType, string calldata name, bytes calldata code) public returns (address addr){
        assert(0 < rtType && rtType < 8);//ChainMaker支持7种虚拟机

	      bytes memory bytesname = bytes(name);
	      bytes memory bytesCode = code;
        bytes memory custom = new bytes(32);
        custom[0] = bytes1(rtType);
        custom = bytesCopy(bytesname, custom, 1);

        assembly {
        		//create2指令参数1为转账额,参数2为合约字节码长度,参数3为字节码,参数4为虚拟机类型+合约名
            addr := create2(0, add(bytesCode,0x20), mload(bytesCode), mload(add(custom, 32)))
        }
    }
}

如示例所示,创建者合约不需要事先知道被创建合约,只需要在调用create方法时,以参数将被创建合约字节码传入即可。因为是动态创建,被创建合约不需要在编译前写入同一文件,所以,非solidity合约同样进入了被创建者的可选范围。

8.1.3. 异构创建

异构创建是指,solidity合约创建其他虚拟机类型的合约。异构创建方式和动态创建相同,只需要为调用者合约提供虚拟机类型、被调合约名和合约字节码即可,注意,这三个参数都是必不可少的。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 8.1. solidity合约内创建合约
    • 8.1.1. 静态创建
      • 8.1.2. 动态创建
        • 8.1.3. 异构创建
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档