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 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()
if len(block.PrevBlockHash)==0{ break }
}
}
|