zoukankan      html  css  js  c++  java
  • 基于Go语言构建区块链:part1

    Golang语言和区块链理论学习完毕后,快速入门方法无疑是项目实战。本文将参考https://jeiwan.cc/tags/blockchain/教程,学习如何基于Go语言构建区块链。

    1、编程环境设置

    编程工具使用GoLand,前文已介绍软件安装经验。软件安装完成后,还需要设置工作路径“GOPATH”。在电脑上新建一个空白目录,然后点击点击Goland菜单按钮:“File”->“Settings”->"GO"->"GOPATH",添加自己的工作目录即可,还可以根据自己的喜好,设置不同的代码呈现颜色、字体、字号等。

    2、简化的block实现

    block结构如下所示:

    type Block struct {
       Timestamp     int64
       Data          []byte
       PrevBlockHash []byte
       Hash          []byte
    }

    Timestamp表示Block被创建的时间戳,Data表示block中实际的价值信息,PrevBlockHash
    表示上一个Blockhash值,Hash表示该block本身的Hash值。
    现在,我们首先SetHash方法,将Block中的字段信息组合后,
    生成该blockSHA-256 Hash值:
    // SetHash calculates and sets block hash
    func (b *Block) SetHash() {
       timestamp := []byte(strconv.FormatInt(b.Timestamp, 10))
       headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{})
       hash := sha256.Sum256(headers)
    
       b.Hash = hash[:]
    }
    接下来,实现NewBlock方法用于创建一个Block
    // NewBlock creates and returns Block
    func NewBlock(data string, prevBlockHash []byte) *Block {
       block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}}
       block.SetHash()
       return block
    }
    OKblock实现完成啦! 

    3、简化的blockchain实现

    本质上,blockchain仅仅是具备某种特殊结构的数据库:有序,反向链接链表。这意味着,block按照插入的顺序存放,同时每个block都保存指向上一block的链接。这种结构保证可以快速获取最新插入的block同时获取它的hash值。 

    Go语言中,可以通过slicemap来实现该结构。slice(有序)用于保存有序的hash值,map()用于保存hash->block对。对于我们的blockchain原型,目前不需要根据hash值来获取block因此仅仅使用slice可满足需求。blockchain结构如下: 

    type Blockchain struct {
       blocks []*Block
    }

    接下来,我们实现AddBlock方法,用于将block添加到blockchain中:
    // AddBlock saves provided data as a block in the blockchain
    func (bc *Blockchain) AddBlock(data string) {
       prevBlock := bc.blocks[len(bc.blocks)-1]
       newBlock := NewBlock(data, prevBlock.Hash)
       bc.blocks = append(bc.blocks, newBlock)
    }
    新增一个block的前提是另一个block已经存在,但是一开始blockchain中并没有任何block。因此,在任何blockchain中都必须有一个特殊的block存在,称之为GenesisBlock。下面实现NewGenesisBlock方法用于创建GenesisBlock
    func NewGenesisBlock() *Block {
       return NewBlock("Genesis Block", []byte{})
    }
    接下来,实现NewBlockchain方法,该方法会创建一个包含Genesis Blockblockchain
    func NewBlockchain() *Blockchain {
       return &Blockchain{[]*Block{NewGenesisBlock()}}
    }

    4、测试Blockchain是否可以正常工作

    func main() {
    bc := NewBlockchain()
    
    bc.AddBlock("Send 1 BTC to Ivan")
    bc.AddBlock("Send 2 more BTC to Ivan")
    
    for _, block := range bc.blocks {
    fmt.Printf("Prev. hash: %x
    ", block.PrevBlockHash)
    fmt.Printf("Data: %s
    ", block.Data)
    fmt.Printf("Hash: %x
    ", block.Hash)
    fmt.Println()
    }
    }


    若直接选择RUN 'go build main.go',会出现如下报错:

    # command-line-arguments
    .main.go:8:8: undefined: NewBlockchain
    
    Compilation finished with exit code 2

    这是因为“block.go”和“blockchain.go”没有同时编译。选择整个项目“Blockchain”选择Run 'go build Blockchain'即可成功,结果如下:

    Prev. hash: 
    Data: Genesis Block
    Hash: aa6085b7b44bcc1d878c6a28a3d98a665f8e1522da8093defee6a61e06aeac67
    
    Prev. hash: aa6085b7b44bcc1d878c6a28a3d98a665f8e1522da8093defee6a61e06aeac67
    Data: Send 1 BTC to Ivan
    Hash: 835c7514ce8b54b83add05c41977bf5f50dfec7791e12e6912feb1d9c286f7b4
    
    Prev. hash: 835c7514ce8b54b83add05c41977bf5f50dfec7791e12e6912feb1d9c286f7b4
    Data: Send 2 more BTC to Ivan
    Hash: cfbd89e2384d7caabc7ff58ed0a27a5172a18fc381b0b87d990e989d55b98ecd

    Process finished with exit code 0
     



  • 相关阅读:
    SSHkey的申请
    版本控制系统-集中式VS分布式(分享)
    01-OC中数组NSArray的遍历
    第4周小组作业:WordCount优化
    第2周作业1:开设博客
    第2周个人作业:WordCount
    测试课程总结2017
    优秀博客的评比结果及相关说明
    静态代码检查工具简介
    Selenium安装中的一些问题及解决办法-软硕1703班3组整理分享
  • 原文地址:https://www.cnblogs.com/yxdz-hit/p/8516555.html
Copyright © 2011-2022 走看看