这篇文章使用Go语言实现简易区块链,通过这篇文章可以了解到:
- 区块的结构和作用
- Hash 算法的基本概念
- 如何构建区块链并添加新区块
一、设计逻辑
- 设计区块结构
- 实现区块的 Hash 计算
- 构建区块链
- 向区块链中添加新区块
区块信息
区块链的基本组成部分是区块。每个区块包含了以下信息:
- Index: 区块的位置索引
- TimeStamp: 区块创建的时间戳
- Data: 存放的数据
- PrevBlockHash: 前一个区块的 Hash 值
- Hash: 当前区块的 Hash 值
二、区块实现
1.区块结构代码
type Block struct {
Index int64
TimeStamp int64
Data []byte
PrevBlockHash []byte
Hash []byte
}
2.创建区块
我们可以使用以下方法来创建一个新的区块,也就是构建 Block
对象:
func NewBlock(index int64, data, prevBlockHash []byte) *Block {
block := &Block{index, time.Now().Unix(), data, prevBlockHash, []byte{}}
block.setHash() // 设置当前区块 Hash
return block
}
3.设置 Hash 函数
区块链采用 Hash 函数进行数据验证的原因包括:
- 计算 Hash 是困难的,增加了创建新区块的难度。
- 任何微小的数据变化都会导致 Hash 值的显著变化,从而保护区块的安全性。
- 每个区块的信息都依赖于当前区块的 Hash,节省存储空间。
实现 Hash 函数的方法如下:
func (b *Block) setHash() {
timestamp := []byte(strconv.FormatInt(b.TimeStamp, 10))
index := []byte(strconv.FormatInt(b.Index, 10))
headers := bytes.Join([][]byte{timestamp, index, b.PrevBlockHash}, []byte{})
hash := sha256.Sum256(headers)
b.Hash = hash[:] // 保存 Hash 结果
}
4.构建创世区块
如同火车需要一节火车头以引导后续的车厢,区块链也需要一个创世区块。
func NewGenesisBlock() *Block {
return NewBlock(0, []byte("first block"), []byte{})
}
三、链实现
区块链是一个有序连接区块的结构,可以视作一种特殊的数据存储。每个区块通过其 Hash 值彼此相连。
1.定义区块链结构
在 Go 语言中,我们可以使用切片来实现区块链:
type Blockchain struct {
blocks []*Block
}
2.添加区块
首先,将创世区块添加到区块链中以引导后续区块:
func NewBlockchain() *Blockchain {
return &Blockchain{[]*Block{NewGenesisBlock()}}
}
func (bc *Blockchain) AddBlock(data string) {
prevBlock := bc.blocks[len(bc.blocks)-1]
newBlock := NewBlock(prevBlock.Index+1, []byte(data), prevBlock.Hash)
bc.blocks = append(bc.blocks, newBlock)
}
3.调用
基本的区块链功能已实现,下面是如何展示区块链内容的代码:
func main() {
bc := NewBlockchain()
bc.AddBlock("Joy send 1 BTC to Jay")
bc.AddBlock("Jack sent 2 BTC to Jay")
for _, block := range bc.blocks {
fmt.Printf("Index : %d\n", block.Index)
fmt.Printf("TimeStamp: %d\n", block.TimeStamp)
fmt.Printf("Data: %s\n", block.Data)
fmt.Printf("PrevHash: %x\n", block.PrevBlockHash)
fmt.Printf("Hash: %x\n", block.Hash)
fmt.Println("_____________________________")
}
}
四、运行结果示例
Index : 0
TimeStamp: 1538560879
Data: first block
PrevHash:
Hash: 4f72e1adeaf4c2c3953465dea1d7224280014128f972554724fe93cf2c6760a7
_____________________________
Index : 1
TimeStamp: 1538560879
Data: Joy send 1 BTC to Jay
PrevHash: 4f72e1adeaf4c2c3953465dea1d7224280014128f972554724fe93cf2c6760a7
Hash: 070b089b9a7128dcfaca53258f004b3797e22c416c48faae1c6a3cefccc975c4
_____________________________
Index : 2
TimeStamp: 1538560879
Data: Jack sent 2 BTC to Jay
PrevHash: 070b089b9a7128dcfaca53258f004b3797e22c416c48faae1c6a3cefccc975c4
Hash: da1244af0658655ac8f82fec235acfe5dab47ce0f58b9afe75ac821c406c1dc6
_____________________________