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