GO语言实现区块链POW共识算法- -pow算法实现

本文详细介绍了如何使用Go语言实现区块链的工作量证明(Proof-of-Work, POW)共识算法。通过增加Nonce字段并设定挖矿难度,创建pow结构体,编写挖矿逻辑与校验功能,确保区块的生成符合挖矿难度要求。在main.go中展示出nonce值和验证区块的正确性。
摘要由CSDN通过智能技术生成

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

GO语言实现区块链POW共识算法

上一篇:# GO语言实现区块链POW共识算法- -区块定义与数据串行化

pow算法实现

上文我们实现了区块链可以计算hash,但是没有确定工作难度(只需一次就可以得到hash值),为了体现工作量,需要给矿工增加挖矿难度。

1、在block.go中增加Nonce字段

go type Block struct { Timestamp int64 //时间戳 Data []byte //数据域 PrevBlockHash []byte //前一区块hash值 Hash []byte //当前区块hash Nonce int64 //随机值 }

2、创建pow.go文件,定义数据结构以及挖矿难度

```go var( //Nonce循环上限 maxNonce =math.MaxInt64 ) //难度值 const targetBits=24

//pow结构 type proOfWork struct { Block *Block target *big.Int } ```

3、创建pow结构

lsh的目标是求一个挖矿难度值,是想上是将target坐移256-targeiBits位,这要基于二进制的比较思想。有兴趣的可以查阅。 go func NewProfOfWork(b *Block)*proOfWork{ //target为最终难度值 target:=big.NewInt(1) //target为1向左位移256-24(挖矿难度) target.Lsh(target,uint(256-targetBits)) //生成pow结构 pow:=&proOfWork{b,target}\ return pow }

4、编写挖矿逻辑

```go //挖矿与运行 func (pow *proOfWork) Run() (int,[]byte) { var hashInt big.Int var hash [32]byte nonce :=0 fmt.Printf("pow数据:%s,maxNonce%d\n",pow.block.Data,maxNonce) for nonce

} //准备函数,使用Join完成字节切片的组合 func (pow *proOfWork) prepareData(nonce int64) []byte { data:=bytes.Join( [][]byte{ pow.block.PrevBlockHash, pow.block.Data, Int2Hex(pow.block.Timestamp), Int2Hex(int64(targetBits)), Int2Hex(nonce), }, []byte{}, ) return data } //组合时需要将Int转化为[]byte func Int2Hex(num int64) []byte { buff:=new(bytes.Buffer) binary.Write(buff,binary.BigEndian,num) return buff.Bytes() } ```

5、提供Pow校验功能

利用当前区块生成pow结构,校验hash是否符合挖矿难度 ```go

//校验区块正确性 func (pow *proOfWork) name()bool { var hashInt big.Int data:= pow.prepareData(pow.block.Nonce) hash:=sha256.Sum256(data) hashInt.SetBytes(hash[:]) return hashInt.Cmp(pow.target)==-1 } ```

6、修改block代码

我们不再需要SetHash了,完全可以在NewBlock中完成,将挖矿成功后的hash保存到block结构体中 ```go

func NewBlock(data string, prevBlockHash []byte) *Block { //先构造block block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}, 0} //需要先挖矿

pow := NewProfOfWork(block) nonce, hash := pow.Run() //设置hash和nonce block.Hash = hash block.Nonce =int64( nonce) return block }

main.go文件中,增加打印nonce值 go for _, block := range bc.Blocks { fmt.Printf("prev,hash:%x\n",block.PrevBlockHash) fmt.Printf("Data:%s\n",block.Data) fmt.Printf("Hash:%x\n",block.Hash) fmt.Printf("nonce:%d\n",block.Nonce) pow:=NewProfOfWork(block) fmt.Printf("Pow: %t\n", pow.Validate()) fmt.Println()

} ```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值