区块链数据如何持久化--博尔特数据库的运用以及之前代码工程的改造

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情

区块链数据如何持久化

第一篇文章:https://juejin.cn/post/7109829091540336647 接上文:https://juejin.cn/post/7110563538078269477 为了让区块链数据持久化,我们不再使用切片来存储区块链信息,而是将区块链数据存放在DB里,因此,Blockchain的生成过程中需要增加读写数据库的操作

我们应该怎么做

将区块链的每一个区块用hash作为key,区块数据作为val存储在bucket中,此外,始终用‘last’作为key记录最新区块的hash

1、Blockchain结构调整

```go //db文件名 const dbFile = "blockchain.db"

//数据库bucket名 const blocksBucket = "blocks"

// 区块链:一个区块的指针数组 type Blockchain struct { //记录最新块hash值 tip []byte //存放区块链的db db *bolt.DB } ```

2、借助gob对区块数据进行编码

gob使用时需要使用NewEnocder生成编码器encoder,然后使用encoder编码区块内存数据就可以了 ```go // 序列化区块 func (b *Block) Serialize() []byte { var result bytes.Buffer

//编码器
encoder := gob.NewEncoder(&result)
//编码
encoder.Encode(b)
return result.Bytes()

} ```

3、修改Blockchain方法

在获取bucket时,如果为空,代表创世块操作,代码中使用了两次Put,第一次是记录hash与数据,第二次是记录最新块的hash值,key为"last" ```go // 创建区块链结构,初始化只有创世块 func NewBlockchain() *Blockchain { var tip []byte //1.打开数据库文件 db, _ := bolt.Open(dbFile, 0600, nil) //2.更新数据库 db.Update(func(tx *bolt.Tx) error { //2.1 获取bucket buck := tx.Bucket([]byte(blocksBucket)) if buck == nil { //2.2.1 第一次使用,创建创世块 fmt.Println("No existing blockchain found. Creating a new one...") genesis := NewGenesisBlock() //2.2.2 区块数据编码 blockdata := genesis.Serialize() //2.2.3 创建新bucket,存入区块信息 bucket, _ := tx.CreateBucket([]byte(blocksBucket)) bucket.Put(genesis.Hash, blockdata) bucket.Put([]byte("last"), genesis.Hash) tip = genesis.Hash

} else {
        //2.3 不是第一次使用,之前有块
        tip = buck.Get([]byte("last"))
    }
    return nil
})
//3. 记录Blockchain 信息
return &Blockchain{tip, db}

} ```

4、修改添加区块的方法

增加区块的核心思想是打开数据库,获取最新的tip值,之后创建新的区块,并将其保存在数据库中。 go // 向区块链结构上增加一个区块 func (bc *Blockchain) AddBlock(data string) { var tip []byte //1. 获取tip值,此时不能再打开数据库文件,要用区块的结构 bc.db.View(func(tx *bolt.Tx) error { buck := tx.Bucket([]byte(blocksBucket)) tip = buck.Get([]byte("last")) return nil }) //2. 更新数据库 bc.db.Update(func(tx *bolt.Tx) error { buck := tx.Bucket([]byte(blocksBucket)) block := NewBlock(data, tip) //将新区块放入db buck.Put(block.Hash, block.Serialize()) buck.Put([]byte("last"), block.Hash) //覆盖tip值 bc.tip = block.Hash return nil }) }

5、总结

此时,区块链持久化就已经完成了,目前挖矿运转良好,但是区块链遍历还有一点问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值