【链块技术57期】超级账本源码分析: peer命令结构

原文链接:超级账本源码分析: peer命令结构

本文介绍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完整的命令结构:

peer

chaincode

instantiate

invoke

query

upgrade

package

install

signpackage

channel

join

create

fetch

list

clilogging

getlevel

Setlevel

Revertlevel

node

start

status

stop

version

 

 

1.3 Peer命令解析

peer模块位置在fabric/peer,目录结构如下:

 

【链块技术57期】超级账本源码分析: peer命令结构_第1张图片

目录结构很清晰,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-

【链块技术57期】超级账本源码分析: peer命令结构_第2张图片

【链块技术57期】超级账本源码分析: peer命令结构_第3张图片

 

你可能感兴趣的:(链块技术,区块链,超级账本)