区块链V3版本实现之四

部分代码(blockchain.go文件中改写addblock函数):

 1 //V3版本
 2 func (bc *BlockChain) AddBlock(data string) {
 3    bc.db.Update(func(tx *bolt.Tx) error {
 4       //所有的操作都在这里
 5 
 6       b := tx.Bucket([]byte("blockBucket"))
 7 
 8       if b == nil {
 9          fmt.Printf("bucket不存在,请检查!\n")
10          os.Exit(1)
11       }
12       block := NewBlock(data, bc.tail)
13       b.Put(block.Hash,block.Serialize()/*将区块序列化,转成字节流*/)
14       b.Put([]byte("lastHashKey"),block.Hash)
15 
16       bc.tail = block.Hash
17 
18       return nil
19    })
20 }

部分代码(blockchain.go文件中将数据修改为全局变量):

  1 package main
  2 
  3 import (
  4    "beijing_go_term2/bolt"
  5    "fmt"
  6    "log"
  7    "os"
  8 )
  9 
 10 //V1,V2版本
 11 ////创建区块链,使用Block数组模拟
 12 //type BlockChain struct {
 13 // Blocks []*Block
 14 //}
 15 
 16 //V3版本
 17 //使用bolt进行改写,需要2个字段
 18 //1.bolt数据库的句柄
 19 //2.最后一个区块的哈希值
 20 type BlockChain struct {
 21    //句柄
 22    db *bolt.DB
 23    //最后一个区块的哈希值,可以直接读取数据库,但是放在内存中更加方便
 24    tail []byte
 25 }
 26 
 27 const blockChainName = "blockChain.db"
 28 const blockBucketName = "blockBucket"
 29 const lastHashKey = "lastHashKey"
 30 
 31 //实现创建区块链的方法
 32 func NewBlockChain() *BlockChain {
 33    ////V1,V2版本使用
 34    ////在创建的时候添加一个区块:创世块
 35    //genesisBlock := NewBlock(genesisInfo, []byte{0x0000000000000000})
 36    //
 37    //bc := BlockChain{Blocks: []*Block{genesisBlock}}
 38    //return &bc
 39 
 40    //V3版本使用
 41    //功能分析
 42    //1.获得数据库的句柄,打开数据库,读写数据
 43       //判读是否有buket,如果没有,创建bucket
 44          //写入创世块
 45          //写入1astHashKey这条数据
 46          //更新tai1为最后一个区块的哈希
 47          //返回bc实例
 48    //2.获取最后一个区块的哈希值
 49       //填充给tail
 50       //返回bc实例
 51 
 52    db, err := bolt.Open(blockChainName, 0600, nil)
 53    //向数据库中写入数据
 54    //从数据库中读取数据
 55 
 56    if err != nil {
 57       log.Panic(err)
 58    }
 59 
 60    var tail []byte
 61 
 62    db.Update(func(tx *bolt.Tx) error {
 63       //所有的操作都在这里
 64 
 65       b := tx.Bucket([]byte(blockBucketName))
 66 
 67       if b == nil {
 68          //如果b为空,说明名字为"blockChain"这个桶不存在,我们需要创建之
 69          fmt.Printf("bucket不存在,准备创建!\n")
 70          b, err = tx.CreateBucket([]byte(blockBucketName))
 71 
 72          if err != nil {
 73             log.Panic(err)
 74          }
 75 
 76          //添加创世块
 77          genesisBlock := NewBlock(genesisInfo, []byte{})
 78          b.Put(genesisBlock.Hash,genesisBlock.Serialize()/*将区块序列化,转成字节流*/)
 79          b.Put([]byte(lastHashKey),genesisBlock.Hash)
 80 
 81          ////区块数据读取,测试写入是否成功,成功就稍后注释
 82          //blockInfo := b.Get(genesisBlock.Hash)
 83          //block := Deserialize(blockInfo)
 84          //fmt.Printf("解码后的block数据:%v\n",block)
 85 
 86          tail = genesisBlock.Hash
 87       }else {
 88          tail = b.Get([]byte(lastHashKey))
 89       }
 90 
 91       return nil
 92    })
 93 
 94    return &BlockChain{db,tail}
 95 }
 96 
 97 //V2版本
 98 ////添加区块
 99 //func (bc *BlockChain) AddBlock(data string) {
100 //
101 // //创建一个区块
102 // //bc.Block的最后一个区块的Hash值就是当前新区块的PrevBlockHash
103 // lastBlock := bc.Blocks[len(bc.Blocks) - 1]
104 // prevHash := lastBlock.Hash
105 //
106 // block := NewBlock(data, prevHash)
107 //
108 // //添加到bc.Block数组中
109 // bc.Blocks = append(bc.Blocks, block)
110 //
111 //}
112 
113 //V3版本
114 func (bc *BlockChain) AddBlock(data string) {
115    bc.db.Update(func(tx *bolt.Tx) error {
116       //所有的操作都在这里
117 
118       b := tx.Bucket([]byte(blockBucketName))
119 
120       if b == nil {
121          fmt.Printf("bucket不存在,请检查!\n")
122          os.Exit(1)
123       }
124       block := NewBlock(data, bc.tail)
125       b.Put(block.Hash,block.Serialize()/*将区块序列化,转成字节流*/)
126       b.Put([]byte(lastHashKey),block.Hash)
127 
128       bc.tail = block.Hash
129 
130       return nil
131    })
132 }

显示效果:(删除之前的bucket后,执行2次hash)

 

posted @ 2020-12-04 23:10  北漂的尘埃  阅读(104)  评论(0编辑  收藏  举报