Hyperledger Fabric tests chaincode calls from different organizations

Hyperledger Fabric tests chaincode calls from different organizations

After being familiar with the various operations of fabric, I started to apply smart contracts for multiple organizations and found that the chain codes of different organizations should be different. At this time, mutual calling involves the issue of how to deploy a chain code.


This test environment, fabric1.1 version, two organizations A and B, where A installs the official chaincode go/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
B installs the chaincode I wrote, The transaction and query functions of the official chain code are called in the chain code. The chain code is as follows:

//为了操作更简便,我把调用的参数写的跟A组织传入一样,后面操作只要修改链码名称就可以了,invoke和query均相同。
package main

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

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
  fmt.Println("ChaincodeInvoke Init")
  return shim.Success(nil)
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
  fmt.Println("ChaincodeInvoke Invoke")
  function, args := stub.GetFunctionAndParameters()
  if function == "invoke" {
     //调用A链码的invoke
     return t.invoke(stub, args)
  } else if function == "query" {
   //调用A链码的query
     return t.query(stub, args)
  }

  return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")
}
func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
  var A, B string    // Entities
  if len(args) != 3 {
     return shim.Error("Incorrect number of arguments. Expecting 3")
  }
  A = args[0]
  B = args[1]
  parm1:=[]string{"invoke",A,B,args[2]}
  queryArgs:=make([][]byte,len(parm1))
  for i,arg:=range parm1{
     queryArgs[i]=[]byte(arg)
  }
  response:=stub.InvokeChaincode("mychannel",queryArgs,"mychannel")
  if response.Status !=shim.OK{
     return shim.Error("failed to invoke other chaincode")
  }
  result:=string(response.Payload)
  return shim.Success([]byte("success to invoke:"+result)) //和官方输出有点区别,我这里输出多了个“success to invoke",便于区分

}

func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
  if len(args) != 1 {
     return shim.Error("Incorrect number of arguments. Expecting 1")
  }
  account:=args[0]
  parm1:=[]string{"query",account}
  queryArgs:=make([][]byte,len(parm1))
  for i,arg:=range parm1{
     queryArgs[i]=[]byte(arg)
  }
  response:=stub.InvokeChaincode("mychannel",queryArgs,"mychannel")
  if response.Status !=shim.OK{
     return shim.Error("failed to invoke other chaincode")
  }
  result:=string(response.Payload)
  return shim.Success([]byte("success to invoke:"+result))
}

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

Thinking of this problem, the environment must be no problem, here is the result.
Organization A installs the example chain code and instantiates it

peer chaincode install -n mychannel -p github.com/hyperledger/fabric/aberic/chaincode/go/chaincode_example02 -v 1.0
peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mychannel -c '{"Args":["init","A","100","B","100"]}' -P "OR ('Org1MSP.member','Org2MSP.member')" -v 1.0
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query","A"]}'
peer chaincode invoke -C mychannel -n mychannel -c '{"Args":["invoke","A","B","5"]}'
//官方链码很简单,实例化的时候,A,B两个账户存100快,然后invoke是AB之间转账,这里是A给B转账5块钱。
转完之后A 95,B 105.
peer channel list   //列出当前通道
peer chaincode list --installed //列出当前组织安装的链码
peer chaincode list --instantiated -C mychannel //列出通道已经实例化的链码

Switch to another organization B. I find it troublesome to use a stand-alone machine here, and perform cli client operations. Just modify the environment variables of the cli container.

peer channel join -b mychannel.block //加入创建的通道
peer chaincode install -n test -p github.com/hyperledger/fabric/aberic/chaincode/go/test -v 1.0
peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n test -c '{"Args":[]}' -P "OR ('Org1MSP.member','Org2MSP.member')" -v 1.0
peer chaincode query -C mychannel -n test -c '{"Args":["query","A"]}'//操作失败,显示找不到链码
peer chaincode invoke -C mychannel -n test -c '{"Args":["invoke","A","B","10"]}'

peer chaincode list --installed //列出B组织安装的链码,可以看到只有B组织test链码
peer chaincode list --instantiated -C mychannel //这里可以看到mychannel通道里实例化链码包括A组织的和B组织的

Reason: Although they are all in the same channel, the AB organizations only have their own chain codes. Even if the A chain code is called by the B organization chain code, the B organization does not install the chain code and cannot execute the A chain code logic.

修改
在B组织安装A的链码,B的链码就可以调用了,同时由于B安装A的链码,所以在B组织执行A链码也是ok的,
感觉这里相当于把A的链码当成一个函数传入了。安装A链码,就相当于引入了这个库,要不然找不到。
//B安装A的链码不需要实例化,同一个通道的某个链码只需要实例化一次。
peer chaincode list --installed //列出B组织安装的链码,可以看到AB链码均存在了。
peer chaincode query -C mychannel -n test -c '{"Args":["query","A"]}'//成功,和A组织执行查询结果相同
peer chaincode invoke -C mychannel -n test -c '{"Args":["invoke","A","B","10"]}'//成功,和A组织执行交易结果相同
------
ps:多加一句,回到A组织,查询安装的链码只有官方链码,所以A还是智能查询A自己的链码。

The pictures are not posted, but the core chain code and steps are written, remember the conclusion, if an organization wants to call other chain codes, then the current organization must install the called chain code

Guess you like

Origin blog.csdn.net/hungrylion/article/details/109288785