fabric源码解读【peer channel】:创建通道

fabric源码解读:peer channel create

创建通道 源码路径:fabric/peer/channel/create.go


创建通道命令

CAFILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/suisui.com/orderers/orderer.suisui.com/msp/tlscacerts/tlsca.suisui.com-cert.pem
$ peer channel create -o orderer.suisui.com:7050 -c suichannel -f ./channel-artifacts/channel.tx --tls true --cafile $CAFILE

创建流程

fabric源码解读【peer channel】:创建通道_第1张图片

源码分析

/peer/channel/create.go

定义create子命令

func createCmd(cf *ChannelCmdFactory) *cobra.Command {
   createCmd := &cobra.Command{
      Use:   "create",
      Short: createCmdDescription,
      Long:  createCmdDescription,
      RunE: func(cmd *cobra.Command, args []string) error {
          // 执行创建func
         return create(cmd, args, cf)
      },
   }
   flagList := []string{
      "channelID",
      "file",
      "timeout",
   }
   attachFlags(createCmd, flagList)

   return createCmd
}
//创建通道命令
func create(cmd *cobra.Command, args []string, cf *ChannelCmdFactory) error {
	//the global chainID filled by the "-c" command
	if channelID == common.UndefinedParamValue {
		return errors.New("Must supply channel ID")
	}

	var err error
	if cf == nil {
		// 初始化命令行cf
		cf, err = InitCmdFactory(EndorserNotRequired, OrdererRequired)
		if err != nil {
			return err
		}
	}
	// 执行创建
	return executeCreate(cf)
}

创建通道并写入文件

//创建通道
func executeCreate(cf *ChannelCmdFactory) error {
	var err error
	//创建应用通道
	if err = sendCreateChainTransaction(cf); err != nil {
		return err
	}
	//获取创始块
	var block *cb.Block
	if block, err = getGenesisBlock(cf); err != nil {
		return err
	}
	//序列化
	b, err := proto.Marshal(block)
	if err != nil {
		return err
	}
	//写入文件
	file := channelID + ".block"
	if err = ioutil.WriteFile(file, b, 0644); err != nil {
		return err
	}

	return nil
}

初始化命令工厂

//根据是否需要背书节点 排序节点 初始化cmdfactory,各个子命令执行时会调用
func InitCmdFactory(isEndorserRequired EndorserRequirement, isOrdererRequired OrdererRequirement) (*ChannelCmdFactory, error) {
   var err error

   cmdFact := &ChannelCmdFactory{}
   //获取默认签名
   cmdFact.Signer, err = common.GetDefaultSignerFnc()
   if err != nil {
      return nil, fmt.Errorf("Error getting default signer: %s", err)
   }
   // 获取广播客户端方法
   cmdFact.BroadcastFactory = func() (common.BroadcastClient, error) {
      return common.GetBroadcastClientFnc()
   }

   // join list getinfo 需要背书节点
   if isEndorserRequired {
      // 获取背书节点客户端
      cmdFact.EndorserClient, err = common.GetEndorserClientFnc()
      if err != nil {
         return nil, fmt.Errorf("Error getting endorser client %s: %s", channelFuncName, err)
      }
   }

   //create fetch 需要order节点支持
   if isOrdererRequired {
      // 校验order节点地址
      if len(strings.Split(common.OrderingEndpoint, ":")) != 2 {
         return nil, fmt.Errorf("ordering service endpoint %s is not valid or missing", common.OrderingEndpoint)
      }
      // 创建分发客户端,用于向order节点请求消息
      cmdFact.DeliverClient, err = newDeliverClient(channelID)
      if err != nil {
         return nil, err
      }
   }
   logger.Infof("Endorser and orderer connections initialized")
   return cmdFact, nil
}

执行命令创建,并写入本地文件

//创建通道
func executeCreate(cf *ChannelCmdFactory) error {
   var err error
   //创建应用通道
   if err = sendCreateChainTransaction(cf); err != nil {
      return err
   }
   //获取创始块
   var block *cb.Block
   if block, err = getGenesisBlock(cf); err != nil {
      return err
   }
   //序列化
   b, err := proto.Marshal(block)
   if err != nil {
      return err
   }
   //写入文件
   file := channelID + ".block"
   if err = ioutil.WriteFile(file, b, 0644); err != nil {
      return err
   }

   return nil
}

发送创建通道消息

//发送创建通道交易  Envelope 类型
func sendCreateChainTransaction(cf *ChannelCmdFactory) error {
   var err error
   var chCrtEnv *cb.Envelope
   //检查通道tx文件
   if channelTxFile != "" {
      // 创建通道配置交易消息
      if chCrtEnv, err = createChannelFromConfigTx(channelTxFile); err != nil {
         return err
      }
   } else {
      if chCrtEnv, err = createChannelFromDefaults(cf); err != nil {
         return err
      }
   }
   //检查并签名消息
   if chCrtEnv, err = sanityCheckAndSignConfigTx(chCrtEnv); err != nil {
      return err
   }

   var broadcastClient common.BroadcastClient
   broadcastClient, err = cf.BroadcastFactory()
   if err != nil {
      return fmt.Errorf("Error getting broadcast client: %s", err)
   }

   defer broadcastClient.Close()
   // 发送到order
   err = broadcastClient.Send(chCrtEnv)

   return err
}

你可能感兴趣的:(区块链)