比特币原理及其代码实践1-区块链数据结构
Jeiwan/blockchain_go: A simplified blockchain implementation in Golang (github.com)
https://gitee.com/Oracion/go-blockchain-learning
引言:
区块链本质只是一个分布式数据库
而已。
区块链具有去中心化(全节点保留所有区块)
、匿名(address(公私所生成的)和我本人没了联系)
、可追溯(UTXO)
、不可更改(merkleTree)
的特点
那么这些特点是如何实现的呢??
如果从原理和代码的角度,相信大家可以更好的理解这些特点。
区块链的开山之作,比特币
中本聪在2008年11月1日提出,并于2009年1月3日正式诞生,区块链也因此进入了人们的视野
区块链的层次结构
我们将实现最下面的三层
区块链结构
如果要我们自己设计区块链的数据结构
,应该如何设计:
- 指向前一个区块链的hash值
- 自己的hash值
- 时间戳
- 数据(交易信息)
数据结构-区块
//区块
type Block struct {
Timestamp int64 //时间戳
Data []byte //数据
PrevBlockHash []byte //前一个区块的hash
Hash []byte //自己的hash
}
其中,时间戳、前一个hash、自己的hash就被叫做区块的header
真实的比特币的区块比这个会再复杂一些,会多版本、挖矿难度、merkleTree的hash等字段
这些字段在之后的讲解中也会加上的,现在我们暂时不做那么复杂
区块需要实现的方法
//计算区块自己的hash值
//区块的hash= hash(PrevBlockHash + Data(交易的merkleTree的hash) + timestamp )
func (b *Block) SetHash() {
//伪代码
b.hash= sha256(PrevBlockHash + Data + timestamp)
}
可以看到,我们使用的hash函数是sha256
于是,我们有了新建区块的方法
//新建一个区块
func NewBlock(data string, prevBlockHash []byte) *Block {
//伪代码
block := &Block{now, data, prevBlockHash}
block.SetHash()
return block
}
数据结构-区块链
把区块连起来,就是区块链
链式结构的实现有两种方式:
- 数组
- 指针
我们先使用最简单的数组,之后的实现中会用到指针
//区块链
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 NewGenesisBlock() *Block {
return NewBlock("Genesis Block", []byte{})
}
//创建区块链
func NewBlockchain() *Blockchain {
return &Blockchain{[]*Block{NewGenesisBlock()}}
}
运行
func main() {
bc := NewBlockchain()
bc.AddBlock("Send 1 BTC to Ivan")
bc.AddBlock("Send 2 more BTC to Ivan")
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()
}
}
哈哈哈