fabric chain across it?

Foreword

The company today makes me sort of a cross-chain scheme fabric-based, not before how contact across the chain, where record their own ideas of it.

First, let's understand a few concepts. What is cross chain? My understanding is that across the chain is cross-channel. The following detailed about my reasons:

  1. Recalling the fabric startup process: creating a certificate, generates creation block, block trading channel configuration, to create a channel, the channel node is added, the installation chain codes of chain code example, call chain code. This is the complete life cycle.
  2. You may be mounted on a plurality of chaincode node, and each is a chaincode books.
  3. The same channel, all nodes are installed the same chaincode, so each node has a complete data across the chain is said does not exist.
  4. In summary, inter-channel cross-link means, because different books have different channel, the nature of the cross-strand is a chain transfer data from one strand to another .

We can only cross in the upper chain to do, it can be done in chaincode layer. After I found a InvokeChaincode Find method, looking good, it appears to be used to call other chaincode of ( do not like me to learn, too literally, if carefully read the API documentation, there is no back story ).

So I designed the following programs across the chain:

a simple case description: OrgA in peer1 and peer2 and ORGC in peer5 added channelA, and installation ChaincodeA, OrgB in peer3 and peer4 and ORGC in peer5 added channelB, and installation ChaincodeB.
peer5 this node is the key across the chain, because the node also has two channels of data.

Things here, and not finished, the above operation is not an atomic operation, so we have to consider transactional, if an intermediate step wrong, we want to roll back the whole process, and this is done in a distributed environment, hey, people really big head.

1 to generate a certificate

Before we begin, we need to build the appropriate corresponding development environment, I do in the source code is on the basis of fabric. Based fabric v1.3.0
environmental planning me is: Org1 two peer nodes, Org2 two peer nodes, Org3 have a node, which Org1 and Org3 join channel1, installation chaincode1, Org2 and Org3 join channel2, installation chaincode2.

Further, a node to be installed chaincode3 Org3 separately, for cross-chain.

The following details the changes to the file I refer to:
https://github.com/Anapodoton/CrossChain

We need to generate a certificate of the configuration file is modified as follows:
Crypto-config.yaml
Docker-Compose-E2E-template.yaml
Docker-Compose-base.yam
generateArtifacts.sh

We need to add information about a third organization, modify the port number.

After the change is completed, we can use cryptogen tool to generate the appropriate certificate file, we use the tree command for viewing.

# 2 generates block creation, application transaction channel configuration file and update the transaction anchor node configuration file
we need to modify files and generateArtifacts.sh configtx.yaml file.

The main tool we use is configtxgen tool. The purpose is to generate system-channel creation block, two channels channel1 and channel2 application configuration file transaction, each organization must be generated for each channel of the anchor node configuration update transaction file. File is generated as follows:

Starting respective container 3

We can first use docker-comppose-e2e network under test Unicom is normal.

docker-compose -f docker-compose-e2e.yaml To see if the network is normal, not normal to promptly adjust.

接下来,我们修改docker-compose-cli.yaml,我们使用fabric提供的fabric-tools镜像来创建cli容器来代替SDK。

4 创建网络

这里主要使用的是script.sh来创建网络,启动orderer节点和peer节点。

我们创建channel1,channel2,把各个节点分别加入channel,更新4个锚节点,安装链码,实例化链码。

上面的操作全部没有错误后,我们就搭建好了跨链的环境了,这里在逼逼一句,我们创建了两个通道,每个通道两个组织,其中Org3是其交集。下面可以正式的进行跨链了。

其实在前面的操作中,并不是一帆风顺的,大家可以看到,需要修改的文件其实还是蛮多的,有一个地方出错,网络就启动不了,建议大家分步进行运行,一步一步的解决问题,比如说,我在configtx.yaml文件中,ORG3的MSPTYPE指定成了idemix类型的,导致后面无论如何也验证不过,通道无法创建成功。

简单说下idemix,这个玩意是fabric v1.3 引入的一个新的特性,是用来用户做隐私保护的,基于零知识证明的知识,这里不在详述,感兴趣的可以参考:
fabric关于idemix的描述

5. 发现错误

在实例化chaincode3的时候,我晕了,chaincode3实例化在两个通道的话,本质上是会产生两个账本啊,即L31和L32,怎么在L31和L32之间转移数据呢?
绕了这么一大圈,竟然回去了。3天的功夫都白费掉了,哎,真的是蠢。。。

6 阅读API

找到fabric提供了这么一个函数的文档,我们先来看看。

invokechaincode

// InvokeChaincode documentation can be found in 
interfaces.gofunc (stub *ChaincodeStub) InvokeChaincode(chaincodeName string, args [][]byte, channel string) pb.Response {     
// Internally we handle chaincode name as a composite name     
    if channel != "" {          
    chaincodeName = chaincodeName + "/" + channel     
    }    
    return stub.handler.handleInvokeChaincode(chaincodeName, args, stub.ChannelId, stub.TxID)}

下面是官方的文档说明:

// InvokeChaincode locally calls the specified chaincode `Invoke` using the
// same transaction context; that is, chaincode calling chaincode doesn't
// create a new transaction message.
// If the called chaincode is on the same channel, it simply adds the called
// chaincode read set and write set to the calling transaction.
// If the called chaincode is on a different channel,
// only the Response is returned to the calling chaincode; any PutState calls
// from the called chaincode will not have any effect on the ledger; that is,
// the called chaincode on a different channel will not have its read set
// and write set applied to the transaction. Only the calling chaincode's
// read set and write set will be applied to the transaction. Effectively
// the called chaincode on a different channel is a `Query`, which does not
// participate in state validation checks in subsequent commit phase.
// If `channel` is empty, the caller's channel is assumed.
InvokeChaincode(chaincodeName string, args [][]byte, channel string) pb.Response

上面的意思是说:
InvokeChaincode并不会创建一条新的交易,使用的是之前的transactionID。
如果调用的是相同通道的chaincode,返回的是调用者的chaincode的响应。仅仅会把被调用的chaincode的读写集添加到调用的transaction中。
如果被调用的chaincode在不同的通道中,任何PutState的调用都不会影响被调用chaincode的账本。

哎,这里已经说的很明白了,跨channel是不能读写的,相同通道才可以的。哎,想想也是啊,channel本来就是用来隔离数据使用的,如果可以通过这个方法访问其他通道的数据,那么fabric的数据隔离机制就崩掉了。

7. 验证

下面我简单搭建一个测试网络来进行验证,还是两个channel,channel2中的chaincode通过invokeChaincode方法尝试调用chaincode1中的方法,我们来看看效果。

其中chaincode1是fabric/examples/chaincode/go/example02,chaincode2基于chaincode1进行修改,增加了一个queryByInvoke方法。

直接贴出queryByInvoke核心代码,代码中有注释

A = args[0]//query的参数
chaincode1:=args[1]//要调用的链码
invokeArgs := toChaincodeArgs("query", A)//把参数和要调用的函数转化成符合InvokeChaincode的要求
response := stub.InvokeChaincode(chaincode1, invokeArgs, "channel1")//调用channel1中的chaincode1的query方法
if response.Status != shim.OK { //是不是调用成功    
    errStr := fmt.Sprintf("Cross chain error.Failed to invoke chaincode.")     
    fmt.Printf(errStr)   
return shim.Error(errStr)}

我们分别执行如下两次查询:
第一次:
  peer chaincode query -C "channel1" -n mycc1 -c '{"Args":["query","a"]}'

结果如下:可以查到正确的结果。

我们再次查询,在channel2上通过chaincode2中的queryByInvoke方法调用channel1的chaincode1中的query方法:

 peer chaincode query -C "channel2" -n mycc2 -c '{"Args":["queryByInvoke","a","mycc1"]}'

结果如下所示:

invokeChaincode方法只能用在相同的channel中,在不同的channel中,不能读也不能写。

8. 总结

在这次方案的研究中,还是踩了很多的坑的,现总结如下:

  1. 对待一个陌生的东西,一定要先看官方文档,然后写个简单的demo进行验证。不要急着先干活。根据验证的结果在决定下面怎么办?
  2. 要学会思考,就比如说这次,其实很简单的道理,channel是为了保护数据的,不需要被调用 方做任何验证的情况下,怎么可能获取到数据呢?

跨链在实际的业务中还是需要的,虽然无法通过chaincode来实现,但是还是要想其他办法的。

Guess you like

Origin www.cnblogs.com/anapodoton/p/11084535.html