共识算法之Pow工作量证明算法go语言实现

pow算法的简介
pow算法的代表性应用就是比特币系统,pow算法的原义是工作量证明算法,故名思意就是干多少活的证明。其实就是暴力求值,通过暴力循环 找到一个合适的哈希值,
这篇文中由详细的介绍

package main

import (
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"log"
	"math/big"
	"strconv"
	"time"
)

// 定义区块链的结构
type Block struct {
	LastHash  string //上一区块的哈希
	Hash      string //本区块的哈希值
	Data      string //数据
	TimeStamp string //时间戳
	Height    int    //区块高度
	Nonce     int64  //随机数
	DiffNum   uint   //难度值
}

// 简单的链式结构
var blockchain []Block

// 难度值
var diffNum uint = 17

// 挖矿函数即工作量证明算法
// 1.通过增大随机数的值 寻找适合的哈希值
// 2.类比比特币 寻找小于目标难度的哈希值
// 工作量证明算法的本质就是暴力求值 循环比较 直至找到符合要求的哈希值
func mine(data string) Block {
	// 定义区块
	if len(blockchain) < 1 {
		fmt.Println("没有区块头")
	}
	// 获取链上的最后一个区块
	lastBlock := blockchain[len(blockchain)-1]
	// 定义一个新的区块
	newBlock := new(Block)
	newBlock.LastHash = lastBlock.Hash
	newBlock.TimeStamp = time.Now().String()
	newBlock.Height = lastBlock.Height + 1
	newBlock.DiffNum = diffNum
	newBlock.Data = data
	var nonce int64 = 0
	newBigInt := big.NewInt(1)
	newBigInt.Lsh(newBigInt, 256-diffNum) // 相当于1 左移256-diffNum

	// 暴力计算
	for {
		newBlock.Nonce = nonce
		newBlock.getHash()
		hashInt := big.Int{}
		hashBytes, _ := hex.DecodeString(newBlock.Hash)
		hashInt.SetBytes(hashBytes) //将区块哈希值转大数字

		// 寻找合适的值
		// 比较x和y的大小。x<y时返回-1;x>y时返回+1;否则返回0
		if hashInt.Cmp(newBigInt) == -1 {
			break
		} else {
			nonce++ //递增随机数 直到找到合适的哈希值
		}
	}
	return *newBlock
}

//序列化
func (b *Block) serialize() []byte {
	bytes, err := json.Marshal(b)
	if err != nil {
		log.Panic(err)
	}
	return bytes
}

// 获取本区块的哈希值
func (b *Block) getHash() {
	result := sha256.Sum256(b.serialize())
	b.Hash = hex.EncodeToString(result[:])
}
func main() {
	// 新建一个区块头
	genesisBlock := &Block{
		TimeStamp: time.Now().String(),
		Data:      "创世区块",
		LastHash:  "0000000000000000000000000000000000000000000000000000000000000000",
		Height:    1,
		Nonce:     0,
		DiffNum:   0,
	}
	genesisBlock.getHash()
	fmt.Println(genesisBlock)
	//将创世区块添加进区块链
	blockchain = append(blockchain, *genesisBlock)
	for i := 0; i < 10; i++ {
		newBlock := mine("天气不错" + strconv.Itoa(i))
		blockchain = append(blockchain, newBlock)
		fmt.Println(newBlock)
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值