page contents

Golang实现区块链教程--简单区块链

设计逻辑 区块设计区块哈希计算构建区块链添加区块到链中 区块 了解区块链,我们就得先了解它的块。在区块链中,块存储了一些信息,比如,区块所在的位置、区块创建的时间、区块存储的变...

attachments-2021-05-xAlxVzv760adb49a2508e.png

设计逻辑

  1. 区块设计
  2. 区块哈希计算
  3. 构建区块链
  4. 添加区块到链中


区块

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

  1. Index 区块位置索引
  2. TimeStamp 时间戳
  3. Data 存放的数据
  4. PrevBlockHash 前一个区块Hash值
  5. Hash 当前区块Hash值

区块结构代码

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


创建区块

下面我们来创建新的区块,即构建Block新对象。

func  NewBlock(index int64,data ,prevBlockHash []byte) *Block  {
block :=&Block{index,time.Now().Unix(),data,prevBlockHash,[]byte{}}
block.setHash() //设置当前区块Hash
return  block
}


设置哈希函数

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

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

下面我们实现它,首先把区块中的Index 、TimeStamp处理成字符串,然后和PrevBlockHash 拼接到一起,通过SHA-256构计算它们的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结果在当前块的Hash中
}


构建创世区块

首先我们说下生活中的火车,它是由火车头和一节一节的车厢组成。如果没有火车头,后面车厢也就无法行驶。在区块链中,为了能够构建一条区块链,我们也必须要一个“火车头”,就是第一个区块,这个区块就是“创世区块”。

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


区块链

区块链,顾名思义区块链就是一个一个有序的区块连接而成。它的本质就是一个一定结构的数据库。我们要特别注意前面的词“有序”。我们前面说过区块链就好像一个火车,在火车中链接每节车厢的是“铰链”,在区块链中它也有“铰链”来链接每个区块。这个“铰链”就是每个区块的当前Hash值。

定义区块链结构

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

type Blockchain struct {
  blocks []*Block
}

添加区块

我们首先把创世区块添加到区块链中,来引导后面的区块。

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)
}


运行

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

func main(){
bc :=NewBlockchain()
bc.AddBlock("Joy send 1 BTC to Jay")
bc.AddBlock("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("_____________________________")
}
}}

运行结果

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值来保证彼此的连接。但是我们还有很多没有实现,比如说区块验证、分叉主链选择、共识算法等。

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

如果你想用Python开辟副业赚钱,但不熟悉爬虫与反爬虫技术,没有接单途径,也缺乏兼职经验
关注下方微信公众号:Python编程学习圈,获取价值999元全套Python入门到进阶的学习资料以及教程,还有Python技术交流群一起交流学习哦。

attachments-2022-06-WdsJQ70v62ac1674a3d0c.jpeg

  • 发表于 2021-05-26 10:38
  • 阅读 ( 629 )
  • 分类:Golang

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1474 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章