3.存储和遍历
现在我们想要把区块存储进数据库中并且根据需要遍历某个区块的信息
3.1区块的存储
这里我们采用Go语言自带的数据库,如果在安装Go语言时没有安装,则需要通过如下链接安装
go get github.com/boltdb/bolt
安装成功后才能实现区块的存储和遍历
我们用键值对来实现对区块的存储,key:当前区块的哈希,value:当前区块序列化后的数组。当然遍历时我们就需要进行反序列化以还原区块信息,现在我们一并构建这它们
/Users/xxx/go/src/publicChain/part15-persistence/BLC/Block.go
//SerializeBlock
func (block *Block) Serialize() []byte {
var result bytes.Buffer
encoder := gob.NewEncoder(&result)
err := encoder.Encode(block)
if err != nil {
log.Panic(err)
}
return result.Bytes()
}
//DeserializeBlock
func DeserializeBlock(blockBytes []byte) *Block {
var block Block
decoder := gob.NewDecoder(bytes.NewReader(blockBytes))
err := decoder.Decode(&block)
if err != nil {
log.Panic()
}
return &block
}
在此之前,我们会将新产生的区块加入到链上,现在我们重新改写一下:在这里我们将会把新产生的区块存入数据库中的数据表里。事实上,只要一个区块的产生依赖于上一个区块,那这些区块自动就是一条“区块链”,所以并不需要我们再重构一条链,我们只需要通过一定的方式处理这些区块即可。前面所说的把一个个区块加入到“链”上其实就是一种处理方式,现在我们把这种方式改变一下,也就是说直接把区块装入数据库中。下面是实现代码:
/Users/xxx/go/src/publicChain/part15-persistence/BLC/Blockchain.go
const dbName = "blockChain.db"
const blockTableName = "blocks"
type Blockchain struct {
Tip []byte //the hash of current block
DB *bolt.DB //database
}
//add a new block to blockchain
func (blc *Blockchain) AddBlockToBlockchain(data string) {
err := blc.DB.Update(func(tx *bolt.Tx) error {
//get a table
b := tx.Bucket([]byte(blockTableName))
//crate a new block
if b != nil {
//Get the latest block
blockBytes := b.Get(blc.Tip)
//Deserialize
block := DeserializeBlock(blockBytes)
//Serialize the block and store it in the database