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

您所在的位置:网站首页 pow挖矿算法 GO语言实现区块链POW共识算法

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

2023-08-27 05:24| 来源: 网络整理| 查看: 265

持续创作,加速成长!这是我参与「掘金日新计划 · 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()

} ```



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3