搭建WeCross跨链平台,并编写跨链智能合约

WeCross是由微众银行自主研发并完全开源的区块链跨链协作平台,支持应用与多链互操作、同/异构链间互操作等多维跨链交互。——来自《WeCross技术文档

本教程基于wecross-demo,以实现多群组跨链为例:

跨链示例:以group1作为源链、group2作为目标链,group2上部署了智能合约,其中包括了全局变量data和修改全局变量data的函数setData(_data)。在跨链过程中,group1发起跨链请求传递函数参数data,指定目标函数就是group2上智能合约对应的setData,试图修改group2上的全局变量data,以此实现跨链合约调用。

0. 环境配置

Ubuntu Linux 18.04

MySQL

Java 11.0.18

1. 安装wecross-demo

下载脚本:

  • cd ~
  • bash <(curl -sL https://gitee.com/WeBank/WeCross/raw/master/scripts/download_demo.sh)

 执行脚本:

  • cd ~/wecross-demo
  • bash clear.sh
  • bash build_cross_groups.sh

执行期间需要输入MySQL数据库的ip、端口port、用户名username和密码password: 

 下载完成之后输入y,开启控制台console:

 输入login,进入管理员控制台:

 2. 编写跨链合约

跨链合约需要包含三个函数:

  1. 源链中发起跨链交易的函数
  2. 目标链中处理跨链交易的函数
  3. 源链中接收跨链交易执行结果的回调函数

合约源码路径:~/wecross-demo/WeCross-Console/conf/contracts/solidity/SetDataInterchain.sol

如下所示:

pragma solidity ^0.5.0;

pragma experimental ABIEncoderV2;
import "./WeCrossHub.sol";

contract SetDataInterchain {
    // 声明WeCrossHub
    WeCrossHub hub;
    function init(address _hub) public {
        hub = WeCrossHub(_hub);
    }

    // 全局变量data
    string data;
    constructor() public {}
    function setData(string memory _data) public {
        data = _data;
    }
    function getData() public returns (string memory) {
        return data;
    }

    // 1.源链中发起跨链交易的函数
    function setDataInterchainInvoke(
        string memory _path,
        string memory _method,
        string memory _data,
        string memory _callbackPath,
        string memory _callbackMethod
    ) public returns (string memory) {
        // 将待跨链传递的参数data存储在args中
        string[] memory args = new string[](1);
        args[0] = _data;

        return
            hub.interchainInvoke(
                _path,
                _method,
                args,
                _callbackPath,
                _callbackMethod
            ); // WeCrossHub将args进行跨链传递
    }

    // 2.目标链中处理跨链交易的函数
    function setDataFromInterchain(string[] memory args)
        public
        returns (string[] memory)
    {
        // 目标链收到args,然后执行setData
        setData(args[0]);
        return args;
    }

    // 3.源链中接收跨链交易执行结果的回调函数
    function setDataInterchainCallback(bool state, string[] memory _result)
        public
        returns (string[] memory)
    {
        // 源链根据回调的结果_result,可选的进行后续操作
        if (state) {}
        return _result;
    }
}

3. 部署跨链合约

3.1-3.4展示在group1上部署跨链合约的四个步骤,3.5在group2上展示四个步骤的全流程。

3.1 部署单链合约

执行命令: 

  • bcosDeploy payment.group1.SetDataInterchain conf/contracts/solidity/SetDataInterchain.sol SetDataInterchain 1.0

保存合约地址:0xdd46661c0f32003a644f079395010c632da626e2

 测试一下函数功能:

  • sendTransaction payment.group1.SetDataInterchain setData HelloWorld
  • call payment.group1.SetDataInterchain getData

3.2 将单链合约注册为跨链资源

  • bcosRegister payment.group1.SetDataInterchain conf/contracts/solidity/SetDataInterchain.sol 0xdd46661c0f32003a644f079395010c632da626e2 SetDataInterchain 2.0

 注意:0xdd46661c0f32003a644f079395010c632da626e2是单链上的合约地址,版本号2.0要与刚才单链部署的1.0版本号进行区分。

3.3 部署WeCrossHub

每条链上都部署WeCrossHub用于与其他链进行通信。

  • bcosDeploy payment.group1.WeCrossHub conf/contracts/solidity/WeCrossHub.sol WeCrossHub 2.0

保存WeCrossHub的地址:0x3a5b4196646c1b7ec6cba22258986f4097903196

 3.4 跨链资源绑定到WeCrossHub

执行SetDataInterchain合约中的init初始化函数,输入WeCrossHub的地址:

  • sendTransaction payment.group1.SetDataInterchain init "0x3a5b4196646c1b7ec6cba22258986f4097903196"

实现SetDataInterchain和WeCrossHub之间的绑定,因此合约SetDataInterchain才具备与外界进行跨链通信的能力。

 3.5 在group2上部署的全部流程

  • bcosDeploy payment.group2.SetDataInterchain conf/contracts/solidity/SetDataInterchain.sol SetDataInterchain 1.0
  • bcosRegister payment.group2.SetDataInterchain conf/contracts/solidity/SetDataInterchain.sol 0x87f3bb38533280a278d7a3e8558bc787d10addf5 SetDataInterchain 2.0

  • bcosDeploy payment.group1.WeCrossHub conf/contracts/solidity/WeCrossHub.sol WeCrossHub 2.0
  • sendTransaction payment.group2.SetDataInterchain init "0x150d4d7cacf6a36b860c5777819eb58279e633f3" 

4. 跨链合约调用

 4.1 源链发起跨链调用

  • sendTransaction payment.group1.SetDataInterchain setDataInterchainInvoke payment.group2.SetDataInterchain setDataFromInterchain NewHelloWorld payment.group1.SetDataInterchain setDataInterchainCallback

根据sendTransaction可以看出,这条命令本质上只是源链上的一笔合约调用交易。第二个参数payment.group1.SetDataInterchain是合约名称、第三个参数setDataInterchainInvoke是合约函数名,后面几个参数都是setDataInterchainInvoke的函数列表,分别对应目标链上的合约名称、合约上的函数名、函数参数、回调函数所在的链上合约、回调函数方法名,然后调用WeCrossHub进行跨链调用:

function setDataInterchainInvoke(
        string memory _path,
        string memory _method,
        string memory _data,
        string memory _callbackPath,
        string memory _callbackMethod
    ) public returns (string memory) {
        string[] memory args = new string[](1);
        args[0] = _data;

        return
            hub.interchainInvoke(
                _path,
                _method,
                args,
                _callbackPath,
                _callbackMethod
            );
    }

4.2 目标链查看跨链调用结果

目标链group2并没有主动调用setData函数,只有来自于源链group1的跨链请求调用了目标链group2上的setData函数,并传递了NewHelloWorld参数,可以查看跨链调用结果:

  • call payment.group2.SetDataInterchain getData

说明跨链合约调用成功了!

猜你喜欢

转载自blog.csdn.net/yilongyoung/article/details/129992489