简介:
区块链技术是21世纪最具革命性的技术之一,其价值不断被发掘。从本质上讲,区块链是交易记录的一个分布式数据库。但是,与其他数据库不同,区块链不是一个私有数据库,而是一个公共的数据库。换句话说,任何使用这项技术的人,都可以拥有该数据的全备份。想要向该数据库添加数据记录,必须获得其他拥有该数据记录的人的共识通过。同时,正是区块链催生数字货币和智能合约的产生。
该系列文章将基于简单的区块链构建一个简化的加密货币。
区块:
在区块链中,区块是区块链的信息载体,区块保存着有价值的信息。例如,在加密货币中,区块用来保存数字货币的交易记录,同时区块可以保存诸如版权信息、资产证明、甚至重要影像等。同时,区块保存着一些技术关键信息:区块版本、时间戳、上一个区块的哈希、该区块哈希等。
在本文中我们将用go语言实现一个最简单的区块模型,该区块只保存一些最有意义的信息。它的结构如下图所示:
type Block struct {
TimeStamp int64//区块时间戳
Data []byte//区块数据
PreBlockHash []byte//上一个区块的哈希值
BlockHash []byte//该区块哈希值
}
既然有了简单的区块结构,那我们如何计算该区块的哈希呢。哈希计算是非常重要的,在区块链中正是哈希计算使得区块链不可修改。计算哈希值就是在解决一个非常大计算量的数学难题,它需要耗费极大的电脑算力。正是这种设计,使得向区块链中添加区块或者修改区块变得很难。
接下来我们用sha256-hash来计算区块哈希值:
func (block *Block) SetHash() {
timestamp := []byte(strconv.FormatInt(block.TimeStamp,10))
//时间戳转换为10进制字符串,并转换为字节
headers := bytes.Join([][]byte{block.PreBlockHash,block.Data,timestamp},[]byte(""))
hash := sha256.Sum256(headers)
block.BlockHash = hash[:]
}
区块链由一个个区块链接而成,那区块是如何产生的呢?接下来我们还需要完成一个简单区块新建的工作:
func NewBlock(data string, prevBlockHash []byte) *Block {
block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}}
block.SetHash()
return block
}
至此,我们的区块已经完成。
区块链:
从本质上讲,区块链是由区块有序链接的数据库。换句话说,区块一个一个插入在区块尾部,与前一个区块的由哈希相连。从这种结构中可以很容易得到最新的区块,并且可以由区块哈希很快确定对应区块。
在go语言中,这种结构可以很容易通过array或者map实现,由于不需要由哈希获取相应区块,因此我们选择array来实现区块链结构。
type BlockChain struct {
blocks []Block
}
那区块是如何加入区块链的呢?
func (bc *BlockChain) AddBlock(data string){
preBlockHash := bc.blocks[len(bc.blocks)-1].PreBlockHash
block := NewBlock(data,preBlockHash)
bc.blocks = append(bc.blocks, block)
}
但是这里又有一个问题,添加区块的时候我们需要获取前一个区块的哈希,那第一个区块如何加入区块链呢?所以,我们需要一个方法来创建第一个区块,在区块链中第一个区块也被称为创世区块:
func NewGenesisBlock() *Block {
return NewBlock("Genesis Block", []byte{})
}
最后,我们需要新建一个区块链:
func NewBlockChain() *BlockChain {
return &BlockChain{[]*Block{NewGenesisBlock()}}
}
至此为止,区块结构和区块链的简化结构已经完成。
我们来测试一下。
func main() {
bc := step1.NewBlockChain()
bc.AddBlock("a 给 b 转账 100 元")
bc.AddBlock("a 给 c 转账 50 元")
bc.AddBlock("b 给 c 转账 10 元")
for _, block :=range (bc.GetBlocks()) {
fmt.Printf("上一个区块的哈希:%x\n区块数据:%s\n区块哈希:%x\n", block.PreBlockHash, block.Data, block.BlockHash
)
}
测试结果如下:
上一个区块的哈希:
区块数据:Genesis Block
区块哈希:b73436c9eac49097341d4562c28ee226acfe16936d6658da02d75e8366893dc8
上一个区块的哈希:b73436c9eac49097341d4562c28ee226acfe16936d6658da02d75e8366893dc8
区块数据:a 给 b 转账 100 元
区块哈希:87cc0316be396377be281455ae5e72ea9b5fdc8e68d844c05c7d13b66ddc2d09
上一个区块的哈希:87cc0316be396377be281455ae5e72ea9b5fdc8e68d844c05c7d13b66ddc2d09
区块数据:a 给 c 转账 50 元
区块哈希:b7751b1342f0ae77863944d11c2bc4320651c15ace1c9b14675daa9676be61e1
上一个区块的哈希:b7751b1342f0ae77863944d11c2bc4320651c15ace1c9b14675daa9676be61e1
区块数据:b 给 c 转账 10 元
区块哈希:d95836c2710015688d47842355a102ba24506c1ad3a6e2dd6242175ce0fc162d
最简单的区块链模型完成!
网友评论