Golang实现最简单的链

最近一直忙于伏羲也没怎么学别的东西···今天更一点东西,一起来看看一条最简单的区块链是如何实现的。

本文转载自:Wuman’s Blog

区块结构体

我们把一个区块看成一个结构体,用结构体来存储区块所需要的信息。

// 创建区块链结构体
type Block struct {
	Timer	int64	// 时间戳
	Data 	[]byte	// 数据
	prevHash[]byte	// 前一个区块的Hash
	Hash 	[]byte	// 本区块的Hash
}

在一个最简单的区块中,我们需要的最基本的属性有:

  • 时间戳
  • 区块数据
  • 前一个区块的Hash值
  • 本区块的Hash值

其中,除了时间戳外,我们均使用字节类型来定义。

创建一个区块

我们需要一些数据来创建一个区块(创世块会稍稍有区别)。

//创建区块
func NewBlock(data string, prevhash []byte) *Block {
	// 创建一个区块链结构体
	block1 := Block{}
	// 获取时间
	block1.Timer = time.Now().Unix()
	// 传入数据参数
	block1.Data = []byte(data)
	// 传入前一个Hash
	block1.prevHash = prevhash
	// setHash方法加密获得自己的Hash
	block1.setHash()
	// 返回区块指针
	return &block1
}

首先,我们需要区块所存储的数据内容data,还需要上一个区块的Hash,在创建完成之后,我们返回一个结构体类型的指针。

其中,我们使用的setHash方法是用来获取本区块Hash的。下面我们来看一看这个函数。

setHash函数

setHash用来给区块加密,来获取本区块的Hash值。

// 进行加密设置Hash
func (block *Block) setHash()  {
	// 首先将区块的时间转化为字符切片类型,便于加密
	time := []byte(strconv.FormatInt(block.Timer, 10))
	// 将数据,时间,前一个区块的Hash进行拼接
	heards := bytes.Join([][]byte{time, block.Data, block.prevHash}, []byte{})
	// sha256加密
	hash := sha256.Sum256(heards)
	// 加密后的Hash直接赋给本Hash
	block.Hash = hash[:]
}

在这里,我们通过sha256加密,对由时间戳、区块数据、上一个区块Hash组成的信息进行加密,将得到的Hash赋给本区块的Hash。

创世区块

创世区块由于没有前一个区块,我们就不需要使用前一个区块的Hash值了。

// 创建创世块
func Firstblock() *Block {
	// 传入参数,返回结构体指针
	firstblock := NewBlock("This is firstblock", []byte{})
	// 返回结构体指针类型
	return firstblock
}

main函数

我们在main函数里打印出区块的Hash

func main()  {
	firstblock := Firstblock()
	// 按照16进制打印
	fmt.Printf("%x",string(firstblock.Hash))
}

代码

package main

import (
	"bytes"
	"crypto/sha256"
	"fmt"
	"strconv"
	"time"
)

// 创建区块链结构体
type Block struct {
	Timer	int64	// 时间戳
	Data 	[]byte	// 数据
	prevHash[]byte	// 前一个区块的Hash
	Hash 	[]byte	// 本区块的Hash
}


// 进行加密设置Hash
func (block *Block) setHash()  {
	// 首先将区块的时间转化为字符切片类型,便于加密
	time := []byte(strconv.FormatInt(block.Timer, 10))
	// 将数据,时间,前一个区块的Hash进行拼接
	heards := bytes.Join([][]byte{time, block.Data, block.prevHash}, []byte{})
	// sha256加密
	hash := sha256.Sum256(heards)
	// 加密后的Hash直接赋给本Hash
	block.Hash = hash[:]
}

// 创建创世块
func Firstblock() *Block {
	// 传入参数,返回结构体指针
	firstblock := NewBlock("This is firstblock", []byte{})
	// 返回结构体指针类型
	return firstblock
}

//创建区块
func NewBlock(data string, prevhash []byte) *Block {
	// 创建一个区块链结构体
	block1 := Block{}
	// 获取时间
	block1.Timer = time.Now().Unix()
	// 传入数据参数
	block1.Data = []byte(data)
	// 传入前一个Hash
	block1.prevHash = prevhash
	// setHash方法加密获得自己的Hash
	block1.setHash()
	// 返回区块指针
	return &block1
}

func main()  {
	firstblock := Firstblock()
	// 按照16进制打印
	fmt.Printf("%x",string(firstblock.Hash))
}

打印结果

GOROOT=D:\Goland\Go #gosetup
GOPATH=D:\Goland\Gowork;D:\Goland\Go #gosetup
D:\Goland\Go\bin\go.exe build -o C:\Users\HP\AppData\Local\Temp\___go_build_running_go.exe D:/Goland/Gowork/src/main/running.go #gosetup
C:\Users\HP\AppData\Local\Temp\___go_build_running_go.exe #gosetup
0d00bc4d9ef291f3e0fe6ac36fa2a1a62e6f6e1939b191688bc18817bb96f1e9
Process finished with exit code 0
自认为是幻象波普星的来客
Built with Hugo
主题 StackJimmy 设计