区块链V3版本实现之五

迭代器分析:

  作用:遍历容器,将数据逐个返回,防止一次性加载到内存,所以一点一点读取。

  类比于for循环里面的range

  区块链迭代器图示如下,最初指向最后一个区块,返回区块,指针前移,直至第一个区块。

 

 

部分代码(blockchain.go文件中定义和创建迭代器):

 1 //定义一个区块链的迭代器,包含db,current
 2 type BlockChainIterator struct {
 3    db *bolt.DB
 4    current []byte //当前所指向区块的哈希值
 5 }
 6 
 7 //创建迭代器,使用bc进行初始化
 8 func (bc *BlockChain) NewIterator() *BlockChainIterator {
 9    return &BlockChainIterator{bc.db,bc.tail}
10 }

部分代码(blockchain.go文件中迭代器Next函数实现):

 1 func (it *BlockChainIterator) Next() *Block {
 2 
 3    var block Block
 4 
 5    it.db.View(func(tx *bolt.Tx) error {
 6       b := tx.Bucket([]byte(blockBucketName))
 7       if b == nil{
 8          fmt.Printf("bucket不存在,请检查!\n")
 9          os.Exit(1)
10       }
11 
12       //真正读取数据
13       blockInfo /*block的字节流*/ := b.Get(it.current)
14       block = *Deserialize(blockInfo)
15 
16       it.current = block.PrevBlockHash
17       return nil
18    })
19 
20    return &block
21 }

部分代码(main.go文件中的代码改进):

 1 package main
 2 
 3 import (
 4    "bytes"
 5    "fmt"
 6    "time"
 7 )
 8 
 9 func main()  {
10    fmt.Printf("HelloWorld!!!\n")
11 
12    bc := NewBlockChain()
13    defer bc.db.Close()
14 
15    bc.AddBlock("hello")
16    bc.AddBlock("hello1")
17    bc.AddBlock("hello2")
18    bc.AddBlock("hello3")
19 
20    it := bc.NewIterator()
21 
22    //区块打印输出
23    for {
24       block := it.Next()
25       fmt.Printf("Version : %d\n", block.Version)
26       fmt.Printf("PrevBlockHash : %x\n", block.PrevBlockHash)
27       fmt.Printf("MerKleRoot : %x\n", block.MerKleRoot)
28 
29       timeFormat := time.Unix(int64(block.TimeStamp), 0).Format("2006-01-02 15:04:05")
30       fmt.Printf("TimeStamp : %s\n", timeFormat)
31 
32       fmt.Printf("Difficulity : %d\n", block.Difficulity)
33       fmt.Printf("Nonce : %d\n", block.Nonce)
34       fmt.Printf("Hash : %x\n", block.Hash)
35       fmt.Printf("Data : %s\n", block.Data)
36 
37       pow := NewProofOfWork(block)
38       fmt.Printf("IsValid : %v\n", pow.IsValid())
39 
40       //判断边界
41       if bytes.Equal(block.PrevBlockHash,[]byte{}){
42          fmt.Printf("区块链遍历结束!\n")
43          break
44       }
45    }
46 }

显示效果:

 

posted @ 2020-12-07 11:01  北漂的尘埃  阅读(83)  评论(0编辑  收藏  举报