我的区块链技术学习笔记(九):提供交互接口

到目前为止,我们说了很多,序列化持久化数据库,但是我们还没有提供一个与程序交互的接口:目前只是在 main 函数中简单执行了 NewBlockchain 和 bc.AddBlock 。是时候改变了

attachments-2018-01-2dsPH8kZ5a657b9660f3c.jpg
作者: Ivan Kuznetsov  吴寿鹤等

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

到目前为止,我们还没有提供一个与程序交互的接口:目前只是在 main 函数中简单执行了 NewBlockchain  bc.AddBlock 。是时候改变了!现在我们想要拥有这些命令:

blockchain_go addblock "Pay 0.031337 for a coffee"
blockchain_go printchain

所有命令行相关的操作都会通过 CLI 结构进行处理:

type CLI struct {
    bc *Blockchain
}

它的 “入口” 是 Run 函数:

func (cli *CLI) Run() {
    cli.validateArgs()

    addBlockCmd := flag.NewFlagSet("addblock", flag.ExitOnError)
    printChainCmd := flag.NewFlagSet("printchain", flag.ExitOnError)

    addBlockData := addBlockCmd.String("data", "", "Block data")

    switch os.Args[1] {
    case "addblock":
        err := addBlockCmd.Parse(os.Args[2:])
    case "printchain":
        err := printChainCmd.Parse(os.Args[2:])
    default:
        cli.printUsage()
        os.Exit(1)
    }

    if addBlockCmd.Parsed() {
        if *addBlockData == "" {
            addBlockCmd.Usage()
            os.Exit(1)
        }
        cli.addBlock(*addBlockData)
    }

    if printChainCmd.Parsed() {
        cli.printChain()
    }
}

我们会使用标准库里面的 flag 包来解析命令行参数:

addBlockCmd := flag.NewFlagSet("addblock", flag.ExitOnError)
printChainCmd := flag.NewFlagSet("printchain", flag.ExitOnError)
addBlockData := addBlockCmd.String("data", "", "Block data")

首先,我们创建两个子命令: addblock  printchain, 然后给 addblock 添加 -data 标志。printchain 没有任何标志。

switch os.Args[1] {
case "addblock":
    err := addBlockCmd.Parse(os.Args[2:])
case "printchain":
    err := printChainCmd.Parse(os.Args[2:])
default:
    cli.printUsage()
    os.Exit(1)
}

然后,我们检查用户提供的命令,解析相关的 flag 子命令:

if addBlockCmd.Parsed() {
    if *addBlockData == "" {
        addBlockCmd.Usage()
        os.Exit(1)
    }
    cli.addBlock(*addBlockData)
}

if printChainCmd.Parsed() {
    cli.printChain()
}

接着检查解析是哪一个子命令,并调用相关函数:

func (cli *CLI) addBlock(data string) {
    cli.bc.AddBlock(data)
    fmt.Println("Success!")
}

func (cli *CLI) printChain() {
    bci := cli.bc.Iterator()

    for {
        block := bci.Next()

        fmt.Printf("Prev. hash: %x\n", block.PrevBlockHash)
        fmt.Printf("Data: %s\n", block.Data)
        fmt.Printf("Hash: %x\n", block.Hash)
        pow := NewProofOfWork(block)
        fmt.Printf("PoW: %s\n", strconv.FormatBool(pow.Validate()))
        fmt.Println()

        if len(block.PrevBlockHash) == 0 {
            break
        }
    }
}

attachments-2018-01-aKUC5cbT5a657d93454c4.

func main() {
    bc := NewBlockchain()
    defer bc.db.Close()

    cli := CLI{bc}
    cli.Run()
}

注意,无论提供什么命令行参数,都会创建一个新的链。

这就是今天的所有内容了! 来看一下是不是如期工作:

$ blockchain_go printchain
No existing blockchain found. Creating a new one...
Mining the block containing "Genesis Block"
000000edc4a82659cebf087adee1ea353bd57fcd59927662cd5ff1c4f618109b

Prev. hash:
Data: Genesis Block
Hash: 000000edc4a82659cebf087adee1ea353bd57fcd59927662cd5ff1c4f618109b
PoW: true

$ blockchain_go addblock -data "Send 1 BTC to Ivan"
Mining the block containing "Send 1 BTC to Ivan"
000000d7b0c76e1001cdc1fc866b95a481d23f3027d86901eaeb77ae6d002b13

Success!

$ blockchain_go addblock -data "Pay 0.31337 BTC for a coffee"
Mining the block containing "Pay 0.31337 BTC for a coffee"
000000aa0748da7367dec6b9de5027f4fae0963df89ff39d8f20fd7299307148

Success!

$ blockchain_go printchain
Prev. hash: 000000d7b0c76e1001cdc1fc866b95a481d23f3027d86901eaeb77ae6d002b13
Data: Pay 0.31337 BTC for a coffee
Hash: 000000aa0748da7367dec6b9de5027f4fae0963df89ff39d8f20fd7299307148
PoW: true

Prev. hash: 000000edc4a82659cebf087adee1ea353bd57fcd59927662cd5ff1c4f618109b
Data: Send 1 BTC to Ivan
Hash: 000000d7b0c76e1001cdc1fc866b95a481d23f3027d86901eaeb77ae6d002b13
PoW: true

Prev. hash:
Data: Genesis Block
Hash: 000000edc4a82659cebf087adee1ea353bd57fcd59927662cd5ff1c4f618109b
PoW: true

test·

好了,一切搞定,下一篇我们将系统讨论交易环节,重头戏哦,哈哈!

上一篇:我的区块链技术学习笔记(八):区块链的数据库概述

下一篇:我的区块链技术学习笔记(十):交易初探

attachments-2018-01-KR3OuPgA5a62135b82784.jpg

  • 发表于 2018-01-22 13:44
  • 阅读 ( 1605 )
  • 分类:学习笔记

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
不写代码的码农
吴寿鹤

36 篇文章

作家榜 »

  1. 社区运营-小以 562 文章
  2. 社区运营-小链 244 文章
  3. 于中阳Mercina-zy 79 文章
  4. 涂晶 75 文章
  5. 李晓琼 44 文章
  6. 兄弟连区块链培训 42 文章
  7. 吴寿鹤 36 文章
  8. John-smith 25 文章