陆羽协议4-异构跨链

异构跨链-使用fabric和fisco-bcos,实现合约互相访问

实现结构构图如下,调用路径类似步骤3,但经过的plugin不同:

异构跨链选择使用fabric和fisco-bcos

首先在101服务器把fabric网络和陆羽的各种插件都启动完毕

在102服务器搭建bcos

bcos的网络搭建参考教程

启动控制台

cd ~/fisco/console && bash start.sh

部署合约Transfer.sol

pragma solidity>=0.4.24 <0.6.11;

contract test {
    uint256 a;
    uint256 b;

    constructor() public {
        a = 1000;
        b = 1000;
    }
    
    function transfer(uint256 amount) public  {
        a = a+amount;
        b = b-amount;
    }
    
    function getABalance() public view returns (uint) {
        return a;
    }
    
    function getBBalance() public view returns (uint) {
        return b;
    }

}

使用绑定名字的方式部署合约

[group:1]> deployByCNS Transfer 1.0

部署成功

transaction hash: 0x9f0ed5cc5d2b9bfbbbb189e2cf762b1da708a3fcbe04128df88ffdb576c3bcb4
contract address: 0xc1d3605d7cde88cd4e896e545d64cfff86435aad
currentAccount: 0xe0b0f34bf184c680c264f5d3732b9edef0129528
{
    "code":1,
    "msg":"Success"
}

调用合约试一下:

call Transfer 0xc1d3605d7cde88cd4e896e545d64cfff86435aad transfer 1

查询a和b余额:

call Transfer 0xc1d3605d7cde88cd4e896e545d64cfff86435aad getABalance 
call Transfer 0xc1d3605d7cde88cd4e896e545d64cfff86435aad getBBalance 

查到a是1001,b是999
登录102配置陆羽和bcos
router先编译

gradle assemble

在101生成证书文件拷贝到102:

cd /root/java/router/dist
sh  build_router.sh -n payment2 -f ipfile -o config-102 -c routers/cert/
scp -r config-102 root@192.168.92.102:/root/java/router/dist/routers

配置bcos-plugin插件到router

cd /root/java/
git clone https://gitee.com/luyu-community/fisco-bcos-plugin.git
cd fisco-bcos-plugin
gradle assemble
cd dist/apps
ls
cp /root/java/fisco-bcos-plugin/dist/apps/* /root/java/router/dist/routers/127.0.0.1-8250-25500/plugin/
mkdir -p /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/chains/bcos102
cd /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/chains/bcos102
vi plugin.toml
[common]
    name = 'bcos102' # 链名
    type = 'BCOS2.0' # 链类型,用哪个插件进行加载
touch driver.toml
vi connection.toml
[chain]
    groupId = 1 # default 1
    chainId = 1 # default 1

[channelService]
    caCert = 'ca.crt'
    sslCert = 'sdk.crt'
    sslKey = 'sdk.key'
    gmConnectEnable = false
    gmCaCert = 'gm/gmca.crt'
    gmSslCert = 'gm/gmsdk.crt'
    gmSslKey = 'gm/gmsdk.key'
    gmEnSslCert = 'gm/gmensdk.crt'
    gmEnSslKey = 'gm/gmensdk.key'
    timeout = 300000  # ms, default 60000ms
    connectionsStr = ['127.0.0.1:20200']

[[resources]]
    name = "Transfer"
    methods = ["transfer(1)", "getABalance(0)", "getBBalance(0)"]

把bcos中node1的证书拷贝过来

cp /root/fisco/nodes/127.0.0.1/node0/conf/ca.crt /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/chains/bcos102/ca.crt
cp /root/fisco/nodes/127.0.0.1/node0/conf/node.crt /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/chains/bcos102/sdk.crt
cp /root/fisco/nodes/127.0.0.1/node0/conf/node.key /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/chains/bcos102/sdk.key

修改配置文件

vi /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/application.toml

启动router并查看日志

2021-12-23 10:35:00.740 [mainLoop] INFO  RouterHost() - Current active chains: [chain=payment2.bcos102,blockNumber=3]
2021-12-23 10:35:00.741 [mainLoop] INFO  RouterHost() - Current active resources: payment2.bcos102.Transfer

启动account-manage

下载编译,拷贝证书和配置文件

cp /root/java/router/dist/routers/cert/account-manager/* /root/java/account-manager/dist/conf/
cp /root/java/account-manager/dist/conf/application-sample.toml /root/java/account-manager/dist/conf/application.toml

启动

cd /root/java/account-manager/dist && sh start.sh

下载java-sdk,生成一个一级账户地址

cd /root/java/luyu-java-sdk/dist && sh gen_account.sh
[SUCCESS] Account secret key generated: 0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df.key

无需添加二级账户
调用

http://192.168.92.102:8250/resource/payment2/bcos102/Transfer/call
{
    "version":"1",
    "data":{
        "path": "payment2.bcos102.Transfer",
        "method": "getABalance",
        "args": [],
        "nonce":123456,
        "luyuSign":"",
        "sender": "0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df"
    }
}
http://192.168.92.102:8250/resource/payment2/bcos102/Transfer/sendTransaction
{
    "version":"1",
    "data":{
        "path": "payment2.bcos102.Transfer",
        "method": "transfer",
        "args": ["1"],
        "nonce":1,
        "luyuSign":"",
        "sender": "0x0959f7d077f9c338f93ebddbc36b44ed9806ef64"
    }
}

在101服务器配置连接bcos102

切换到101:

配置bcos-plugin插件到router

cd /root/java/
git clone https://gitee.com/luyu-community/fisco-bcos-plugin.git
cd fisco-bcos-plugin
gradle assemble
cp /root/java/fisco-bcos-plugin/dist/apps/* /root/java/router/dist/routers/127.0.0.1-8250-25500/plugin/
cd /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/chains 
mkdir bcos102 && cd bcos102
vi plugin.toml
[common]
    name = 'bcos102' # 链名
    type = 'BCOS2.0' # 链类型,用哪个插件进行加载
vi driver.toml
[verifier]
        # 填写所有共识节点的公钥(nodeid)
        pubKey = [
            '0282f2a1741f3c86f86bb7b0cd01e2b160284bbe917811bf1829382332ff403553e6511f3a4f4232b1078778a19f24865f7ff3ec5390a1e0db0e037de07262e2',
            '9076a34fc144d6e09f25e8ab74bec0d04f5f251824a3966827418472f69c639eae4c5627d57f6018ed3c0d2aecb4941df28c8ea7ae46c923fd407553d8eafbf1',
            '05973122fc787cacac138be8c28f0e73e2fd8876422df1752389519b765faf15add5b065e153d908a6caffd8c95c3491e1d1506bd1ed42c49c7de63b83d0c9f5',
            'b65d4db059613872e4d1f12a8774f83560541e8786b39810d48ef2eaf1c3cb6d5987b7d08f20a382c97bb17a31b0641ace60d47b91ad7bf5a19ee39bebae3392'
        ]

修改[p2p]标签下面的peers

vi /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/application.toml
peers = ['192.168.92.102:25500']

配置完成后,重启路由使其生效

cd /root/java/router/dist/routers/
sh stop_all.sh && sh start_all.sh

日志无误,调用:

http://192.168.92.101:8250/resource/payment2/bocs102/Transfer
{
    "version":"1",
    "data":{
        "path": "payment2.bcos102.Transfer",
        "method": "getABalance",
        "args": [],
        "nonce":123456,
        "luyuSign":"",
        "sender": "0x346be6fc044cfa03000bf2f5ea906a761c6ae843"
    }
}
http://192.168.92.101:8250/resource/payment2/bocs102/Transfer/sendTransaction
{
    "version":"1",
    "data":{
        "path": "payment2.bcos102.Transfer",
        "method": "transfer",
        "args": ["1"],
        "nonce":1,
        "luyuSign":"",
        "sender": "0x346be6fc044cfa03000bf2f5ea906a761c6ae843"
    }
}

在102服务器配置连接fabric101

cd /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/chains
mkdir fabric101 && cd fabric101
vi plugin.toml
[common]
    name = 'fabric101'
    type = 'Fabric1.4'

vi driver.toml
[verifier]
     [verifier.endorserCA] # 机构的CA列表
            Org1MSP = 'verifier/org1CA/ca.org1.example.com-cert.pem' # 相对路径:验证证书所在位置的
            Org2MSP = 'verifier/org2CA/ca.org2.example.com-cert.pem'
     [verifier.ordererCA] # 排序节点的CA证书
            OrdererMSP = 'verifier/ordererCA/ca.example.com-cert.pem'

mkdir verifier && cd verifier
mkdir ordererCA org1CA org2CA
scp root@192.168.92.101:/root/go/src/github.com/hyperledger/fabric-samples/first-network/crypto-config/ordererOrganizations/example.com/ca/ca.example.com-cert.pem /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/chains/fabric101/verifier/ordererCA/

scp root@192.168.92.101:/root/go/src/github.com/hyperledger/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/chains/fabric101/verifier/org1CA/

scp root@192.168.92.101:/root/go/src/github.com/hyperledger/fabric-samples/first-network/crypto-config/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/chains/fabric101/verifier/org2CA/

拷贝fabric插件

cp /root/java/WeCross-Fabric1-Stub/dist/apps/fabric1-stub-2.0.0-rc1.jar /root/java/router/dist/routers/127.0.0.1-8250-25500/plugin/

修改[p2p]标签下面的peers

vi /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/application.toml
peers = ['192.168.92.101:25500']

重启router

后台日志无误表示两个router102已经连上了router101

配置fabric二级账户

现在要在101的机器上配置fabric102账户,才能在101的router调用fabric102

cd /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/accounts/
mkdir fabric101_admin
vi fabric101_admin/account.toml
[account]
    type = 'Fabric1.4'
    mspid = 'Org1MSP' 
    keystore = 'account.key'
    signcert = 'account.crt'
scp root@192.168.92.101:$GOPATH/src/github.com/hyperledger/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/*_sk  /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/accounts/fabric101_admin/account.key

scp root@192.168.92.101:$GOPATH/src/github.com/hyperledger/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem /root/java/router/dist/routers/127.0.0.1-8250-25500/conf/accounts/fabric101_admin/account.crt
cd /root/java/router/dist/routers/127.0.0.1-8250-25500
java -cp conf/:lib/*:plugin/* link.luyu.protocol.link.fabric1.tools.AddAlgAccountRequestPacketBuilder 0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df payment1.fabric101 fabric101_admin

设置ssl证书为false后,调用addAlgAccount

{
  "data" : {
    "luyuSign" : "",
    "type" : "ECDSA_SECP256R1_WITH_SHA256",
    "nonce" : 1640241170667,
    "identity" : "0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df",
    "pubKey" : "BMILOBYCNLMOi7+DWdpW5j/42pGTI1io6aHA+taKS+VFNi/KX2fqRA4acl//H/lLhOxDy0fdmO3j7hEZ9TWMjtY=",
    "secKey" : "AIKqLtiv9WI072mEEg8SGgLtOYd/RvIKhXzk6EsaCfda",
    "properties" : {
      "Fabric1.4:payment1.fabric101:cert" : "-----BEGIN CERTIFICATE-----\nMIICKTCCAdCgAwIBAgIRAPbBuYoIq/Di8+3QH9dKl6gwCgYIKoZIzj0EAwIwczEL\nMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG\ncmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMjExMjIyMTAzNTAwWhcNMzExMjIwMTAzNTAw\nWjBrMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN\nU2FuIEZyYW5jaXNjbzEOMAwGA1UECxMFYWRtaW4xHzAdBgNVBAMMFkFkbWluQG9y\nZzEuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATCCzgWAjSz\nDou/g1naVuY/+NqRkyNYqOmhwPrWikvlRTYvyl9n6kQOGnJf/x/5S4TsQ8tH3Zjt\n4+4RGfU1jI7Wo00wSzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADArBgNV\nHSMEJDAigCC7eWSUg/J3uBykohtXjd8brGrCucaNu5LIVtejLB8ouzAKBggqhkjO\nPQQDAgNHADBEAiAq2Vfab6QTzrmETg11g8I1DJ1A+O7HxgDCIC8mt7RX4gIgCd5z\nrGVR5xhWFzzOvbdATU7yA3XxzJYRfvlYqxQ+X3M=\n-----END CERTIFICATE-----\n",
      "Fabric1.4:payment1.fabric101:name" : "fabric101_admin",
      "Fabric1.4:payment1.fabric101:mspid" : "Org1MSP"
    },
    "isDefault" : true
  }
}

调用fabric101

http://192.168.92.102:8250/resource/payment1/fabric101/mycc/call
{
    "version":"1",
    "data":{
        "path": "payment1.fabric101.mycc",
        "method": "query",
        "args": ["a"],
        "nonce":123456,
        "luyuSign":"",
        "sender": "0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df"
    }
}
http://192.168.92.102:8250/resource/payment1/fabric101/mycc/sendTransaction
{
    "version":"1",
    "data":{
        "path": "payment1.fabric101.mycc",
        "method": "invoke",
        "args": ["a","b","1"],
        "nonce":1,
        "luyuSign":"",
        "sender": "0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df"
    }
}

两个router访问彼此的异构区块链网络,一切正常

下面编写跨链合约,尝试bcos合约访问fabric的mycc合约

LuyuSDK.sol是官方的接口合约(该合约在bcos2.0的控制台内会报错,推测是solidity编译器版本的原因,可以适当修改)

修改后的LuyuSDK.sol:

pragma solidity >=0.4.22 <0.6.0;
pragma experimental ABIEncoderV2;

interface ILuyuSDK {
    function luyuSendTransaction(string path,string method,string[] args,string luyuIdentity,string callbackMethod) returns (uint256);
    function luyuCall(string path,string method,string[] args,string luyuIdentity,string callbackMethod) returns (uint256);
    event LuyuSendTransaction(
        string path,
        string method,
        string[] args,
        uint256 nonce,
        string luyuIdentity,
        string callbackMethod,
        address sender
    );
    event LuyuCall(
        string path,
        string method,
        string[] args,
        uint256 nonce,
        string luyuIdentity,
        string callbackMethod,
        address sender
    );
}

contract LuyuContract is ILuyuSDK {
    uint256 nonceSeed = 0;

    function luyuSendTransaction(
        string memory path,
        string memory method,
        string[] memory args,
        string memory luyuIdentity,
        string memory callbackMethod
    ) public returns (uint256) {
        uint256 nonce = getNonce();
        emit LuyuSendTransaction(
            path,
            method,
            args,
            nonce,
            luyuIdentity,
            callbackMethod,
            tx.origin
        );
        return nonce;
    }


    function luyuCall(
        string memory path,
        string memory method,
        string[] memory args,
        string memory luyuIdentity,
        string memory callbackMethod
    ) public returns (uint256) {
        uint256 nonce = getNonce();
        emit LuyuCall(
            path,
            method,
            args,
            nonce,
            luyuIdentity,
            callbackMethod,
            tx.origin
        );
        return nonce;
    }
    
    function getNonce() private returns (uint256) {
        return ((nonceSeed++) % 100000) + getNow() * 100000;
    }
    
    function getNow() private view returns (uint256) {
        // 'now' in ehtereum return in seconds but millisecond in fisco bcos
        // Need to format to seconds
        return getSecondTime(now);
    }
    
    function getSecondTime(uint256 time) private pure returns (uint256) {
        if (time / 10000000000 != 0) {
            return getSecondTime(time / 10);
        } else {
            return time;
        }
    }

}

编写chcontract1.sol:

pragma solidity >=0.4.22 <0.6.0;
pragma experimental ABIEncoderV2;
import "./LuyuSDK.sol";

contract chcontract3 is LuyuContract{
    uint64 public callTime = 0;
    uint64 public sendTxTime = 0;
    string public fabric101AValue;

    function getArgs() public view returns (uint64 ,uint64, string memory){
        return (callTime, sendTxTime, fabric101AValue);
    }
    
    function sendTxTofabric101() public returns (uint256) {
        string memory path = "payment1.fabric101.mycc";
        string memory method = "invoke";
        string[] memory args = new string[](3);
        args[0] = "a";
        args[1] = "b";
        args[2] = "1";
        string memory luyuIdentity = "0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df";
        string memory callbackMethod = "sendTxCallback";
        uint256 nonce = luyuSendTransaction(
            path,
            method,
            args,
            luyuIdentity,
            callbackMethod
        );
        return nonce;
    }
    
    function callTofabric101() public returns (uint256) {
        string memory path = "payment1.fabric101.mycc";
        string memory method = "query";
        string[] memory args = new string[](1);
        args[0] = "a";
        string memory luyuIdentity = "0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df";
        string memory callbackMethod = "callfunCallback";
    
        uint256 nonce = luyuCall(
            path,
            method,
            args,
            luyuIdentity,
            callbackMethod
        );
        return nonce;
    }
    
    function sendTxCallback(
        uint256 nonce,
        string memory result0
    ) public {
        sendTxTime++;
    }
    
    function callfunCallback(
        uint256 nonce,
        string memory result1
    ) public {
        callTime++;
        fabric101AValue = result1;
    }

}

需要注意的几点:
1,如果想要监听chcontract的跨链请求,则必须将其纳入资源管理中。在connection.toml配置文件中加入要管理的resource,否则虽然可以调用合约,但是无法监听该合约的event,而event是跨链请求的必要环节。
2,编写chcontract合约中的回调函数,其参数必须和对方链返回的参数个数一致,否则会报错“Arguments mismatch”。需要注意的是fabric的chaincode的return shim.Success(nil)代表着一个空字符串。

部署

cd /root/fisco/console/contracts/solidity
vi chcontract3.sol
vi LuyuSDK.sol

控制台部署:

deployByCNS chcontract3 1.0
transaction hash: 0xbdebb2fed44cea6df92a917ae0e624db184512b2df05036d5808e101bc524ccb
contract address: 0x64504642481b371ae458824a002d13dfd4bc1492
currentAccount: 0x5baca606888c62f195d2046ea4ad1ebc3c95d538
{
    "code":1,
    "msg":"Success"
}

试试在控制台调用

call chcontract3 0x64504642481b371ae458824a002d13dfd4bc1492 getArgs

查看

http://192.168.92.101:8250/resource/payment2/bcos102/chcontract3/call
{
    "version":"1",
    "data":{
        "path": "payment2.bcos102.chcontract3",
        "method": "getArgs",
        "args": [],
        "nonce":123456,
        "luyuSign":"",
        "sender": "0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df"
    }
}

跨链交易

http://192.168.92.102:8250/resource/payment2/bcos102/chcontract3/sendTransaction
{
    "version":"1",
    "data":{
        "path": "payment2.bcos102.chcontract3",
        "method": "sendTxTofabric101",
        "args": [],
        "nonce":1,
        "luyuSign":"",
        "sender": "0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df"
    }
}

跨链查询

http://192.168.92.102:8250/resource/payment2/bcos102/chcontract3/sendTransaction
{
    "version":"1",
    "data":{
        "path": "payment2.bcos102.chcontract3",
        "method": "callTofabric101",
        "args": [],
        "nonce":123456,
        "luyuSign":"",
        "sender": "0x3ef2cba92cdc5dd5d9688cfe870b764b4a39d2df"
    }
}

编写fabric合约,访问bcos102网络的Transfer.sol合约

chccToBcos.go
package main

import (
    "fmt"
    "github.com/hyperledger/fabric/core/chaincode/shim"
    pb "github.com/hyperledger/fabric/protos/peer"
    "strconv"
)

type ChccToBcos struct {
}

func main() {
    err := shim.Start(new(ChccToBcos))
    if err != nil {
        fmt.Printf("Error starting Simple chaincode: %s", err)
    }
}

const (
    ccbt  = "callCallBackTimes"            //用来计数,回调了call方法多少次
    stcbt = "sendTransactionCallBackTimes" //用来计数,回调了sendTransaction方法多少次
    aval  = "fabric102AValue"
)

func (c *ChccToBcos) Init(stub shim.ChaincodeStubInterface) pb.Response {
    z := strconv.Itoa(0)
    stub.PutState(ccbt, []byte(z))
    stub.PutState(stcbt, []byte(z))
    return shim.Success(nil)
}

func (c *ChccToBcos) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    function, args := stub.GetFunctionAndParameters()
    if function == "callBcos102" {
        return c.callBcos102(stub, args)
        //调用sengTransaction方法
    } else if function == "sendTxToBcos102" {
        return c.sendTxToBcos102(stub, args)
        //查询调用次数
    } else if function == "getLuYuInvokeTimes" {
        return c.getLuYuInvokeTimes(stub, args)
    } else if function == "getCallback" {
        var nonce uint64
        nonce, callbackArgs, err := ParseCallbackArgs(args)
        if err != nil {
            return shim.Error(err.Error())
        }
        return c.getCallback(stub, nonce, callbackArgs)
    } else if function == "setCallback" {
        var nonce uint64
        var callbackArgs []string
        nonce, callbackArgs, err := ParseCallbackArgs(args)
        if err != nil {

        }
        return c.setCallback(stub, nonce, callbackArgs)
    }
    return shim.Error("Invalid invoke function name.")

}

func (c *ChccToBcos) callBcos102(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    nonce, err := CrossCall(stub, "payment2.bcos102.Transfer", "getABalance",
        []string{}, "0x45eeaa0b36ac900b42b9c5dab55d9dd35ef82b80", "getCallback")
    if err != nil {
        return shim.Error("call error:" + err.Error())
    }
    return shim.Success([]byte(fmt.Sprintf("nonce: %d", nonce)))
}

func (c *ChccToBcos) sendTxToBcos102(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    //
    nonce, err := CrossSendTransaction(stub, "payment2.bcos102.Transfer", "transfer",
        []string{"1"}, "0x45eeaa0b36ac900b42b9c5dab55d9dd35ef82b80", "setCallback")
    if err != nil {
        return shim.Error("call error:" + err.Error())
    }
    return shim.Success([]byte(fmt.Sprintf("nonce: %d", nonce)))
}

func (c *ChccToBcos) getCallback(stub shim.ChaincodeStubInterface, nonce uint64, value []string) pb.Response {
    res, err := stub.GetState(ccbt)
    if err != nil {
        return shim.Error(err.Error())
    }
    i, _ := strconv.Atoi(string(res))
    i++
    if err := stub.PutState(ccbt, []byte(strconv.Itoa(i))); err != nil {
        return shim.Error(err.Error())
    }
    a := value[0]
    stub.PutState(aval, []byte(a))
    return shim.Success(nil)
}

func (c *ChccToBcos) setCallback(stub shim.ChaincodeStubInterface, nonce uint64, args []string) pb.Response {
    res, err := stub.GetState(stcbt)
    if err != nil {
        return shim.Error(err.Error())
    }
    i, _ := strconv.Atoi(string(res))
    i++
    stub.PutState(stcbt, []byte(strconv.Itoa(i)))
    return shim.Success(nil)
}

func (c *ChccToBcos) getLuYuInvokeTimes(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    res1, err := stub.GetState(ccbt)
    if err != nil {
        return shim.Error(err.Error())
    }
    res2, err := stub.GetState(stcbt)
    if err != nil {
        return shim.Error(err.Error())
    }
    r1, _ := strconv.Atoi(string(res1))
    r2, _ := strconv.Atoi(string(res2))
    a, _ := stub.GetState(aval)
    res := []byte(fmt.Sprintf("callCallBackTimes = %v,sendTransactionCallBackTimes = %v, 102A-Value = %v \n",
        r1, r2, string(a)))
    return shim.Success(res)
}

部署:

docker cp /root/go/src/chaincode/ cli:/opt/gopath/src/github.com/chaincode/chcc/
docker exec -it cli bash
peer chaincode install -n chcc6 -v 1.0.0 -p github.com/chaincode/chcc/chaincode
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:9051
CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
peer chaincode install -n chcc6 -v 1.0.0 -p github.com/chaincode/chcc/chaincode
peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n chcc6 -l golang -v 1.0.0 -c '{"Args":["init"]}'
peer chaincode query -o orderer.example.com:7050  -C mychannel -n chcc6 -c '{"Args":["getLuYuInvokeTimes"]}'

调用:

http://192.168.92.101:8250/resource/payment1/fabric101/chcc6/sendTransaction
{
    "version":"1",
    "data":{
        "path": "payment1.fabric101.chcc6",
        "method": "callBcos102",
        "args": [],
        "nonce":123456,
        "luyuSign":"",
        "sender": "0x45eeaa0b36ac900b42b9c5dab55d9dd35ef82b80"
    }
}
http://192.168.92.101:8250/resource/payment1/fabric101/chcc6/sendTransaction
{
    "version":"1",
    "data":{
        "path": "payment1.fabric101.chcc6",
        "method": "sendTxToBcos102",
        "args": [],
        "nonce":1,
        "luyuSign":"",
        "sender": "0x45eeaa0b36ac900b42b9c5dab55d9dd35ef82b80"
    }
}

检查调用是否成功

http://192.168.92.101:8250/resource/payment1/fabric101/chcc6/call
{
    "version":"1",
    "data":{
        "path": "payment1.fabric101.chcc6",
        "method": "getLuYuInvokeTimes",
        "args": [],
        "nonce":123456,
        "luyuSign":"",
        "sender": "0x45eeaa0b36ac900b42b9c5dab55d9dd35ef82b80"
    }
}

至此fabric和bcos的双向跨链完成


转载请注明来源

×

喜欢就点赞,疼爱就打赏