Hyperledger Fabric測驗不同組織鏈碼呼叫
在熟悉fabric的各種操作之后,開始針對多組織智能合約的應用,發現不同組織的鏈碼應該不同,這時候相互呼叫涉及到一個鏈碼如何部署的問題,
本測驗環境,fabric1.1版本,兩個組織A和B,其中A安裝官方鏈碼go/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
B安裝我自己寫的鏈碼,鏈碼里呼叫官方鏈碼的交易以及查詢功能,鏈碼如下:
//為了操作更簡便,我把呼叫的引數寫的跟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鏈碼的邏輯,
修改
在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自己的鏈碼,
圖都都沒貼,但是核心鏈碼和步驟都寫了,記住結論,如果一個組織要呼叫其他鏈碼,那么當前組織一定要安裝呼叫的鏈碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/195020.html
標籤:其他
上一篇:基于MetaID的分布式儲存方案
