区块链V3版本实现思路
当前版本问题:
- 区块在内存中,每次执行完程序就释放,无法重用
- 创建区块不灵活,在main中写死,无法随意添加区块
V3版本思路:
- Bolt数据库介绍:轻量级、开源、go语言实现、key->value进行读取(map)[ ]byteè[ ]byte
- BlockChain结构重写
- NewBlockChain函数重写:由对数组操作改为对数据库操作,创建数据库
- AddBlock函数重写:对数据库的读取和写入
- 打印数据:对数据库的遍历(迭代器Iterator)
- 命令行:命令行介绍及编写;添加区块命令;打印区块命令;创建区块链’
Bolt数据库:
数据储存格式分析:
key唯一;
把所有的区块都写到一个bucket中:key -> value: []byte -> []byte
在bucket存储两种数据:
1. 区块,区块的哈希值作为key,区块的字节流作为value
block.Hash -> block.toBytes()
2.最后一个区块的哈希值
key使用固定的字符串:[]byte("lastHashKey"),value就是最后一个区块的哈希存储区块,使用的key必须唯一,所以使用区块的hash值作为key,block的字节流作为value.
具体存储格式:
添加一个新区块要做两件事情:
- 添加区块
- 更新last这个key对应的值,这个值就是最后一个区块的哈希值,用于新区块的创建添加。
部分代码(boltdemo.go文件中创建一个demo):
1 package main 2 3 import ( 4 "beijing_go_term2/bolt" //这个库在github上下载并导入就行 5 "fmt" 6 "log" 7 ) 8 9 func main() {10 db, err := bolt.Open("test.db", 0600, nil)11 //向数据库中写入数据12 //从数据库中读取数据13 14 if err != nil {15 log.Panic(err)16 }17 18 defer db.Close()19 20 db.Update(func(tx *bolt.Tx) error {21 //所有的操作都在这里22 23 b1 := tx.Bucket([]byte("bucketName1"))24 25 if b1 == nil {26 //如果b1为空,说明名字为"buckeName1"这个桶不存在,我们需要创建之27 fmt.Printf("bucket不存在,准备创建!\n")28 b1, err = tx.CreateBucket([]byte("bucketName1"))29 30 if err != nil {31 log.Panic(err)32 }33 }34 35 //bucket已经创建完成,准备写入数据36 //写数据使用Put,读数据使用Get37 err = b1.Put([]byte("name1"), []byte("Lily1111"))38 if err != nil {39 fmt.Printf("写入数据失败name1 : Lily!\n")40 }41 42 err = b1.Put([]byte("name2"), []byte("Jim1111"))43 if err != nil {44 fmt.Printf("写入数据失败name2 : Jim!\n")45 }46 47 //读取数据48 49 name1 := b1.Get([]byte("name1"))50 name2 := b1.Get([]byte("name2"))51 name3 := b1.Get([]byte("name3"))52 53 fmt.Printf("name1: %s\n", name1)54 fmt.Printf("name2: %s\n", name2)55 fmt.Printf("name3: %s\n", name3)56 57 58 return nil59 })60 61 }
显示效果:
赞 (0)