Hyperledger Fabric測試不一樣組織鏈碼調用

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

相關文章
相關標籤/搜索