多合约的进阶操作

1.0.8以后,子链引入了多合约的概念。子链多合约指的是在一条子链中部署多个智能合约,多合约可以将业务逻辑进行拆分,相互调用,合约之间也可以进行升级。

子链业务逻辑合约间的调用

本实例完成一个合约调用另外一个合约中的方法。

STEP0:部署dappbase.sol

STEP1:部署合约dapp1.sol,并注册到dappbase中去

contract Dapp1 {
struct tup {
    uint amount;
    string desc;
}
tup[] public tups;
function addTup(uint amount, string desc) public {
    tups.push(tup(desc));
}
function getString() public view returns (string) {
    return tups[0].desc;
}
function getTup(address addr) public view returns (tup) {
    for (uint i=0; i<tups.length; i++) {
        if (tups[i].owner == addr) {
            return tups[i];
        }
    }
}

STEP2:部署合约dapp2.sol,要求可以调用dapp1的getString方法

contract Dapp1 {
    struct tup {
        uint amount;
        string desc;
    }
    function getUint() public view returns (uint);
    function getString() public view returns (string);
    function getTup(address addr) public view returns (tup);
}
contract Dapp2 {
    struct tup {
        uint amount;
        string desc;
    }
    function Dapp2(address dapp1addr) public {
        Dapp1 dp1 = Dapp1(addr1);
    }
    function getString(address addr1) public view returns (string) {
        return dp1.getString();
    }
}

调用示例:

> nonce = 1   // 调用ScsRPCMethod.GetNonce获得
> subchainaddr = '0xb877bf4e4cc94fd9168313e00047b77217760930';
> dappaddr = '0xcc0D18E77748AeBe3cC6462be0EF724e391a4aD9';
> via = '0xf103bc1c054babcecd13e7ac1cf34f029647b08c';
> data = dappaddr + '89ea642f';
> chain3.personal.unlockAccount(chain3.mc.accounts[0], '123456');
> chain3.mc.sendTransaction( { nonce: nonce, from: chain3.mc.accounts[0], value:0, to: subchainaddr, gas:0, shardingFlag:'0x1', data: data, via: via,});

子链合约的升级(版本迭代)

本实例完成一个合约获取另外一个合约中的数据,进而替代另外一个合约中的功能。

STEP0:部署dappbase.sol

STEP1:部署合约dapp1.sol,并注册到dappbase中去

 contract Dapp1 {
    struct tup {
        uint amount;
        address addr;
    }
    tup[] public tups;
    tup[] private mytups;

    function addTup(uint amount, address addr) public {
        tups.push(tup(amount, addr));
    }

    function getAmountByAddr(address myaddr) public view returns (tup[]) {
        for (uint i=0;i<tups.length;i++){
            if (tups[i].addr == myaddr){
                mytups.push(tups[i]);
            }
        }
        return mytups;
    }
}

STEP2:部署合约dapp3.sol,要求可以访问dapp1中的数据

contract Dapp1 {
    struct tup {
        uint amount;
        address addr;
    }
    function getAmountByAddr(address) public view returns (tup[]);
}

contract Dapp3 {
    struct tup {
        uint amount;
        address addr;
    }

    Dapp1 public dp1;
    tup[] public tups;
    tup[] private mytups;
    function Dapp3(address dapp1addr) public{
        dp1 = Dapp1(dapp1addr);
    }

    function addTup(uint amount, address addr) public {
        tups.push(tup(amount, addr));
    }

    function getAmountByAddr(address addr) public view returns (tup[]) {
        Dapp1.tup[] memory oldtups = new Dapp1.tup[](10);
        oldtups = dp1.getAmountByAddr(addr);
        for (uint i=0;i<oldtups.length;i++){
            if (oldtups[i].addr == addr){
                mytups.push(tup(oldtups[i].amount, oldtups[i].addr));
            }
        }

        for (i=0;i<tups.length;i++){
            if (tups[i].addr == addr){
                mytups.push(tups[i]);
            }
        }
        return mytups;
    }
}

说明:getAmountByAddr方法将dapp1中的老数据放入dapp3中的mytups。

STEP3:部署合约dapp4.sol,要求可以访问dapp3中的数据

contract Dapp3 {
        struct tup {
            uint amount;
            address addr;
        }
        function getUint() public view returns (uint);
        function getString() public view returns (string);
        function getAmountByAddr(address) public view returns (tup[]);
}

contract Dapp4 {
    struct tup {
            uint amount;
            address addr;
    }

    tup[] public tups;
    Dapp3 dp3;
    tup[] private mytups;
    function Dapp4(address dapp3addr)  public {
        dp3 = Dapp3(dapp3addr);
    }

    function addTup(uint amount, address addr) public {
        tups.push(tup(amount, addr));
    }

    function getAmountByAddr(address addr) public view returns (tup[]) {
        //get dapp3 data
        Dapp3.tup[] memory oldtups = new Dapp3.tup[](10);
        oldtups = dp3.getAmountByAddr(addr);
        for (uint i=0;i<oldtups.length;i++){
            if (oldtups[i].addr == addr){
                mytups.push(tup(oldtups[i].amount, oldtups[i].addr));
            }
        }
        //new data
        for (i=0;i<tups.length;i++){
            if (tups[i].addr == addr){
                mytups.push(tups[i]);
            }
        }
        return mytups;
    }
}

说明:getAmountByAddr方法将dapp3中的老数据放入dapp3中的mytups,因为dapp3的方法中包含dapp1的数据,所以这个方法最终返回dapp1,dapp3,dapp4中所有符合addr的数据。