区块链V3版本实现之一
部分代码(改写blockchain.go文件,修改获取区块的方式):
1 package main 2 3 import ( 4 "beijing_go_term2/bolt" 5 "fmt" 6 "log" 7 ) 8 9 //V1,V2版本 10 ////创建区块链,使用Block数组模拟 11 //type BlockChain struct { 12 // Blocks []*Block 13 //} 14 15 //V3版本 16 //使用bolt进行改写,需要2个字段 17 //1.bolt数据库的句柄 18 //2.最后一个区块的哈希值 19 type BlockChain struct { 20 //句柄 21 db *bolt.DB 22 //最后一个区块的哈希值 23 tail []byte 24 } 25 26 27 //实现创建区块链的方法 28 func NewBlockChain() *BlockChain { 29 ////V1,V2版本使用 30 ////在创建的时候添加一个区块:创世块 31 //genesisBlock := NewBlock(genesisInfo, []byte{0x0000000000000000}) 32 // 33 //bc := BlockChain{Blocks: []*Block{genesisBlock}} 34 //return &bc 35 36 //V3版本使用 37 //功能分析 38 //1.获得数据库的句柄,打开数据库,读写数据 39 //判读是否有buket,如果没有,创建bucket 40 //写入创世块 41 //写入1astHashKey这条数据 42 //更新tai1为最后一个区块的哈希 43 //返回bc实例 44 //2.获取最后一个区块的哈希值 45 //填充给tail 46 //返回bc实例 47 48 db, err := bolt.Open("blockChain.db", 0600, nil) 49 //向数据库中写入数据 50 //从数据库中读取数据 51 52 if err != nil { 53 log.Panic(err) 54 } 55 56 var tail []byte 57 58 db.Update(func(tx *bolt.Tx) error { 59 //所有的操作都在这里 60 61 b := tx.Bucket([]byte("blockBucket")) 62 63 if b == nil { 64 //如果b为空,说明名字为"blockChain"这个桶不存在,我们需要创建之 65 fmt.Printf("bucket不存在,准备创建!\n") 66 b, err = tx.CreateBucket([]byte("blockBucket")) 67 68 if err != nil { 69 log.Panic(err) 70 } 71 72 //添加创世块 73 genesisBlock := NewBlock(genesisInfo, []byte{}) 74 b.Put(genesisBlock.Hash,genesisBlock.Serialize()/*将区块序列化,转成字节流*/) 75 b.Put([]byte("lastHashKey"),genesisBlock.Hash) 76 77 ////区块数据读取,测试写入是否成功,成功就稍后注释 78 //blockInfo := b.Get(genesisBlock.Hash) 79 //block := Deserialize(blockInfo) 80 //fmt.Printf("解码后的block数据:%v\n",block) 81 82 tail = genesisBlock.Hash 83 }else { 84 tail = b.Get([]byte("lastHashKey")) 85 } 86 87 return nil 88 }) 89 90 return &BlockChain{db,tail} 91 }