创建通道 源码路径: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
/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
}