在实现PoW算法之前,需要搭建基本的区块链,不然挖矿没有目标。下面将比特币的基本结构简化,设计一个最简单的区块结构,在使用切片来存储产生的区块,并用hash联系起来。
1、定义Block结构。
创建PoW目录,新建block.go文件:
type Block struct {
Timestamp int64
Data []byte
PrevBlockHash []byte
Hash []byte
}
2、区块计算hash。
func (b *Block) SetHash() {
timestamp := []byte(strconv.FormatInt(b.Timestamp, 10))
headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{})
hash := sha256.Sum256(headers)
b.Hash = hash[:]
}
3、创世块创建。
func NewBlock(data string, prevBlockHash []byte) *Block {
block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}}
block.SetHash()
return block
func NewGenesisBlock() *Block {
return NewBlock("Genesis Block", []byte{})
}
以上是block.go的编写。
4、创建blockchain.go文件实现区块链功能。区块链使用一个Block指针类型的切片来实现。
package main
type Blockchain struct {
blocks []*Block
}
func (bc *Blockchain) AddBlock(data string) {
prevBlock := bc.blocks[len(bc.blocks)-1]
newBlock := NewBlock(data, prevBlock.Hash)
bc.blocks = append(bc.blocks, newBlock)
}
func NewBlockchain() *Blockchain {
return &Blockchain{[]*Block{NewGenesisBlock()}}
}
5、测试。
创建test.go文件
package main
import (
"fmt"
)
func main() {
bc := NewBlockchain()
bc.AddBlock("Send 1 BTC to 喜羊羊")
bc.AddBlock("Send more 2 BTC to 灰太狼")
for _, block := range bc.blocks {
fmt.Printf("Prev.hash : %x\n", block.PrevBlockHash)
fmt.Printf("Data : %s\n", block.Data)
fmt.Printf("Hash : %x\n", block.Hash)
fmt.Println()
}
}
运行test.go
结果如下: