go区块链公链实战0x04cli命令行工具

我们在使用bitcoin客户端或者以太坊客户端时,都是可以在命令行直接执行挖矿,新增交易等操作。这些操作都有赖于cli工具,我们写的基于go的公链也会支持这个功能。所以,今天就学习实现简单的cli工具,以后再逐渐完善。

flag:go下的命令行解析包

常用的方法
//String defines a string flag with specified name, default value, and usage string.
//定义一个字符串的变量
type string string
func String(name string, value string, usage string) *string

//Int defines an int flag with specified name, default value, and usage string.
//定义一个int型变量
type int int
func Int(name string, value int, usage string) *int

//定义一个bool型变量
type bool bool
func Bool(name string, value bool, usage string) *bool

func Float64(name string, value float64, usage string) *float64

func Int64(name string, value int64, usage string) *int64

//在所有的变量参数被设置后需要进行一次解析才生效
func Parse()

//给指定的参数设置值
func Set(name, value string) error

//Flag结构体
type Flag struct {
        Name     string // name as it appears on command line
        Usage    string // help message
        Value    Value  // value as set
        DefValue string // default value (as text); for usage message
}
简单示例
//定义一个字符串变量,并制定默认值以及使用方式
    flagStr := flag.String("printchain", "", "输出所有区块信息")

    //定义一个int型字符 默认值为6
    flagInt := flag.Int("number", 6, "输出一个数")

    //定义一个bool型变量 默认值为false
    flagBool := flag.Bool("open", false, "判断真假")

    //flag解析
    flag.Parse()
    
    fmt.Printf("%s\n", *flagStr)
    fmt.Printf("%d\n", *flagInt)
    fmt.Printf("%v\n", *flagBool)
运行分析
flag简单使用
os.Args方法

go的os.Args方法可以获取用户在命令行输入的参数个数,跑个简单的🌰就知道它的用处了。

package main
import (
    "fmt"
    "os"
)

func main() {
    args := os.Args
    fmt.Printf("%v\n", args)
}

Run:

os.Args

不难发现,os.Args返回的是我们在命令行输入的参数数组,且顺序和输入顺序相同。

cli工具

我们之前写好的添加区块,打印区块链都必须在.go文件中写好,然后编译运行。我们想要实现的是编译之后在命令行输入诸如以下命令再进行操作:

//添加交易” chaors send 100btc to ww“到区块并进行挖矿
./main -addBlock "chaors send 100btc to ww"

//打印区块链的所有区块信息
./main -printchain

以” addBlock“为例,我们必须这样做来达到上述目的:
1.用flag设置addBlock命令
2. 用flag为addBlock命令设置参数
3.flag.Parse()解析参数
4.在解析中,调用区块链的新增区块方法新增区块

CLI结构
type CLI struct {
    //添加cli命令行工具的类
    Blockchain *Blockchain
}
当前所有方法的使用说明
//打印目前左右命令使用方法
func printUsage() {
    fmt.Println("Usage:")
    fmt.Println("\taddBlock -data DATA 交易信息   新增区块")
    fmt.Println("\tprintchain 打印所有区块信息")
}
参数合法性验证

由于要在main后使用诸如addBlock命令调用相应方法,所有参数必须多余1个。当参数小于2个时,提示当前命令使用方法。

func isValidArgs() {
        
        //获取当前输入参数个数
        if len(os.Args) < 2 {
        printUsage()
        os.Exit(1)
    }
}
cli命令的真正调用

要想实现区块的新增,必须是命令行输入命令触发了相应的新增区块方法才行。这里这样定义:

//新增区块
func (cli *CLI) addBlock(data string) {
    cli.Blockchain.AddBlockToBlockchain(data)

}

//打印区块链
func (cli *CLI) printchain() {
    cli.Blockchain.Printchain()
}
激活cli工具
func (cli *CLI) Run() {

    isValidArgs()

    //自定义cli命令
    addBlockCmd := flag.NewFlagSet("addBlock", flag.ExitOnError)
    printchainCmd := flag.NewFlagSet("printchain", flag.ExitOnError)

    //addBlockCmd 设置默认参数
    flagAddBlockData := addBlockCmd.String("data", "chaors", "交易数据")
    
    //解析输入的第二个参数是addBlock还是printchain,第一个参数为./main
    switch os.Args[1] {
    case "addBlock":
        //第二个参数为相应命令,取第三个参数开始作为参数并解析
        err := addBlockCmd.Parse(os.Args[2:])
        if err != nil {
            log.Panic(err)
        }
    case "printchain":
        err := printchainCmd.Parse(os.Args[2:])
        if err != nil {
            log.Panic(err)
        }
    default:
        printUsage()
        os.Exit(1)
    }

    //对addBlockCmd命令的解析
    if addBlockCmd.Parsed() {

        if *flagAddBlockData == "" {

            printUsage()
            os.Exit(1)
        }
        
        //这里真正地调用新增区块方法
        cli.addBlock(*flagAddBlockData)
    }
    //对printchainCmd命令的解析
    if printchainCmd.Parsed() {

        cli.printchain()
    }
}
cli测试
package main

import (

    "chaors.com/LearnGo/publicChaorsChain/part5-cli-Prototype/BLC"
)

func main() {
        
    //创建区块链
    blockchain := BLC.CreateBlockchainWithGensisBlock() 
    //创建命令行工具
    cli := BLC.CLI{blockchain}
    //激活cli
    cli.Run()
}

Run:

cli_1
cli_2

很显然,我们已经达到了预想的目的。当然,这还只是一个简陋的cli工具。以后,会随着go公链的开发进度而逐渐完善,今天就到这了。

源代码在这,喜欢的朋友记得给个小star,或者fork.也欢迎大家一起探讨区块链相关知识,一起进步!

.
.
.
.

互联网颠覆世界,区块链颠覆互联网!

---------------------------------------------20180624 23:40
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356

推荐阅读更多精彩内容