摘要:兄弟連區(qū)塊鏈教程源代碼分析服務(wù)端,年下半年,區(qū)塊鏈行業(yè)正逐漸褪去發(fā)展之初的浮躁回歸理性,表面上看相關(guān)人才需求與身價(jià)似乎正在回落。源代碼筆記之服務(wù)端概述相關(guān)代碼在目錄下。,接口實(shí)現(xiàn),即結(jié)構(gòu)體及方法,以及服務(wù)端處理流程。
兄弟連區(qū)塊鏈教程Fabric1.0源代碼分析Peer(Endorser服務(wù)端),2018年下半年,區(qū)塊鏈行業(yè)正逐漸褪去發(fā)展之初的浮躁、回歸理性,表面上看相關(guān)人才需求與身價(jià)似乎正在回落。但事實(shí)上,正是初期泡沫的漸退,讓人們更多的關(guān)注點(diǎn)放在了區(qū)塊鏈真正的技術(shù)之上。
Fabric 1.0源代碼筆記 之 Peer #EndorserServer(Endorser服務(wù)端) 1、EndorserServer概述EndorserServer相關(guān)代碼在protos/peer、core/endorser目錄下。
protos/peer/peer.pb.go,EndorserServer接口定義。
core/endorser/endorser.go,EndorserServer接口實(shí)現(xiàn),即Endorser結(jié)構(gòu)體及方法,以及Endorser服務(wù)端ProcessProposal處理流程。
2、EndorserServer接口定義 2.1、EndorserServer接口定義type EndorserServer interface { ????ProcessProposal(context.Context, *SignedProposal) (*ProposalResponse, error) } //代碼在protos/peer/peer.pb.go2.2、gRPC相關(guān)實(shí)現(xiàn)
var _Endorser_serviceDesc = grpc.ServiceDesc{ ????ServiceName: "protos.Endorser", ????HandlerType: (*EndorserServer)(nil), ????Methods: []grpc.MethodDesc{ ????????{ ????????????MethodName: "ProcessProposal", ????????????Handler: _Endorser_ProcessProposal_Handler, ????????}, ????}, ????Streams: []grpc.StreamDesc{}, ????Metadata: "peer/peer.proto", } func RegisterEndorserServer(s *grpc.Server, srv EndorserServer) { ????s.RegisterService(&_Endorser_serviceDesc, srv) } func _Endorser_ProcessProposal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { ????in := new(SignedProposal) ????if err := dec(in); err != nil { ????????return nil, err ????} ????if interceptor == nil { ????????return srv.(EndorserServer).ProcessProposal(ctx, in) ????} ????info := &grpc.UnaryServerInfo{ ????????Server: srv, ????????FullMethod: "/protos.Endorser/ProcessProposal", ????} ????handler := func(ctx context.Context, req interface{}) (interface{}, error) { ????????return srv.(EndorserServer).ProcessProposal(ctx, req.(*SignedProposal)) ????} ????return interceptor(ctx, in, info, handler) } //代碼在protos/peer/peer.pb.go3、EndorserServer接口實(shí)現(xiàn) 3.1、Endorser結(jié)構(gòu)體及方法
type Endorser struct { ????policyChecker policy.PolicyChecker //策略檢查器 } //代碼在core/endorser/endorser.go
涉及方法如下:
//構(gòu)造Endorser func NewEndorserServer() pb.EndorserServer //執(zhí)行提案 func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedProposal) (*pb.ProposalResponse, error) //檢查SignedProposal是否符合通道策略,調(diào)用e.policyChecker.CheckPolicy() func (e *Endorser) checkACL(signedProp *pb.SignedProposal, chdr *common.ChannelHeader, shdr *common.SignatureHeader, hdrext *pb.ChaincodeHeaderExtension) error //檢查Escc和Vscc,暫未實(shí)現(xiàn) func (*Endorser) checkEsccAndVscc(prop *pb.Proposal) error //獲取賬本的交易模擬器,調(diào)用peer.GetLedger(ledgername).NewTxSimulator() func (*Endorser) getTxSimulator(ledgername string) (ledger.TxSimulator, error) //獲取賬本歷史交易查詢器,調(diào)用peer.GetLedger(ledgername).NewHistoryQueryExecutor() func (*Endorser) getHistoryQueryExecutor(ledgername string) (ledger.HistoryQueryExecutor, error) //執(zhí)行鏈碼 func (e *Endorser) callChaincode(ctxt context.Context, chainID string, version string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, cis *pb.ChaincodeInvocationSpec, cid *pb.ChaincodeID, txsim ledger.TxSimulator) (*pb.Response, *pb.ChaincodeEvent, error) func (e *Endorser) disableJavaCCInst(cid *pb.ChaincodeID, cis *pb.ChaincodeInvocationSpec) error //通過調(diào)用chaincode來模擬提案 func (e *Endorser) simulateProposal(ctx context.Context, chainID string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, cid *pb.ChaincodeID, txsim ledger.TxSimulator) (*ccprovider.ChaincodeData, *pb.Response, []byte, *pb.ChaincodeEvent, error) //從LSCC獲取鏈碼數(shù)據(jù) func (e *Endorser) getCDSFromLSCC(ctx context.Context, chainID string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chaincodeID string, txsim ledger.TxSimulator) (*ccprovider.ChaincodeData, error) //提案背書 func (e *Endorser) endorseProposal(ctx context.Context, chainID string, txid string, signedProp *pb.SignedProposal, proposal *pb.Proposal, response *pb.Response, simRes []byte, event *pb.ChaincodeEvent, visibility []byte, ccid *pb.ChaincodeID, txsim ledger.TxSimulator, cd *ccprovider.ChaincodeData) (*pb.ProposalResponse, error) //提交模擬交易,僅測試使用 func (e *Endorser) commitTxSimulation(proposal *pb.Proposal, chainID string, signer msp.SigningIdentity, pResp *pb.ProposalResponse, blockNumber uint64) error //代碼在core/endorser/endorser.go3.2、Endorser服務(wù)端ProcessProposal處理流程
Endorser服務(wù)端ProcessProposal處理流程,即func (e Endorser) ProcessProposal(ctx context.Context, signedProp pb.SignedProposal) (*pb.ProposalResponse, error)方法實(shí)現(xiàn)。
3.2.1、校驗(yàn)SignedProposal合法性,并獲取ChannelHeader和SignatureHeader//校驗(yàn)SignedProposal合法性 prop, hdr, hdrExt, err := validation.ValidateProposalMessage(signedProp) //獲取ChannelHeader chdr, err := putils.UnmarshalChannelHeader(hdr.ChannelHeader) //獲取SignatureHeader shdr, err := putils.GetSignatureHeader(hdr.SignatureHeader) //代碼在core/endorser/endorser.go
validation.ValidateProposalMessage(signedProp)代碼如下:
func ValidateProposalMessage(signedProp *pb.SignedProposal) (*pb.Proposal, *common.Header, *pb.ChaincodeHeaderExtension, error) { ????prop, err := utils.GetProposal(signedProp.ProposalBytes) //獲取type Proposal struct ????hdr, err := utils.GetHeader(prop.Header) //獲取Proposal.Header ????chdr, shdr, err := validateCommonHeader(hdr) //校驗(yàn)Proposal.Header ????//檢查來自創(chuàng)建者的簽名 ????err = checkSignatureFromCreator(shdr.Creator, signedProp.Signature, signedProp.ProposalBytes, chdr.ChannelId) ????//校驗(yàn)交易TxID,TxID由Nonce和Creator構(gòu)成 ????err = utils.CheckProposalTxID( ????????chdr.TxId, //ChannelHeader.TxId ????????shdr.Nonce, //SignatureHeader.Nonce ????????shdr.Creator) //SignatureHeader.Creator ????switch common.HeaderType(chdr.Type) { ????case common.HeaderType_CONFIG: ????????fallthrough ????case common.HeaderType_ENDORSER_TRANSACTION: ????????//校驗(yàn)ChaincodeHeaderExtension ????????chaincodeHdrExt, err := validateChaincodeProposalMessage(prop, hdr) ????????return prop, hdr, chaincodeHdrExt, err ????default: ????????return nil, nil, nil, fmt.Errorf("Unsupported proposal type %d", common.HeaderType(chdr.Type)) ????} } //代碼在core/common/validation/msgvalidation.go3.2.2、校驗(yàn)是否系統(tǒng)鏈碼且提案不可調(diào)用,獲取chainID和TxId,獲取Ledger并校驗(yàn)txid是否已存在,非系統(tǒng)鏈碼校驗(yàn)提案權(quán)限(是否符合通道策略)
//校驗(yàn)是否系統(tǒng)鏈碼且提案不可調(diào)用 if syscc.IsSysCCAndNotInvokableExternal(hdrExt.ChaincodeId.Name) { ????//如果是系統(tǒng)鏈碼且提案不可調(diào)用 } //獲取chainID,即ChannelId chainID := chdr.ChannelId //獲取交易TxId txid := chdr.TxId if chainID != "" { ????//獲取Ledger ????lgr := peer.GetLedger(chainID) ????//校驗(yàn)txid是否已存在 ????_, err := lgr.GetTransactionByID(txid) ????//非系統(tǒng)鏈碼校驗(yàn)提案權(quán)限(是否符合通道策略) ????if !syscc.IsSysCC(hdrExt.ChaincodeId.Name) { ????????err = e.checkACL(signedProp, chdr, shdr, hdrExt) ????} } //代碼在core/endorser/endorser.go3.2.3、獲取賬本的交易模擬器和歷史記錄查詢器,并模擬提案執(zhí)行
var txsim ledger.TxSimulator var historyQueryExecutor ledger.HistoryQueryExecutor if chainID != "" { ????//獲取賬本的交易模擬器 ????txsim, err = e.getTxSimulator(chainID) ????//獲取歷史記錄查詢器 ????historyQueryExecutor, err = e.getHistoryQueryExecutor(chainID) ????//HistoryQueryExecutorKey key = "historyqueryexecutorkey" ????//context.WithValue,將Key與對象建立關(guān)系 ????ctx = context.WithValue(ctx, chaincode.HistoryQueryExecutorKey, historyQueryExecutor) } //模擬提案執(zhí)行 cd, res, simulationResult, ccevent, err := e.simulateProposal(ctx, chainID, txid, signedProp, prop, hdrExt.ChaincodeId, txsim) //代碼在core/endorser/endorser.go
e.simulateProposal(ctx, chainID, txid, signedProp, prop, hdrExt.ChaincodeId, txsim)代碼如下:模擬提案執(zhí)行。
func (e *Endorser) simulateProposal(ctx context.Context, chainID string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, cid *pb.ChaincodeID, txsim ledger.TxSimulator) (*ccprovider.ChaincodeData , *pb.Response, []byte, *pb.ChaincodeEvent, error) { ????//獲取ChaincodeInvocationSpec ????cis, err := putils.GetChaincodeInvocationSpec(prop) ????//禁用Java安裝、實(shí)例化和立即升級(jí) ????err = e.disableJavaCCInst(cid, cis) ????//檢查Escc和Vscc,暫未實(shí)現(xiàn) ????err = e.checkEsccAndVscc(prop) ????var cdLedger *ccprovider.ChaincodeData ????var version string ????if !syscc.IsSysCC(cid.Name) { //非系統(tǒng)鏈碼 ????????//獲取鏈碼數(shù)據(jù)ChaincodeData ????????cdLedger, err = e.getCDSFromLSCC(ctx, chainID, txid, signedProp, prop, cid.Name, txsim) ????????//獲取鏈碼數(shù)據(jù)版本 ????????version = cdLedger.Version ????????//檢查鏈碼實(shí)例化策略 ????????err = ccprovider.CheckInsantiationPolicy(cid.Name, version, cdLedger) ????} else { ????????version = util.GetSysCCVersion() //獲取系統(tǒng)鏈碼版本 ????} ????var simResult []byte ????var res *pb.Response ????var ccevent *pb.ChaincodeEvent ????//執(zhí)行鏈碼 ????res, ccevent, err = e.callChaincode(ctx, chainID, version, txid, signedProp, prop, cis, cid, txsim) ????if txsim != nil { ????????//獲取交易模擬結(jié)果 ????????simResult, err = txsim.GetTxSimulationResults() ????} ????return cdLedger, res, simResult, ccevent, nil } //代碼在core/endorser/endorser.go
e.endorseProposal(ctx, chainID, txid, signedProp, prop, res, simulationResult, ccevent, hdrExt.PayloadVisibility, hdrExt.ChaincodeId, txsim, cd)代碼如下:為提案背書。
func (e *Endorser) callChaincode(ctxt context.Context, chainID string, version string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, cis *pb.ChaincodeInvocationSpec, cid *pb.ChaincodeID, txsim ledger.TxSimulator) (*pb.Response, *pb.ChaincodeEvent, error) { ????var err error ????var res *pb.Response ????var ccevent *pb.ChaincodeEvent ????if txsim != nil { ????????//TXSimulatorKey key = "txsimulatorkey",key與對象建立關(guān)系 ????????ctxt = context.WithValue(ctxt, chaincode.TXSimulatorKey, txsim) ????} ????scc := syscc.IsSysCC(cid.Name) //是否系統(tǒng)鏈碼 ????cccid := ccprovider.NewCCContext(chainID, cid.Name, version, txid, scc, signedProp, prop) ????//執(zhí)行鏈碼 ????res, ccevent, err = chaincode.ExecuteChaincode(ctxt, cccid, cis.ChaincodeSpec.Input.Args) ????//如果是生命周期管理系統(tǒng)鏈碼,并且參數(shù)為實(shí)例化或升級(jí) ????if cid.Name == "lscc" && len(cis.ChaincodeSpec.Input.Args) >= 3 && (string(cis.ChaincodeSpec.Input.Args[0]) == "deploy" || string(cis.ChaincodeSpec.Input.Args[0]) == "upgrade") { ????????var cds *pb.ChaincodeDeploymentSpec ????????//獲取ChaincodeDeploymentSpec ????????cds, err = putils.GetChaincodeDeploymentSpec(cis.ChaincodeSpec.Input.Args[2]) ????????//待實(shí)例化或升級(jí)的鏈碼執(zhí)行實(shí)例化或升級(jí) ????????cccid = ccprovider.NewCCContext(chainID, cds.ChaincodeSpec.ChaincodeId.Name, cds.ChaincodeSpec.ChaincodeId.Version, txid, false, signedProp, prop) ????????_, _, err = chaincode.Execute(ctxt, cccid, cds) ????} ????return res, ccevent, err } //代碼在core/endorser/endorser.go
Chaincode更詳細(xì)內(nèi)容,參考:Fabric 1.0源代碼筆記 之 Chaincode(鏈碼)
3.2.4、為提案背書,構(gòu)造ProposalResponse并返回給Endorser客戶端var pResp *pb.ProposalResponse //為提案背書,即調(diào)取escc系統(tǒng)鏈碼 pResp, err = e.endorseProposal(ctx, chainID, txid, signedProp, prop, res, simulationResult, ccevent, hdrExt.PayloadVisibility, hdrExt.ChaincodeId, txsim, cd) pResp.Response.Payload = res.Payload return pResp, nil //代碼在core/endorser/endorser.go
e.endorseProposal(ctx, chainID, txid, signedProp, prop, res, simulationResult, ccevent, hdrExt.PayloadVisibility, hdrExt.ChaincodeId, txsim, cd)代碼如下:
func (e *Endorser) endorseProposal(ctx context.Context, chainID string, txid string, signedProp *pb.SignedProposal, proposal *pb.Proposal, response *pb.Response, simRes []byte, event *pb.ChaincodeEvent, visibility []byte, ccid *pb.ChaincodeID, txsim ledger.TxSimulator, cd *ccprovider.ChaincodeData) (*pb.ProposalResponse, error) { ????isSysCC := cd == nil ????var escc string ????if isSysCC { ????????escc = "escc" ????} else { ????????escc = cd.Escc ????} ????var err error ????var eventBytes []byte ????if event != nil { ????????eventBytes, err = putils.GetBytesChaincodeEvent(event) ????} ????resBytes, err := putils.GetBytesResponse(response) ????if isSysCC { ????????ccid.Version = util.GetSysCCVersion() ????} else { ????????ccid.Version = cd.Version ????} ????ccidBytes, err := putils.Marshal(ccid) ????args := [][]byte{[]byte(""), proposal.Header, proposal.Payload, ccidBytes, resBytes, simRes, eventBytes, visibility} ????version := util.GetSysCCVersion() ????ecccis := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: escc}, Input: &pb.ChaincodeInput{Args: args}}} ????//執(zhí)行escc系統(tǒng)鏈碼 ????res, _, err := e.callChaincode(ctx, chainID, version, txid, signedProp, proposal, ecccis, &pb.ChaincodeID{Name: escc}, txsim) ????prBytes := res.Payload ????pResp, err := putils.GetProposalResponse(prBytes) ????return pResp, nil } //代碼在core/endorser/endorser.go
感謝關(guān)注兄弟連區(qū)塊鏈教程分享!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/24368.html
摘要:兄弟連區(qū)塊鏈教程源代碼分析客戶端,年下半年,區(qū)塊鏈行業(yè)正逐漸褪去發(fā)展之初的浮躁回歸理性,表面上看相關(guān)人才需求與身價(jià)似乎正在回落。源代碼筆記之客戶端概述相關(guān)代碼分布如下,接口及實(shí)現(xiàn)。代碼在工具函數(shù)獲取客戶端代碼在 兄弟連區(qū)塊鏈教程Fabric1.0源代碼分析Peer EndorserClient(Endorser客戶端),2018年下半年,區(qū)塊鏈行業(yè)正逐漸褪去發(fā)展之初的浮躁、回歸理性...
摘要:兄弟連區(qū)塊鏈教程源代碼分析命令及子命令實(shí)現(xiàn),年下半年,區(qū)塊鏈行業(yè)正逐漸褪去發(fā)展之初的浮躁回歸理性,表面上看相關(guān)人才需求與身價(jià)似乎正在回落。 兄弟連區(qū)塊鏈教程Fabric1.0源代碼分析Peer peer chaincode命令及子命令實(shí)現(xiàn),2018年下半年,區(qū)塊鏈行業(yè)正逐漸褪去發(fā)展之初的浮躁、回歸理性,表面上看相關(guān)人才需求與身價(jià)似乎正在回落。但事實(shí)上,正是初期泡沫的漸退,讓人們更多...
摘要:區(qū)塊鏈教程源代碼分析根命令入口及加載子命令,年下半年,區(qū)塊鏈行業(yè)正逐漸褪去發(fā)展之初的浮躁回歸理性,表面上看相關(guān)人才需求與身價(jià)似乎正在回落。代碼在為命令啟動(dòng)。 區(qū)塊鏈教程Fabric1.0源代碼分析Peer peer根命令入口及加載子命令,2018年下半年,區(qū)塊鏈行業(yè)正逐漸褪去發(fā)展之初的浮躁、回歸理性,表面上看相關(guān)人才需求與身價(jià)似乎正在回落。但事實(shí)上,正是初期泡沫的漸退,讓人們更多的...
摘要:兄弟連區(qū)塊鏈教程源代碼分析根命令入口及加載子命令二。此處傳入為,將模塊日志級(jí)別設(shè)置為,并會(huì)將初始化為。代碼在目錄下包括。核心代碼為,目的是在或?yàn)榭諘r(shí)設(shè)置默認(rèn)值。感謝關(guān)注兄弟連區(qū)塊鏈教程分享 兄弟連區(qū)塊鏈教程Fabric1.0源代碼分析Peer peer根命令入口及加載子命令二。flogging,即:fabric logging,為Fabric基于第三方包go-logging封裝的日...
摘要:作為系列的新篇章,我選擇從超級(jí)賬本的開始。為什么選擇超級(jí)賬本作為起點(diǎn)我在之前的文章中曾說過會(huì)從超級(jí)賬本入手開始區(qū)塊鏈的學(xué)習(xí)和實(shí)踐,同時(shí)也給出了個(gè)人的理由。檢查事務(wù)提議的響應(yīng)。為了降低區(qū)塊鏈應(yīng)用的開發(fā)難度,超級(jí)賬本項(xiàng)目又引入了。 本著以教帶學(xué),Learning by Doing的想法,我于上周加入了Bob組織的HiBlock區(qū)塊鏈技術(shù)布道群。這個(gè)群可不太好混,群規(guī)要求每個(gè)成員必需每周有輸...
閱讀 3096·2021-09-22 15:20
閱讀 2613·2019-08-30 15:54
閱讀 1979·2019-08-30 14:06
閱讀 3125·2019-08-30 13:05
閱讀 2475·2019-08-29 18:36
閱讀 583·2019-08-29 15:10
閱讀 536·2019-08-29 11:17
閱讀 834·2019-08-28 18:11