博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
区块链教程Fabric1.0源代码分析Peer peer channel命令及子命令实现
阅读量:6841 次
发布时间:2019-06-26

本文共 6872 字,大约阅读时间需要 22 分钟。

  区块链教程Fabric1.0源代码分析Peer peer channel命令及子命令实现,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。

Fabric1.0源代码笔记之Peer peer channel命令及子命令实现

1、peer channel create子命令实现(创建通道)

1.1、初始化Orderer客户端

const (    EndorserRequired    EndorserRequirement = true    EndorserNotRequired EndorserRequirement = false    OrdererRequired     OrdererRequirement  = true    OrdererNotRequired  OrdererRequirement  = false)cf, err = InitCmdFactory(EndorserNotRequired, OrdererRequired)//代码在peer/channel/create.go

cf, err = InitCmdFactory(EndorserNotRequired, OrdererRequired)代码如下:

type ChannelCmdFactory struct {    EndorserClient   pb.EndorserClient //EndorserClient    Signer           msp.SigningIdentity //Signer    BroadcastClient  common.BroadcastClient //BroadcastClient    DeliverClient    deliverClientIntf //DeliverClient    BroadcastFactory BroadcastClientFactory //BroadcastClientFactory,type BroadcastClientFactory func() (common.BroadcastClient, error)}func InitCmdFactory(isEndorserRequired EndorserRequirement, isOrdererRequired OrdererRequirement) (*ChannelCmdFactory, error) {    var err error    cmdFact := &ChannelCmdFactory{}    cmdFact.Signer, err = common.GetDefaultSignerFnc() //GetDefaultSignerFnc = GetDefaultSigner    cmdFact.BroadcastFactory = func() (common.BroadcastClient, error) {        return common.GetBroadcastClientFnc(orderingEndpoint, tls, caFile) //GetBroadcastClientFnc = GetBroadcastClient    }    //peer channel join或list需要endorser,本处暂未使用    if isEndorserRequired {        cmdFact.EndorserClient, err = common.GetEndorserClientFnc()    }    //peer channel create或fetch需要orderer    if isOrdererRequired {        var opts []grpc.DialOption        if tls {            if caFile != "" {                creds, err := credentials.NewClientTLSFromFile(caFile, "")                opts = append(opts, grpc.WithTransportCredentials(creds))            }        } else {            opts = append(opts, grpc.WithInsecure())        }        conn, err := grpc.Dial(orderingEndpoint, opts...)        client, err := ab.NewAtomicBroadcastClient(conn).Deliver(context.TODO())        cmdFact.DeliverClient = newDeliverClient(conn, client, chainID) //构造deliverClient    }    return cmdFact, nil}//代码在peer/channel/channel.go

1.2、发送创建区块链的交易

err = sendCreateChainTransaction(cf)//代码在peer/channel/create.go

sendCreateChainTransaction(cf)代码如下:

func sendCreateChainTransaction(cf *ChannelCmdFactory) error {    var err error    var chCrtEnv *cb.Envelope    if channelTxFile != "" { //peer channel create -f指定通道交易配置文件        chCrtEnv, err = createChannelFromConfigTx(channelTxFile) //获取创世区块    } else {        chCrtEnv, err = createChannelFromDefaults(cf) //没有指定通道交易配置文件    }    chCrtEnv, err = sanityCheckAndSignConfigTx(chCrtEnv) //检查和签名交易配置    var broadcastClient common.BroadcastClient    broadcastClient, err = cf.BroadcastFactory()    defer broadcastClient.Close()    err = broadcastClient.Send(chCrtEnv)    return err}//代码在peer/channel/create.go

1.3、获取创世区块并写入文件

var block *cb.Blockblock, err = getGenesisBlock(cf) //获取创世区块b, err := proto.Marshal(block) //块序列化err = ioutil.WriteFile(file, b, 0644) //写入文件//代码在peer/channel/create.go

2、peer channel join子命令实现(加入通道)

2.1、初始化Endorser客户端

cf, err = InitCmdFactory(EndorserRequired, OrdererNotRequired)//代码在peer/channel/join.go

2.2、构造ChaincodeInvocationSpec消息(cscc.JoinChain)

spec, err := getJoinCCSpec()invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}//代码在peer/channel/join.go

spec, err := getJoinCCSpec()代码如下:

func getJoinCCSpec() (*pb.ChaincodeSpec, error) {    gb, err := ioutil.ReadFile(genesisBlockPath)    input := &pb.ChaincodeInput{Args: [][]byte{[]byte(cscc.JoinChain), gb}}    spec := &pb.ChaincodeSpec{        Type:        pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]),        ChaincodeId: &pb.ChaincodeID{Name: "cscc"},        Input:       input,    }    return spec, nil}//代码在peer/channel/join.go

2.3、创建cscc Proposal并签名

creator, err := cf.Signer.Serialize()//从CIS创建Proposal,CIS即ChaincodeInvocationSpec//调用CreateChaincodeProposal(typ, chainID, cis, creator)//而后调用CreateChaincodeProposalWithTransient(typ, chainID, cis, creator, nil)prop, _, err = putils.CreateProposalFromCIS(pcommon.HeaderType_CONFIG, "", invocation, creator)var signedProp *pb.SignedProposalsignedProp, err = putils.GetSignedProposal(prop, cf.Signer)//代码在peer/channel/join.go

CreateChaincodeProposalWithTransient(typ, chainID, cis, creator, nil)代码如下:

func CreateChaincodeProposalWithTransient(typ common.HeaderType, chainID string, cis *peer.ChaincodeInvocationSpec, creator []byte, transientMap map[string][]byte) (*peer.Proposal, str    ing, error) {    //创建随机Nonce    nonce, err := crypto.GetRandomNonce()    //计算交易ID    //digest, err := factory.GetDefault().Hash(append(nonce, creator...),&bccsp.SHA256Opts{})    txid, err := ComputeProposalTxID(nonce, creator)    return CreateChaincodeProposalWithTxIDNonceAndTransient(txid, typ, chainID, cis, nonce, creator, transientMap)}//代码在protos/utils/proputils.go

CreateChaincodeProposalWithTxIDNonceAndTransient(txid, typ, chainID, cis, nonce, creator, transientMap)代码如下:

func CreateChaincodeProposalWithTxIDNonceAndTransient(txid string, typ common.HeaderType, chainID string, cis *peer.ChaincodeInvocationSpec, nonce, creator []byte, transientMap map[string][]byte) (*peer.Proposal, string, error) {    ccHdrExt := &peer.ChaincodeHeaderExtension{ChaincodeId: cis.ChaincodeSpec.ChaincodeId}    ccHdrExtBytes, err := proto.Marshal(ccHdrExt)    cisBytes, err := proto.Marshal(cis)    ccPropPayload := &peer.ChaincodeProposalPayload{Input: cisBytes, TransientMap: transientMap}    ccPropPayloadBytes, err := proto.Marshal(ccPropPayload)    var epoch uint64 = 0    timestamp := util.CreateUtcTimestamp()    hdr := &common.Header{ChannelHeader: MarshalOrPanic(&common.ChannelHeader{        Type:      int32(typ),        TxId:      txid,        Timestamp: timestamp,        ChannelId: chainID,        Extension: ccHdrExtBytes,        Epoch:     epoch}),        SignatureHeader: MarshalOrPanic(&common.SignatureHeader{Nonce: nonce, Creator: creator})}    hdrBytes, err := proto.Marshal(hdr)    return &peer.Proposal{Header: hdrBytes, Payload: ccPropPayloadBytes}, txid, nil}//代码在protos/utils/proputils.go

2.4、提交并处理Proposal

var proposalResp *pb.ProposalResponseproposalResp, err = cf.EndorserClient.ProcessProposal(context.Background(), signedProp)//代码在peer/channel/join.go

3、peer channel update(更新锚节点配置)

cf, err = InitCmdFactory(EndorserNotRequired, OrdererRequired)fileData, err := ioutil.ReadFile(channelTxFile)ctxEnv, err := utils.UnmarshalEnvelope(fileData)sCtxEnv, err := sanityCheckAndSignConfigTx(ctxEnv)var broadcastClient common.BroadcastClientbroadcastClient, err = cf.BroadcastFactory()defer broadcastClient.Close()return broadcastClient.Send(sCtxEnv)//代码在peer/channel

感谢关注兄弟连区块链教程分享!

转载于:https://blog.51cto.com/14041296/2313430

你可能感兴趣的文章