go区块链教程 (go区块链需要掌握什么技能)

通过我们前边的讲解,我们已经生成了区块链,并可在区块链中增加区块,不过这些区块的只是通过简单的Hash运算获取hash值,这些哈希值太过随意,实际上我们需要在区块中使用的hash是有一定要求,并有生成的难度,这样的过程叫挖矿,在挖矿时,谁先生成符合要求的hash才能生成区块并加入区块链,并且在生成的区块中生成过程的工作还需要能够证明,下面我们来模拟下这个过程

用Visual Studio Code打开blockchain文件夹,找到blockchain/core文件夹,创建proofofwork.go文件,在文件中增加如下代码:

package core

import (

"crypto/sha256"

"math"

"math/big"

)

const difficulty = 4 //生成Hash难度定义,值越大难度越高

//ProofOfWork 定义工作证明结构

type ProofOfWork struct {

block *Block

target *big.Int

}

//NewProofOfWork 新建工作证明

func NewProofOfWork(block *Block) *ProofOfWork {

target := big.NewInt(1)

target.Lsh(target, uint(256-difficulty))

pow := &ProofOfWork{block, target}

return pow

}

//GetWrokResult 获取工作结果

func (pow *ProofOfWork) GetWrokResult() (int, []byte) {

var hashInt big.Int

var hash [32]byte

count := math.MaxInt64

nonce := 0

for nonce < count {

data := pow.block.CalculateHash(nonce)

hash = sha256.Sum256(data)

hashInt.SetBytes(hash[:])

if hashInt.Cmp(pow.target) == -1 {

break

} else {

nonce++

}

}

return nonce, hash[:]

}

//ValidateWork 验证工作结果

func (pow *ProofOfWork) ValidateWork() bool {

var hashInt big.Int

data := pow.block.CalculateHash(pow.block.Nonce)

hash := sha256.Sum256(data)

hashInt.SetBytes(hash[:])

isvalid := hashInt.Cmp(pow.target) == -1

return isvalid

}

添加后保存,我们需要修改block.go文件中计算哈希的方法和新建区块方法,不再简单计算哈希,而是交给工作证明方式来进行

go区块链代码,go区块链3.0

如上图,我们对calculateHash方法修改3个地方,修改为Block的内部方法,calculateHash的C字母大写修改为public方法,方法的参数修改为nonce,并在生成Block的hash参数时使用,最后注释生成hash方法,返回和成的data参数,这个方法在ProofOfWork 中的GetWrokResult和ValidateWork都有调用

go区块链代码,go区块链3.0

红色栏标记了,NewBlock方法修改的地方,注释了原哈希获取,创建工作证明,并获取工作证明后的hash值,nonce参数返回的数值为尝试生成符合规则的hash值的次数,修改blockchain.go文件中的Show方法,把区块中的Nonce显示出来

go区块链代码,go区块链3.0

我们再进入终端,go run main.go看下结果

go区块链代码,go区块链3.0

注意下Hash值和Nonce,哈希值的首位都是0,第一个区块的Nonce为22,意思就是尝试的22次才找到符合首位为0的哈希值,这个首位为0是在proofofwork.go文件中的const difficulty = 4参数来控制的,我们修改难度为8后再次尝试下

go区块链代码,go区块链3.0

可以看到结果,难度增加了,Hash值前2位都为0,第一个区块110次尝试才找到,第二个区块859次尝试才找到,我们再次修改难度为12要求生成的hash值必须前3位都是0,并验证这些生成区块中的Hash值是工作得到,并非伪造产生

go区块链代码,go区块链3.0

修个blockchain.go文件中的Show方法,显示验证的结果

go区块链代码,go区块链3.0

在mina方法中再增加2个区块,对比输出结果

go区块链代码,go区块链3.0

我们看到输出的结果上每个区块的Hash值前3位都是0,并且运行验证方法返回的也都是true,说明这些区块都是工作产生的,并非伪造添加,同时输出结果的时间也变长了,每个区块尝试的次数变大了,这样我们的区块就可以工作验证

Go语言知识点

1、go语言的函数可以返回多个参数,在函数方法中 { 前定义返回的参数类型,用(,)号分开多个参数即可在方法中返回,例如proofofwork.go文件中的获取工作结果方法GetWrokResult() (int, []byte) ,在这个方法中要获取到尝试的次数和找到的Hash值2个参数,所以定义了2个返回参数,我们在block.go文件中的NewBlock方法内通过

nonce, hash := pow.GetWrokResult() 的形式直接获取这二个参数使用

Go 从零开发区块链-区块链开发准备

Go 从零开发区块链-1、创建数据区块

Go 从零开发区块链-2、创建区块链