Golang实现区块链(一)—简单区块链

随着比特币、以太坊等虚拟货币的越来越火,作为这些虚拟货币背后支撑的区块链技术,也被越来越多的人提及。下面我们将使用go语言对区块链进行探讨,并实现一个简易的区块链,本文暂不涉及poW、poS等共识算法。

通过本文,你可以做到:

  • 了解区块
  • Hash算法
  • 区块链的构建

Block/区块基础##

了解区块链,我们就得先了解它的块。在区块链中,块存储了一些信息,比如,区块所在的位置、区块创建的时间、区块存储的变量信息、区块的当前Hash值、以及上一个区块的Hash值等。

设计逻辑

  • 区块设计
  • 哈希计算
  • 生成新块
  • 构建区块链

区块结构代码

 type Block struct {
	Index  int64
	TimeStamp int64
	Data  []byte
	PrevBlockHash []byte
	Hash []byte
}

Hash算法

区块链使用的是Hash验证,那为什么使用Hash计算呢?

  1. 计算Hash非常困难,使在牛逼的计算机中也要花上一些时间计算出来,这样可以增加创建新块的难度。
  2. 只要区块的信息有任意一点变化,Hash值也会随着变化,下一个块Hash验证就通过不了,这就保证的区块的安全性。
    3.每个块上的信息,都存储在当前块的Hash上,这就节省了空间。

设置哈希函数

下面我们对区块信息进行hash加密

func (b *Block)CalHash()  {
	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[:]
}

创建区块

下面我们来创建新的区块

func  NewBlock(index int64,data ,prevBlockHash []byte) *Block  {
	block :=&Block{index,time.Now().Unix(),data,prevBlockHash,[]byte{}}
	block.CalHash()
	return  block
}

区块链

区块链,顾名思义区块链就是一个一个有序的区块连接而成。它的本质就是一个一定结构的数据库。我们要特别注意前面的词“有序”。

区块链抽象图

Golang实现区块链(一)—简单区块链

定义简单区块链

在golang里可以使用数组、map来实现,数组可以保证顺序,map实现hash->block组合的映射 不过,针对目前的进度,我们不需要实现能过hash找到区块的方法,所以这里只用数组来保证顺序即可。

	type Blockchain struct {
  blocks []*Block
}

构建创世区块

为了能创建区块链,我们必须要一个已经存在的区块,才能链下去。在区块链中,这个第一个区块,即是“创世区块”。

func NewGenesisBlock() *Block  {
	return  NewBlock(0,[]byte("first block"),[]byte{})
}
}

然后我们把这个创世区块添加到区块链中,来引导下面的区块。

func  NewBlockchain()*Blockchain  {
	return &Blockchain{[]*Block{NewGenesisBlock()}}
}

运行

基本的区块链功能我们已经实现,下面我们就开看看它的效果。

func main(){
	bc :=NewBlockchain()
	bc.AddBlock(bc.blocks[len(bc.blocks)-1].Index+1,"Joy send 1 BTC to Jay")
	bc.AddBlock(bc.blocks[len(bc.blocks)-1].Index+1,"Jakc 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("_____________________________")
	}
	                 nnnnnnnnnnnnnnnnnnnnnnnnnnnn
}

运行结果

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: Jakc sent 2 BTC to Jay
PrevHash: 070b089b9a7128dcfaca53258f004b3797e22c416c48faae1c6a3cefccc975c4
Hash: da1244af0658655ac8f82fec235acfe5dab47ce0f58b9afe75ac821c406c1dc6
_____________________________

总结

本篇文章介绍了怎么创建简单的区块链原型:只有一个数组来维护的链,每个块都拥有前一个块的hash值来保证彼此的连接。但是我们还有很多没有实现,比如说区块验证、分叉主链选择、共识算法等。