区块链应用技术开发,区块链开发,超级账本,本文介绍fabric peer命令的结构。
一、Peer命令解析
1.1 前言
Peer节点是Fabric中处理交易和存储区块的重要角色,peer命令提供了很多命令供用户使用,比如创建通道、加入通道、安装和调用链码等等。我们后面很多文章会通过分析某些命令的执行流程来理解Fabric各个模块,本小节首先分析peer命令的结构。
1.2 Peer命令结构
Peer命令有四个子命令分别是channel、chaincode、clilogging、node,从字面意思上很好理解,比如channel子命令负责通道相关的操作,chaincode负责链码相关的操作。这些子命令都会被main函数调用, 因为main函数是程序的入口。从官方的实例中我们可以看出,peer命令的输入都是类似的格式,比如 peer channel …、peer node …、peer chaincode…,这种命令的风格是“命令 + 子命令 + 选项”,下图是peer完整的命令结构:

1.3 Peer命令解析
peer模块位置在fabric/peer,目录结构如下:

目录结构很清晰,peer目录下只有一个main文件,peer的子命令都在peer的子目录下,比chaincode、channel、clilogging等。
peer命令使用的是第三方包github.com/spf13/cobra,cobra是一个用于生成命令行程序的库, cobra基本用法如下:
1. 创建一个根命令对象,类型为Command,每个命令都是一个Command对象实例。创建一个命令对象就是实现和填充Command中的成员。
type Command struct {
Use string //命令的名称,比如在命令行敲peer version,这个字段就是“peer”
Short string
Long string
Run func(cmd *Command, args []string)
...
}
RootCmd := &cobra.Command{...}
例如fabric的peer命令的定义如下:
var mainCmd = &cobra.Command{
Use: "peer",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// check for CORE_LOGGING_LEVEL environment variable, which should override
// all other log settings
loggingSpec := viper.GetString("logging_level")
if loggingSpec == "" {
// if CORE_LOGGING_LEVEL not set, use the value for 'peer' from core.yaml
loggingSpec = viper.GetString("logging.peer")
}
flogging.InitFromSpec(loggingSpec)
return nil
},
Run: func(cmd *cobra.Command, args []string) {
if versionFlag {
fmt.Print(version.GetInfo())
} else {
cmd.HelpFunc()(cmd, args)
}
},
}
2. 为命令添加flag,也就是添加命令行选项,比如下面这个就是peer的主命令添加了一个version选项,各个用法类似于go的flag包。
mainFlags := mainCmd.PersistentFlags()
mainFlags.BoolVarP(&versionFlag, "version", "v", false, "Display current version of fabric peer server")
3. 添加子命令
mainCmd.AddCommand(version.Cmd())
mainCmd.AddCommand(node.Cmd())
mainCmd.AddCommand(chaincode.Cmd(nil))
mainCmd.AddCommand(clilogging.Cmd(nil))
mainCmd.AddCommand(channel.Cmd(nil))
4. 执行命令
if mainCmd.Execute() != nil {
os.Exit(1)
}
1.4 子命令解析
我们以node子命令为例来介绍:
1.在node.go中,首先定义了一个node命令对象,var nodeCmd = &cobra.Command{…}
// Cmd returns the cobra command for Node
func Cmd() *cobra.Command {
nodeCmd.AddCommand(startCmd())
nodeCmd.AddCommand(statusCmd())
return nodeCmd
}
var nodeCmd = &cobra.Command{
Use: nodeFuncName,
Short: fmt.Sprint(shortDes),
Long: fmt.Sprint(longDes),
}
2.在Cmd函数中,添加了start、stop、status三个子命令,子命令又分别在start.go,status.go,stop.go文件中实现。
3.在start.go中,首先定义了一个start命令对象,var nodeStartCmd = &cobra.Command{…},其中对RunE成员赋值了一个匿名函数,函数体中执行了serve函数,这也是该命令最终会调用的函数。如果我们在命令行中输入peer node start, 这个serve函数就会被调用,顾名思义serve会启动很多peer的服务。后面我们在分析serve函数具体细节。
1.5 总结
本章节主要介绍了fabric peer的命令处理方式,由于peer使用了cobra库,流程上跟cobra使用方法一致,下面一节我们会介绍peer node start命令的具体实现。
-END-
(未经授权,谢绝转载,版权最终解释权归链块学院所有)