pkg/client/channel支持訪問Fabric網(wǎng)絡(luò)上的通道。channel客戶端實(shí)例提供與指定通道上的Peer節(jié)點(diǎn)進(jìn)行交互的處理函數(shù)。channel客戶端可以在指定通道上查詢鏈碼,執(zhí)行鏈碼以及注冊或注銷鏈碼事件。如果應(yīng)用程序需要與Fabric網(wǎng)絡(luò)的多條通道進(jìn)行交互,需要為每條通道創(chuàng)建一個(gè)單獨(dú)的通道客戶端實(shí)例。
官方文檔:
https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/channel
創(chuàng)新互聯(lián)建站堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站制作、網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的大冶網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
channel使用流程如下:
A、準(zhǔn)備通道客戶端上下文
B、創(chuàng)建通道客戶端
C、執(zhí)行鏈碼
D、查詢鏈碼
channel使用示例如下:
c, err := New(mockChannelProvider("mychannel"))
if err != nil {
fmt.Println("failed to create client")
}
response, err := c.Query(Request{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("data")}})
if err != nil {
fmt.Printf("failed to query chaincode: %s\n", err)
}
fmt.Println(string(response.Payload))
// output:
// abc
// Request 包含查詢和執(zhí)行一個(gè)調(diào)用交易的參數(shù)
type Request struct {
ChaincodeID string
Fcn string
Args [][]byte
TransientMap map[string][]byte
// InvocationChai包含元數(shù)據(jù),某些選擇服務(wù)實(shí)現(xiàn)使用元數(shù)據(jù)來選擇滿足調(diào)用鏈中所有鏈碼的背書
// 策略的背書節(jié)點(diǎn)
// Each chaincode may also be associated with a set of private data collection names
// which are used by some Selection Services (e.g. Fabric Selection) to exclude endorsers
// that do NOT have read access to the collections.
// The invoked chaincode (specified by ChaincodeID) may optionally be added to the invocation
// chain along with any collections, otherwise it may be omitted.
InvocationChain []*fab.ChaincodeCall
}
//Response包含執(zhí)行和查詢一個(gè)調(diào)用交易的響應(yīng)參數(shù)
type Response struct {
Proposal *fab.TransactionProposal
Responses []*fab.TransactionProposalResponse
TransactionID fab.TransactionID
TxValidationCode pb.TxValidationCode
ChaincodeStatus int32
Payload []byte
}
type Client struct {
context context.Channel
membership fab.ChannelMembership
eventService fab.EventService
greylist *greylist.Filter
clientTally // nolint
}
通道客戶端支持訪問Fabric網(wǎng)絡(luò)上的通道。為了與特定通道的Peer節(jié)點(diǎn)進(jìn)行交互,通道客戶端實(shí)例提供了一個(gè)處理程序。 如果應(yīng)用程序需要與多個(gè)通道進(jìn)行交互,應(yīng)該為每個(gè)通道創(chuàng)建一個(gè)單獨(dú)的通道客戶端實(shí)例。 通道客戶端只支持非管理功能。
type ClientOption func(*Client) error
func New(channelProvider context.ChannelProvider, opts ...ClientOption) (*Client, error)
返回通道Client實(shí)例。通道客戶端可以在特定通道上查詢鏈碼,執(zhí)行鏈碼以及注冊/注銷鏈碼事件。
使用示例:
ctx := mockChannelProvider("mychannel")
c, err := New(ctx)
if err != nil {
fmt.Println(err)
}
if c != nil {
fmt.Println("channel client created")
} else {
fmt.Println("channel client is nil")
}
// output:
// channel client created
func (cc *Client) Execute(request Request, options ...RequestOption) (Response, error)
使用請求和可選的請求選項(xiàng)進(jìn)行準(zhǔn)備并執(zhí)行事務(wù)。
參數(shù):?
request包含必備鏈碼ID和函數(shù)的相關(guān)信息
options包含可選的請求選項(xiàng)
返回Peer的提案回復(fù)
使用示例:
c, err := New(mockChannelProvider("mychannel"))
if err != nil {
fmt.Println("failed to create client")
}
_, err = c.Execute(Request{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("move"), []byte("a"), []byte("b"), []byte("1")}})
if err != nil {
fmt.Println(err.Error())
}
fmt.Println("Chaincode transaction completed")
// output:
// Chaincode transaction completed
func (cc *Client) InvokeHandler(handler invoke.Handler, request Request, options ...RequestOption) (Response, error)
InvokeHandler使用提供的請求和可選請求選項(xiàng)來調(diào)用處理程序
參數(shù):
handler為要調(diào)用的處理程序
request包含必備的鏈碼ID和函數(shù)的相關(guān)信息
options包含可選的請求選項(xiàng)
返回Peer的提案回復(fù)
使用示例:
c, err := New(mockChannelProvider("mychannel"))
if err != nil {
fmt.Println("failed to create client")
}
response, err := c.InvokeHandler(&exampleHandler{}, Request{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("data")}})
if err != nil {
fmt.Printf("failed to query chaincode: %s\n", err)
}
fmt.Println(string(response.Payload))
// output:
// custom
func (cc *Client) Query(request Request, options ...RequestOption) (Response, error)
使用request 和可選請求選項(xiàng)options查詢鏈碼。
參數(shù):
request包含必備鏈碼ID和函數(shù)的相關(guān)信息
options包含可選的請求選項(xiàng)
返回值:Peer的提案回復(fù)
使用示例:
c, err := New(mockChannelProvider("mychannel"))
if err != nil {
fmt.Println("failed to create client")
}
response, err := c.Query(Request{ChaincodeID: "testCC", Fcn: "invoke", Args: [][]byte{[]byte("query"), []byte("b")}})
if err != nil {
fmt.Printf("failed to query chaincode: %s\n", err)
}
if len(response.Payload) > 0 {
fmt.Println("chaincode query success")
}
// output:
// chaincode query success
func (cc *Client) RegisterChaincodeEvent(chainCodeID string, eventFilter string) (fab.Registration, <-chan *fab.CCEvent, error)
注冊鏈碼事件。當(dāng)不再需要注冊時(shí),必須調(diào)用取消注冊。
參數(shù):
chaincodeID接收事件的鏈碼的鏈碼ID
eventFilter用于接收事件的鏈碼事件過濾器(正則表達(dá)式)
返回注冊和用于接收事件的通道。調(diào)用注銷事件時(shí),通道將關(guān)閉。
使用示例:
c, err := New(mockChannelProvider("mychannel"))
if err != nil {
fmt.Println("failed to create client")
}
registration, _, err := c.RegisterChaincodeEvent("examplecc", "event123")
if err != nil {
fmt.Println("failed to register chaincode event")
}
defer c.UnregisterChaincodeEvent(registration)
fmt.Println("chaincode event registered successfully")
// output:
// chaincode event registered successfully
func (cc *Client) UnregisterChaincodeEvent(registration fab.Registration)
刪除給定的鏈碼事件注冊并關(guān)閉事件通道。
參數(shù):
registration是從RegisterChaincodeEvent方法返回的注冊句柄
type requestOptions struct {
Targets []fab.Peer // targets
TargetFilter fab.TargetFilter
TargetSorter fab.TargetSorter
Retry retry.Opts
BeforeRetry retry.BeforeRetryHandler
Timeouts map[fab.TimeoutType]time.Duration //timeout options for channel client operations
ParentContext reqContext.Context //parent grpc context for channel client operations (query, execute, invokehandler)
CCFilter invoke.CCFilter
}
// RequestOption func for each Opts argument
type RequestOption func(ctx context.Client, opts *requestOptions) error
func WithBeforeRetry(beforeRetry retry.BeforeRetryHandler) RequestOption
指定在重試前調(diào)用的函數(shù)func WithChaincodeFilter(ccFilter invoke.CCFilter) RequestOption
添加一個(gè)鏈碼過濾器,用于計(jì)算額外的背書節(jié)點(diǎn)func WithParentContext(parentContext reqContext.Context) RequestOption
WithParentContext封裝了grpc父上下文func WithRetry(retryOpt retry.Opts) RequestOption
WithRetry生成用于配置重試的選項(xiàng)func WithTargetEndpoints(keys ...string) RequestOption
WithTargetEndpoints允許為請求的覆蓋目標(biāo)Peer節(jié)點(diǎn)。目標(biāo)Peer節(jié)點(diǎn)由名稱或URL指定,SDK將創(chuàng)建底層的Peer節(jié)點(diǎn)對象。func WithTargetFilter(filter fab.TargetFilter) RequestOption
WithTargetFilter指定每個(gè)請求的目標(biāo)Peer節(jié)點(diǎn)的過濾器func WithTargets(targets ...fab.Peer) RequestOption
WithTargets允許為請求覆蓋目標(biāo)Peer節(jié)點(diǎn)func WithTimeout(timeoutType fab.TimeoutType, timeout time.Duration) RequestOption
WithTimeout封裝了超時(shí)類型的鍵值對func WithTargetSorter(sorter fab.TargetSorter) RequestOption
指定每個(gè)請求的排序節(jié)點(diǎn)
ctx := sdk.ChannelContext(channelName, fabsdk.WithOrg(org), fabsdk.WithUser(user))
cli, err := channel.New(ctx)
if err != nil {
return channel.Response{}, err
}
// 狀態(tài)的查詢
resp,err := cli.Query(channel.Request{
ChaincodeID: chaincodeName,
Fcn: fcn,
Args: args,
}, channel.WithTargetEndpoints("peer0.org1.example.com"))