区块链工作量证明

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_32023305/article/details/81947667

  • 简单实现

 

  1. 代码思路

  2. 具体代码(在简单区块链实现https://blog.csdn.net/sinat_32023305/article/details/82021024中改进)

proofOfWork.go

package main

import (
	"math/big"
	"bytes"
	"math"
	"crypto/sha256"
	"fmt"
)

type ProofOfWork struct {
	block *Block
	//目标值
	target *big.Int
}

const targetBits  = 24
func NewProofOfWork(block *Block) *ProofOfWork{
	//000000000000000....01
	target := big.NewInt(1)
	//0x000000100000000000  16进制
	target.Lsh(target,256-targetBits)

	pow := ProofOfWork{block,target}
	return &pow
}
//拼装数据
func (pow *ProofOfWork)PrepareData(nonce int64) []byte{
	block := pow.block
	tmp := [][]byte{
		IntToByte(block.Version),
		block.PrevBlockHash,
		block.MerKelRoot,
		IntToByte(block.TimeStamp),
		IntToByte(targetBits),
		IntToByte(nonce),
		block.Data}
	data := bytes.Join(tmp,[]byte{})
	return data
}

func (pow *ProofOfWork)Run()(int64,[]byte){
	//1. 拼装数据
	//2. 哈希值转成big.Int类型
	/*
		for nonce{
			hash := sha256(block数据 + nonce)
			if 转换(hash) < pow.target {
				找到了
			}else{
				nonce++
			}
		}
		return nonce, hash[:]
	*/
	var nonce int64 = 0
	var hash [32]byte
	var hashInt big.Int

	fmt.Println("Begin Mining...")
	fmt.Printf("target hash: %x\n",pow.target.Bytes())
	for nonce < math.MaxInt64{
		data := pow.PrepareData(nonce)
		hash = sha256.Sum256(data)
		hashInt.SetBytes(hash[:])
		if hashInt.Cmp(pow.target) == -1 {
			fmt.Printf("found hash : %x, nonce : %d\n", hash, nonce)
			break
		}else {
			nonce++
		}
	}
	return  nonce,hash[:]
}

func (pow *ProofOfWork)IsVaild()bool{
	var hashInt big.Int
	data := pow.PrepareData(pow.block.Nonce)
	hash := sha256.Sum256(data)
	hashInt.SetBytes(hash[:])
	return  hashInt.Cmp(pow.target) == -1
}

block.go

package main

import (
	"time"
)

type Block struct {
	Version int64
	PrevBlockHash []byte
	Hash []byte
	MerKelRoot []byte
	TimeStamp int64
	Bits int64
	Nonce int64

	Data []byte
}

func NewBlock(data string,prevBlockHash []byte) *Block{

	var block Block
	block = Block {
		Version:1,
		PrevBlockHash:prevBlockHash,
		MerKelRoot: []byte{},
		TimeStamp:time.Now().Unix(),
		Bits:targetBits,
		Nonce:0,
		Data:[]byte(data)}
		//block.SetHash()
	pow :=NewProofOfWork(&block)
	nonce,hash := pow.Run()
	block.Nonce = nonce
	block.Hash = hash
	return &block
}
func NewGenesisBlock() *Block{
	return NewBlock("Genesis Block",[]byte{})
}
  • 总结(思维导图)

猜你喜欢

转载自blog.csdn.net/sinat_32023305/article/details/81947667