摘要:兄弟連區塊鏈教程源代碼分析命令及子命令實現,年下半年,區塊鏈行業正逐漸褪去發展之初的浮躁回歸理性,表面上看相關人才需求與身價似乎正在回落。
兄弟連區塊鏈教程Fabric1.0源代碼分析Peer peer chaincode命令及子命令實現,2018年下半年,區塊鏈行業正逐漸褪去發展之初的浮躁、回歸理性,表面上看相關人才需求與身價似乎正在回落。但事實上,正是初期泡沫的漸退,讓人們更多的關注點放在了區塊鏈真正的技術之上。
Fabric 1.0源代碼筆記 之 Peer #peer chaincode命令及子命令實現 1、peer chaincode install子命令實現(安裝鏈碼) 1.0、peer chaincode install子命令概述peer chaincode install,將鏈碼的源碼和環境封裝為一個鏈碼安裝打包文件,并傳輸到背書節點。
peer chaincode install支持如下兩種方式:
指定代碼方式,peer chaincode install -n <鏈碼名稱> -v <鏈碼版本> -p <鏈碼路徑>
基于鏈碼打包文件方式,peer chaincode install <鏈碼打包文件>
有個圖3
1.1、初始化Endorser客戶端cf, err = InitCmdFactory(true, false) //代碼在peer/chaincode/install.go
cf, err = InitCmdFactory(true, false)代碼如下:
func InitCmdFactory(isEndorserRequired, isOrdererRequired bool) (*ChaincodeCmdFactory, error) { ????var err error ????var endorserClient pb.EndorserClient ????if isEndorserRequired { ????????//獲取Endorser客戶端 ????????endorserClient, err = common.GetEndorserClientFnc() //func GetEndorserClient() (pb.EndorserClient, error) ????} ????//獲取簽名 ????signer, err := common.GetDefaultSignerFnc() ????var broadcastClient common.BroadcastClient ????if isOrdererRequired { ????????//此處未用到,暫略 ????} ????//構造ChaincodeCmdFactory ????return &ChaincodeCmdFactory{ ????????EndorserClient: endorserClient, ????????Signer: signer, ????????BroadcastClient: broadcastClient, ????}, nil } //代碼在peer/chaincode/common.go1.2、構造ChaincodeDeploymentSpec消息(鏈碼信息及鏈碼文件打包)
if ccpackfile == "" { //指定代碼方式,重新構造構造ChaincodeDeploymentSpec消息 ????ccpackmsg, err = genChaincodeDeploymentSpec(cmd, chaincodeName, chaincodeVersion) } else { //基于鏈碼打包文件方式,直接讀取ChaincodeDeploymentSpec消息 ????var cds *pb.ChaincodeDeploymentSpec ????ccpackmsg, cds, err = getPackageFromFile(ccpackfile) } //代碼在peer/chaincode/install.go
ccpackmsg, err = genChaincodeDeploymentSpec(cmd, chaincodeName, chaincodeVersion)代碼如下:
func genChaincodeDeploymentSpec(cmd *cobra.Command, chaincodeName, chaincodeVersion string) (*pb.ChaincodeDeploymentSpec, error) { ????//已經存在,直接報錯 ????if existed, _ := ccprovider.ChaincodePackageExists(chaincodeName, chaincodeVersion); existed { ????????return nil, fmt.Errorf("chaincode %s:%s already exists", chaincodeName, chaincodeVersion) ????} ????spec, err := getChaincodeSpec(cmd) ????cds, err := getChaincodeDeploymentSpec(spec, true) ????return cds, nil } //代碼在peer/chaincode/install.go
spec, err := getChaincodeSpec(cmd)代碼如下:
func getChaincodeSpec(cmd *cobra.Command) (*pb.ChaincodeSpec, error) { ????spec := &pb.ChaincodeSpec{} ????err := checkChaincodeCmdParams(cmd) //檢查參數合法性 ????input := &pb.ChaincodeInput{} ????//flags.StringVarP(&chaincodeCtorJSON, "ctor", "c", "{}",ctor為鏈碼具體執行參數信息,默認為{} ????err := json.Unmarshal([]byte(chaincodeCtorJSON), &input) ????//flags.StringVarP(&chaincodeLang, "lang", "l", "golang",lang為鏈碼的編寫語言,默認為golang ????chaincodeLang = strings.ToUpper(chaincodeLang) ????spec = &pb.ChaincodeSpec{ ????????Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value[chaincodeLang]), ????????ChaincodeId: &pb.ChaincodeID{Path: chaincodePath, Name: chaincodeName, Version: chaincodeVersion}, ????????Input: input, ????} ????return spec, nil } //代碼在peer/chaincode/common.go
cds, err := getChaincodeDeploymentSpec(spec, true)代碼如下:
func getChaincodeDeploymentSpec(spec *pb.ChaincodeSpec, crtPkg bool) (*pb.ChaincodeDeploymentSpec, error) { ????var codePackageBytes []byte ????if chaincode.IsDevMode() == false && crtPkg { ????????var err error ????????err = checkSpec(spec) //檢查spec合法性 ????????codePackageBytes, err = container.GetChaincodePackageBytes(spec) //打包鏈碼文件及依賴文件 ????} ????//構造ChaincodeDeploymentSpec ????chaincodeDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes} ????return chaincodeDeploymentSpec, nil //代碼在peer/chaincode/common.go1.3、創建lscc Proposal并簽名
creator, err := cf.Signer.Serialize() //獲取簽名者 //按ChaincodeDeploymentSpec構造Proposal,即鏈碼ChaincodeDeploymentSpec消息作為參數傳遞給lscc系統鏈碼并調用 //調用createProposalFromCDS(chainID, cds, creator, policy, escc, vscc, "deploy") prop, _, err := utils.CreateInstallProposalFromCDS(msg, creator) var signedProp *pb.SignedProposal signedProp, err = utils.GetSignedProposal(prop, cf.Signer) //簽名提案 //代碼在peer/chaincode/install.go
createProposalFromCDS(chainID, cds, creator, policy, escc, vscc, "deploy")代碼如下:
func createProposalFromCDS(chainID string, msg proto.Message, creator []byte, policy []byte, escc []byte, vscc []byte, propType string) (*peer.Proposal, string, error) { ????var ccinp *peer.ChaincodeInput ????var b []byte ????var err error ????b, err = proto.Marshal(msg) ????switch propType { ????case "deploy": ????????fallthrough ????case "upgrade": ????????cds, ok := msg.(*peer.ChaincodeDeploymentSpec) ????????ccinp = &peer.ChaincodeInput{Args: [][]byte{[]byte(propType), []byte(chainID), b, policy, escc, vscc}} ????case "install": ????????ccinp = &peer.ChaincodeInput{Args: [][]byte{[]byte(propType), b}} ????} ????lsccSpec := &peer.ChaincodeInvocationSpec{ //構造lscc ChaincodeInvocationSpec ????????ChaincodeSpec: &peer.ChaincodeSpec{ ????????????Type: peer.ChaincodeSpec_GOLANG, ????????????ChaincodeId: &peer.ChaincodeID{Name: "lscc"}, ????????????Input: ccinp}} ????return CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, chainID, lsccSpec, creator) } //代碼在protos/utils/proputils.go1.4、提交并處理Proposal
proposalResponse, err := cf.EndorserClient.ProcessProposal(context.Background(), signedProp) //代碼在peer/chaincode/install.go2、peer chaincode instantiate子命令實現(實例化鏈碼) 2.0、peer chaincode instantiate概述
peer chaincode instantiate命令通過構造生命周期管理系統鏈碼(LSCC)的交易,將安裝過的鏈碼在指定通道上進行實例化調用。
在peer上創建容器啟動,并執行初始化操作。
與2.1接近,附BroadcastClient初始化代碼如下:
cf, err = InitCmdFactory(true, true) //代碼在peer/chaincode/instantiate.go
func InitCmdFactory(isEndorserRequired, isOrdererRequired bool) (*ChaincodeCmdFactory, error) { ????//初始化EndorserClient、Signer ????var broadcastClient common.BroadcastClient ????if isOrdererRequired { ????????//flags.StringVarP(&orderingEndpoint, "orderer", "o", "", "Ordering service endpoint") ????????//orderingEndpoint為orderer服務地址 ????????broadcastClient, err = common.GetBroadcastClientFnc(orderingEndpoint, tls, caFile) ????} } //代碼在peer/chaincode/common.go
BroadcastClient更詳細內容,參考Fabric 1.0源代碼筆記 之 Peer #BroadcastClient(Broadcast客戶端)
2.2、構造ChaincodeDeploymentSpec消息spec, err := getChaincodeSpec(cmd) //構造ChaincodeSpec,參考本文1.2 //構造ChaincodeDeploymentSpec,參考本文1.2,但無法打包鏈碼文件 cds, err := getChaincodeDeploymentSpec(spec, false) //代碼在peer/chaincode/instantiate.go2.3、創建lscc Proposal并簽名
creator, err := cf.Signer.Serialize() //獲取簽名者 //policyMarhsalled為flags.StringVarP(&policy, "policy", "P", common.UndefinedParamValue,即鏈碼關聯的背書策略 //即調用 createProposalFromCDS(chainID, cds, creator, policy, escc, vscc, "deploy"),參考本文1.3 prop, _, err := utils.CreateDeployProposalFromCDS(chainID, cds, creator, policyMarhsalled, []byte(escc), []byte(vscc)) var signedProp *pb.SignedProposal signedProp, err = utils.GetSignedProposal(prop, cf.Signer) //簽名提案 //代碼在peer/chaincode/instantiate.go2.4、提交并處理Proposal、獲取Proposal響應并創建簽名交易Envelope
proposalResponse, err := cf.EndorserClient.ProcessProposal(context.Background(), signedProp) if proposalResponse != nil { ????env, err := utils.CreateSignedTx(prop, cf.Signer, proposalResponse) //由Proposal創建簽名交易Envelope ????return env, nil } //代碼在peer/chaincode/instantiate.go
env, err := utils.CreateSignedTx(prop, cf.Signer, proposalResponse)代碼如下:
func CreateSignedTx(proposal *peer.Proposal, signer msp.SigningIdentity, resps ...*peer.ProposalResponse) (*common.Envelope, error) { ????hdr, err := GetHeader(proposal.Header) //反序列化為common.Header ????pPayl, err := GetChaincodeProposalPayload(proposal.Payload) //反序列化為peer.ChaincodeProposalPayload ????signerBytes, err := signer.Serialize() //signer序列化 ????shdr, err := GetSignatureHeader(hdr.SignatureHeader) //反序列化為common.SignatureHeader ????if bytes.Compare(signerBytes, shdr.Creator) != 0 { //Proposal創建者需與當前簽名者相同 ????????return nil, fmt.Errorf("The signer needs to be the same as the one referenced in the header") ????} ????hdrExt, err := GetChaincodeHeaderExtension(hdr) //Header.ChannelHeader反序列化為peer.ChaincodeHeaderExtension ????var a1 []byte ????for n, r := range resps { ????????if n == 0 { ????????????a1 = r.Payload ????????????if r.Response.Status != 200 { //檢查Response.Status是否為200 ????????????????return nil, fmt.Errorf("Proposal response was not successful, error code %d, msg %s", r.Response.Status, r.Response.Message) ????????????} ????????????continue ????????} ????????if bytes.Compare(a1, r.Payload) != 0 { //檢查所有ProposalResponse.Payload是否相同 ????????????return nil, fmt.Errorf("ProposalResponsePayloads do not match") ????????} ????} ????endorsements := make([]*peer.Endorsement, len(resps)) ????for n, r := range resps { ????????endorsements[n] = r.Endorsement ????} ????//如下為逐層構建common.Envelope ????cea := &peer.ChaincodeEndorsedAction{ProposalResponsePayload: resps[0].Payload, Endorsements: endorsements} ????propPayloadBytes, err := GetBytesProposalPayloadForTx(pPayl, hdrExt.PayloadVisibility) ????cap := &peer.ChaincodeActionPayload{ChaincodeProposalPayload: propPayloadBytes, Action: cea} ????capBytes, err := GetBytesChaincodeActionPayload(cap) ????taa := &peer.TransactionAction{Header: hdr.SignatureHeader, Payload: capBytes} ????taas := make([]*peer.TransactionAction, 1) ????taas[0] = taa ????tx := &peer.Transaction{Actions: taas} ????txBytes, err := GetBytesTransaction(tx) ????payl := &common.Payload{Header: hdr, Data: txBytes} ????paylBytes, err := GetBytesPayload(payl) ????sig, err := signer.Sign(paylBytes) ????return &common.Envelope{Payload: paylBytes, Signature: sig}, nil } //代碼在protos/utils/txutils.go
common.Envelope更詳細內容,參考:Fabric 1.0源代碼筆記 之 附錄-關鍵數據結構
2.5、向orderer廣播交易Envelopeerr = cf.BroadcastClient.Send(env) //代碼在peer/chaincode/instantiate.go3、peer chaincode invoke子命令實現(調用鏈碼) 3.0、peer chaincode invoke概述
通過invoke命令可以調用運行中的鏈碼的方法。
.png)
參考本文1.1和2.1。
cf, err = InitCmdFactory(true, true) //代碼在peer/chaincode/invoke.go3.2、構造ChaincodeInvocationSpec
spec, err := getChaincodeSpec(cmd) //構造ChaincodeSpec invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} //構造ChaincodeInvocationSpec //代碼在peer/chaincode/common.go3.3、創建Chaincode Proposal并簽名
creator, err := signer.Serialize() var prop *pb.Proposal prop, _, err = putils.CreateProposalFromCIS(pcommon.HeaderType_ENDORSER_TRANSACTION, cID, invocation, creator) var signedProp *pb.SignedProposal signedProp, err = putils.GetSignedProposal(prop, signer) //Proposal簽名 //代碼在peer/chaincode/common.go3.4、提交并處理Proposal、獲取Proposal響應
var proposalResp *pb.ProposalResponse proposalResp, err = endorserClient.ProcessProposal(context.Background(), signedProp) //代碼在peer/chaincode/common.go3.5、創建簽名交易Envelope并向orderer廣播交易Envelope
if invoke { ????env, err := putils.CreateSignedTx(prop, signer, proposalResp) //創建簽名交易 ????err = bc.Send(env) //廣播交易 } //代碼在peer/chaincode/common.go4、peer chaincode query子命令實現(查詢鏈碼)
與3、peer chaincode invoke子命令實現(調用鏈碼)基本相同,區別在于提交并處理Proposal后,不再創建交易以及廣播交易。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/24371.html
摘要:區塊鏈教程源代碼分析根命令入口及加載子命令,年下半年,區塊鏈行業正逐漸褪去發展之初的浮躁回歸理性,表面上看相關人才需求與身價似乎正在回落。代碼在為命令啟動。 區塊鏈教程Fabric1.0源代碼分析Peer peer根命令入口及加載子命令,2018年下半年,區塊鏈行業正逐漸褪去發展之初的浮躁、回歸理性,表面上看相關人才需求與身價似乎正在回落。但事實上,正是初期泡沫的漸退,讓人們更多的...
摘要:兄弟連區塊鏈教程源代碼分析服務端,年下半年,區塊鏈行業正逐漸褪去發展之初的浮躁回歸理性,表面上看相關人才需求與身價似乎正在回落。源代碼筆記之服務端概述相關代碼在目錄下。,接口實現,即結構體及方法,以及服務端處理流程。 兄弟連區塊鏈教程Fabric1.0源代碼分析Peer(Endorser服務端),2018年下半年,區塊鏈行業正逐漸褪去發展之初的浮躁、回歸理性,表面上看相關人才需求與...
摘要:兄弟連區塊鏈教程源代碼分析根命令入口及加載子命令二。此處傳入為,將模塊日志級別設置為,并會將初始化為。代碼在目錄下包括。核心代碼為,目的是在或為空時設置默認值。感謝關注兄弟連區塊鏈教程分享 兄弟連區塊鏈教程Fabric1.0源代碼分析Peer peer根命令入口及加載子命令二。flogging,即:fabric logging,為Fabric基于第三方包go-logging封裝的日...
摘要:兄弟連區塊鏈教程源代碼分析客戶端,年下半年,區塊鏈行業正逐漸褪去發展之初的浮躁回歸理性,表面上看相關人才需求與身價似乎正在回落。源代碼筆記之客戶端概述相關代碼分布如下,接口及實現。代碼在工具函數獲取客戶端代碼在 兄弟連區塊鏈教程Fabric1.0源代碼分析Peer EndorserClient(Endorser客戶端),2018年下半年,區塊鏈行業正逐漸褪去發展之初的浮躁、回歸理性...
摘要:協議的細節由一個名為的處理。運行下面的腳本來讓所有的事情都發生一兩分鐘后,命令提示符將返回運行結果如下圖所示現在運行該命令查看當前正在運行的容器。 showImg(https://segmentfault.com/img/bVbazHF?w=709&h=159); 前言 本教程基本上是對Marbles項目的翻譯過程. 如果英文比較好的話,建議根據官方操作說明,一步步進行環境部署。當然你...
閱讀 2080·2023-04-25 17:57
閱讀 1287·2021-11-24 09:39
閱讀 2487·2019-08-29 16:39
閱讀 3317·2019-08-29 13:44
閱讀 3126·2019-08-29 13:14
閱讀 2323·2019-08-26 11:36
閱讀 3815·2019-08-26 11:00
閱讀 952·2019-08-26 10:14