Hyperledger Fabric测试不一样组织链码调用
在熟悉fabric的各类操做以后,开始针对多组织智能合约的应用,发现不一样组织的链码应该不一样,这时候相互调用涉及到一个链码如何部署的问题。git
本测试环境,fabric1.1版本,两个组织A和B,其中A安装官方链码go/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
B安装我本身写的链码,链码里调用官方链码的交易以及查询功能,链码以下:
github
//为了操做更简便,我把调用的参数写的跟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) } }
想到这个问题的,环境确定都没啥问题,这里直接说结果。
A组织安装example链码,实例化
函数
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 //列出通道已经实例化的链码
切换到另外个组织B,我这里嫌麻烦用的是单机,执行的是cli客户端操做,修改一下cli容器的环境变量就能够。测试
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组织的
缘由:虽然都在同一个通道,可是AB组织都只有各自的链码,即便B组织链码调用了A链码,可是B组织没有安装链码,没法执行A链码的逻辑。spa
修改 在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本身的链码。
图都都没贴,可是核心链码和步骤都写了,记住结论,若是一个组织要调用其余链码,那么当前组织必定要安装调用的链码code