区块链之开发命令行操作模块


链接: 区块链项目github地址
项目目前进度:
在这里插入图片描述

功能介绍

利用命令行操作区块链相较于图形用户界面来说,编写代码简单,同时也可以实现复杂的功能。命令行模块的功能应该满足:
1.无任何参数输入:输出命令行支持功能信息
在这里插入图片描述

2.输入参数addBlock -data “Alice send 100 eth to Bob”:输出
在这里插入图片描述3.输入参数create:
创世区块未存在:输出创世区块信息
在这里插入图片描述创世区块已存在:输出提示
在这里插入图片描述4.输入参数printChain
在这里插入图片描述

go语言中flag用法简介

go语言通过flag获取命令行参数与命令行操作,其中步骤可以归为一下几步:
1.新建flagSet,需要传入命名参数

addBlockcmd := flag.NewFlagSet("addBlock", flag.ExitOnError)

2.参数默认值设置
"data"表示参数名称,"Alice send 100 eth to Bob"表示默认值,"add data to block"表示参数提示信息。

flagAddBlockArg := addBlockcmd.String("data", "Alice send 100 eth to Bob", "add data to block")

3.判断命令类型,并进行目标flag进行激活
os.args[1]表示命令的参数,os.args[0]为执行的文件名称,所以需要从下标为1开始判断。

switch os.Args[1] {
    
    
	case "addBlock":
		err := addBlockcmd.Parse(os.Args[2:])
		if err != nil {
    
    
			log.Panicf("parse the addBlockcmd failed%v\n", err)
		}
	}

4.判断被激活的flag有哪些,并执行目标函数
addBlockcmd.Parsed()判断flag是否被解析,addBlockcmd为flagset类型

	if addBlockcmd.Parsed() {
    
    
		if *flagAddBlockArg == "" {
    
    
			//未输入-data的参数
			PrintUsage()
			os.Exit(1)
		}
		cli.addBlock(*flagAddBlockArg)
	}

项目命令行具体实现

1.封装命令行类,降低各个模块之间的耦合性。

type CLI struct {
    
    
	BC *BlockChain
}

2.新建命令行提示符,在不清楚命令行用法的情况下,使用命令行进行提示

// 命令行提示用法展示
func PrintUsage() {
    
    
	fmt.Println("Usage:  go run file.exe <command> [arguments]")
	//初始化区块链
	fmt.Printf("\tcreate              create a new blockchain\n")
	//添加区块
	fmt.Printf("\taddBlock   -data  	 add a new block\n")
	//遍历区块链
	fmt.Printf("\tprintChain          print the all message of blockchain\n")
}

3.完成以上三个功能的函数编写

扫描二维码关注公众号,回复: 15383720 查看本文章
// 初始化区块链
func (cli *CLI) createBlockchain() {
    
    
	CreateBlockChainWithGenesisBlock()
}

// 添加区块
func (cli *CLI) addBlock(data string) {
    
    
	if !DBExist() {
    
    
		fmt.Printf("DB haven't existed")
		os.Exit(1)
	}
	block := BlockChainObject()
	block.AddBlock([]byte(data))
}

// 打印区块完整信息
func (cli *CLI) printChain() {
    
    
	if !DBExist() {
    
    
		fmt.Printf("DB haven't existed")
		os.Exit(1)
	}
	block := BlockChainObject()
	block.PrintBlockChain()
}

4.创建命令行运行接口函数run(),便于在主函数中运行。其中run()的具体思路如下:

  1. 建立flagSet
  2. 将有参数的flagSet的参数进行默认值设置
  3. 判断命令行字符串,并对相应的flag进行解析
  4. 对解析成功的flag,找到对应的函数并运行

这里相较于flag用法简介,新增了一个创世区块创建时的文件判断函数与命令行字符判断函数,如下:

// 参数数量检测函数
func IsValidArgs() {
    
    
//未输入任何功能需求
	if len(os.Args) < 2 {
    
    
		PrintUsage()
		os.Exit(1)
	}
}

os.Stat为go语言封装的一个获取文件信息的函数。若文件存在,则可以返回文件的各种信息,若文件不存在,则返回错误。可以利用返回的错误进行检测,判断文件是否存在。

// 判断数据库文件是否存在
func DBExist() bool {
    
    
	if _, err := os.Stat(dbName); os.IsNotExist(err) {
    
    
		//数据库文件不存在
		return false
	}
	return true
}

猜你喜欢

转载自blog.csdn.net/qq_45931661/article/details/128546327