go实现区块链[4]-遍历区块链与数据库持久化(下)

jonson_jackson · · 1089 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

遍历区块链

blockchain.go完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package main

import (
"github.com/boltdb/bolt"
"log"
"fmt"
)

const dbFile = "blockchain.db"
const blockBucket = "blocks"
type Blockchain struct{
tip []byte //最近的一个区块的hash值
db * bolt.DB
}


type BlockChainIterateor struct{
currenthash []byte
db * bolt.DB
}
func (bc * Blockchain) AddBlock(){
var lasthash []byte

err := bc.db.View(func(tx * bolt.Tx) error{
b:= tx.Bucket([]byte(blockBucket))
lasthash = b.Get([]byte("l"))
return nil
})
if err!=nil{
log.Panic(err)
}
newBlock := NewBlock(lasthash)


bc.db.Update(func(tx *bolt.Tx) error {
b:=tx.Bucket([]byte(blockBucket))
err:= b.Put(newBlock.Hash,newBlock.Serialize())
if err!=nil{
log.Panic(err)
}
err = b.Put([]byte("l"),newBlock.Hash)

if err!=nil{
log.Panic(err)
}
bc.tip = newBlock.Hash
return nil
})
}


func NewBlockchain() * Blockchain{
var tip []byte
db,err := bolt.Open(dbFile,0600,nil)
if err!=nil{
log.Panic(err)
}

err = db.Update(func(tx * bolt.Tx) error{

b:= tx.Bucket([]byte(blockBucket))

if b==nil{

fmt.Println("区块链不存在,创建一个新的区块链")

genesis := NewGensisBlock()
b,err:=tx.CreateBucket([]byte(blockBucket))
if err!=nil{
log.Panic(err)
}

err = b.Put(genesis.Hash,genesis.Serialize())
if err!=nil{
log.Panic(err)
}
err =  b.Put([]byte("l"),genesis.Hash)
tip = genesis.Hash

}else{
tip  =  b.Get([]byte("l"))
}

return nil
})

if err!=nil{
log.Panic(err)
}

bc:=Blockchain{tip,db}
return &bc
}

func (bc * Blockchain) iterator() * BlockChainIterateor{

bci := &BlockChainIterateor{bc.tip,bc.db}

return bci
}

func (i * BlockChainIterateor) Next() * Block{

var block *Block

err:= i.db.View(func(tx *bolt.Tx) error {
b:=tx.Bucket([]byte(blockBucket))
deblock := b.Get(i.currenthash)
block = DeserializeBlock(deblock)
return nil
})

if err!=nil{
log.Panic(err)
}

i.currenthash = block.PrevBlockHash
return block
}
func (bc * Blockchain) printBlockchain(){
bci:=bc.iterator()


for{
block:= bci.Next()
block.String()
fmt.Println()

//fmt.Printf("长度:%d\n",len(block.PrevBlockHash))
if len(block.PrevBlockHash)==0{
break
}

}

}

测试

1
2
3
4
5
6
7
8
9
10
func TestBoltDB(){
blockchain := NewBlockchain()
blockchain.AddBlock()
blockchain.AddBlock()
blockchain.printBlockchain()
}

func main(){
TestBoltDB()
}

第一次执行执行:

go build .
./buildingBlockChain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
区块链不存在,创建一个新的区块链
version:2
Prev.BlockHash:0000349e762f37b4f79f23c5270066cb2963610f5a6c999a846b781cec3152bc
Prev.merkleroot:
Prev.Hash:0000deb768a8e6c520081051d28756578c4c666bde404ff282d7a8e41a1e0107
Time:1544966755
Bits:404454260
nonce:13075

version:2
Prev.BlockHash:0000fdcb6bd475c8275ab47ac6d8d97ab2644ae33d574a914d36f9c1024099eb
Prev.merkleroot:
Prev.Hash:0000349e762f37b4f79f23c5270066cb2963610f5a6c999a846b781cec3152bc
Time:1544966755
Bits:404454260
nonce:142155

version:2
Prev.BlockHash:
Prev.merkleroot:
Prev.Hash:0000fdcb6bd475c8275ab47ac6d8d97ab2644ae33d574a914d36f9c1024099eb
Time:1544966755
Bits:404454260
nonce:105247

再次执行./buildingBlockChain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
version:2
Prev.BlockHash:0000c336d1f0284faac173c1d68ca196b3f2e94684d12f201b2610aca39acc7b
Prev.merkleroot:
Prev.Hash:0000a00ab59ad06d7c5d29e9769171676705c270d9edb1e5bd4b39da41e0d40c
Time:1544966858
Bits:404454260
nonce:67063

version:2
Prev.BlockHash:0000deb768a8e6c520081051d28756578c4c666bde404ff282d7a8e41a1e0107
Prev.merkleroot:
Prev.Hash:0000c336d1f0284faac173c1d68ca196b3f2e94684d12f201b2610aca39acc7b
Time:1544966858
Bits:404454260
nonce:69856

version:2
Prev.BlockHash:0000349e762f37b4f79f23c5270066cb2963610f5a6c999a846b781cec3152bc
Prev.merkleroot:
Prev.Hash:0000deb768a8e6c520081051d28756578c4c666bde404ff282d7a8e41a1e0107
Time:1544966755
Bits:404454260
nonce:13075

version:2
Prev.BlockHash:0000fdcb6bd475c8275ab47ac6d8d97ab2644ae33d574a914d36f9c1024099eb
Prev.merkleroot:
Prev.Hash:0000349e762f37b4f79f23c5270066cb2963610f5a6c999a846b781cec3152bc
Time:1544966755
Bits:404454260
nonce:142155

version:2
Prev.BlockHash:
Prev.merkleroot:
Prev.Hash:0000fdcb6bd475c8275ab47ac6d8d97ab2644ae33d574a914d36f9c1024099eb
Time:1544966755
Bits:404454260
nonce:105247

image.png


有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:jonson_jackson

查看原文:go实现区块链[4]-遍历区块链与数据库持久化(下)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1089 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传