主页 > imtoken钱包官网下载2.0 > GO语言实现区块链POW共识算法--pow算法实现

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

imtoken钱包官网下载2.0 2023-05-04 05:37:35

继续创造,加速成长!今天是我参加“掘金每日新计划·六月更新挑战赛”的第10天,点击查看活动详情

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

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

pow算法实现

比特币采用了PoW共识算法_挖比特币用什么算法_比特币算法作用

上面我们实现了区块链可以计算hash比特币采用了PoW共识算法,但是没有确定工作的难度(hash值只能获取一次)比特币采用了PoW共识算法,为了体现工作量,需要提高矿工的挖矿难度.

1.在block.go中添加Nonce字段

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

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

比特币采用了PoW共识算法_比特币算法作用_挖比特币用什么算法

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

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

3.创建pow结构

lsh 的目标是找到挖矿难度值。 思路是将target偏移256-targetiBits,这是基于二进制比较的思想。 有兴趣的可以去看看。 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 }

挖比特币用什么算法_比特币采用了PoW共识算法_比特币算法作用

4.编写挖矿逻辑

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

} //准备函数,使用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共识算法_挖比特币用什么算法_比特币算法作用

使用当前区块生成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[: ]) 返回 hashInt.Cmp(pow.target)==-1 }```

6.修改区块代码

我们不再需要SetHash,可以在NewBlock中完成,挖矿成功后的hash保存在区块结构中```go

比特币采用了PoW共识算法_挖比特币用什么算法_比特币算法作用

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

pow := NewProfOfWork(block) nonce, hash := pow.Run() //Set hash and nonce block.Hash = hash block.Nonce =int64( nonce) return block }

在 main.go 文件中,添加 print nonce value 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()

```