多合约的进阶操作¶
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的数据。