子链业务逻辑的部署

同主链相同,业务逻辑的实现也通过智能合约的方式。

在1.0.8及之后的版本中,加入的子链多合约的功能。子链多合约功能指的是在一条子链上部署多个子链业务逻辑合约,又称DAPP的功能。

多合约部署准备工作

需要有一条已经在运行的子链,具体部署方法可参见“子链部署方法”。

假设有两个业务逻辑合约dapp1.sol和dapp2.sol。

从发布链接下载多合约基础合约dappbase.sol

DAPP智能合约的部署(多合约版)

DAPP智能合约也通过主链的sendTransaction发送交易到 proxy vnode 的方式进行部署。

参数:

to: 子链控制合约subchainbase的地址
gas: 不需要消耗gas费用,传值:0
shardingflag:表示操作子链, 传值:0x3,请注意,多合约版本部署任何合约shardingflag都为0x3
via: 对应 proxy vnode 的收益地址

STEP1:在子链上部署多合约基础合约 DappBase.sol

!!!特别注意!!!:目前子链原生币支持moac和erc20两种兑换方式,交易values分别对应subchainbase的tokensupply和erc20的totalsupply,这个值必须对应,否则将会导致dappbase部署失败。细节详见母子链货币交互章节

部署示例(以下在nodeJs console中进行):

> chain3 = require('chain3')
> solc = require('solc')
> chain3 = new chain3();
> chain3.setProvider(new chain3.providers.HttpProvider('http://localhost:8545'));
> solfile = 'DappBase.sol';
> contract = fs.readFileSync(solfile, 'utf8');
> output = solc.compile(contract, 1);
> abi = output.contracts[':DappBase'].interface;
> bin = output.contracts[':DappBase'].bytecode;
> subchainaddr = '0x1195cd9769692a69220312e95192e0dcb6a4ec09';
> via = '0xf103bc1c054babcecd13e7ac1cf34f029647b08c';
> chain3.personal.unlockAccount(chain3.mc.accounts[0], '123456');
> amount = tokensupply // 注意:amount分别对应subchainbase的tokensupply和erc20的totalsupply,细节详见母子链货币交互章节
> chain3.mc.sendTransaction({from: chain3.mc.accounts[0], value:chain3.toSha(amount,'mc'), to: subchainaddr, gas:0, shardingFlag: "0x3", data: '0x' + bin, nonce: 0, via: via, });
验证:

合约部署成功后,Nonce值应该是1 可调用monitor的rpc接口ScsRPCMethod.GetNonce进行检查,具体详见子链接口调用部分。

dapp合约地址:6ab296062d8a147297851719682fb5ffe081f1d3 dapp合约地址可调用monitor的rpc接口ScsRPCMethod.GetReceipt,传入对应Nonce,获得contractAddress字段内容

STEP2:在子链上部署业务逻辑合约 dapp1.sol,部署方法和上面雷同
合约地址可调用monitor的rpc接口ScsRPCMethod.GetReceipt,传入对应Nonce,获得contractAddress字段内容
STEP3:在子链上部署业务逻辑合约 dapp2.sol,部署方法和上面雷同
合约地址可调用monitor的rpc接口ScsRPCMethod.GetReceipt,传入对应Nonce,获得contractAddress字段内容

DAPP智能合约的调用

DAPP智能合约的调用也通过主链的sendTransaction发送交易到 proxy vnode 的方式进行。

在多合约版本中,调用dapp方法前,需要先调用dappbase中的registerDapp方法来注册每一个dapp,具体方式如下:

请注意,与母链调用不同,子链的任何调用需要在data前加上dapp的合约地址!!

dappbase.sol有个方法 registerDapp(address,address,string)

参数:

to: 子链控制合约subchainbase的地址
nonce:调用monitor的rpc接口ScsRPCMethod.GetNonce获得
gas: 0 不需要消耗gas费用
shardingflag: 0x1  表示子链调用操作
via: 对应 proxy vnode 的收益地址
data: 调用合约地址 + registerDapp(address,address,string)对应参数

registerDapp中,第一个参数是想要注册的dapp的地址(dapp1和dapp2的地址),可以通过RPC getReciipt方法获得部署时contract address;第二个参数是创建dappbase时的from,也就是只有创建dappbase的人才能调用此方法;第三个参数是这个dapp的ABI。

调用示例:

> nonce = 3
> addr_dapp = 需要注册dapp的合约地址
> abi = 需要注册dapp的abi
> data = dappbase.address + dappbase.registerDapp.getData(addr_dapp, chain3.mc.accounts[0], abi).substring(2)
> subchainaddr = '0x1195cd9769692a69220312e95192e0dcb6a4ec09';
> via = '0xf103bc1c054babcecd13e7ac1cf34f029647b08c';
> 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,});
验证:
每次操作成功后,Nonce会自动增加1 或者直接调用monitor的rpc接口ScsRPCMethod.GetDappAddrList获得合约注册列表的方式进行验证。

以部署dapp1和dapp2为例,需要将这两个业务逻辑合约注册到dappbase中去:

STEP4: 调用dappbase中的registerDapp方法来注册dapp1

STEP5: 调用dappbase中的registerDapp方法来注册dapp2

STEPX: 调用dapp1或dapp2中的业务逻辑