294-BitCoin全攻略七_工作量证明










BitCoin全攻略七_工作量证明







我们已经把最简单的区块链的大体框架写好了
现在我们来写工作量证明
也就是俗称的挖矿

挖矿的原理就是根据自身的数据
计算出一个哈希值
每次计算Nonce值加一
一直算到比目标值小的时候
挖矿就成功了




我们创建一个proofofwork.go文件

来个结构体

type ProofOfWork struct{

	block Block

	target big.Int

}




然后我们写一个函数创建

我们这里暂时先写死一个难度值
0001000000000000000000000000000000000000000000000000000000000000

func NewProofOfWork(block Block) (*ProofOfWork){

	targetStr = "0001000000000000000000000000000000000000000000000000000000000000"
	
	bigIntTemp := big.Int{}

	bigIntTemp.setString(targetStr, 16)

	pow := ProofOfWork{
		block: block,
		target: bigIntTemp,
	}

	return &pow
}






然后我们写一个计算的方法
这里我们先写个TODO
等下再来完善Run方法
func (pow *ProofOfWork) Run() (nonce uint64, hash []byte) {

	return 100,[]byte{}

}







然后我们想一下,工作量证明应该在哪里进行呢
应该是在创建区块的时候
因为我们挖矿成功了
才能得到Nonce,才能得到区块

所以我们改一下NewBlock

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

	timeStamp := uint64(time.Now().Unix())

	block := Block{
		PrevBlockHash: prevBlockHash,
		Hash:          nil,
		Data:          data,
		Version:       version,
		MerkleRoot:    nil,
		TimeStamp:     timeStamp,
		Bits:          0,
		Nonce:         0,
	}

	pow := NewProofOfWork(block)
	nonce, hash := pow.Run()

	block.Nonce = nonce
	block.Hash = hash

	return &block
}







我们看下完整代码

先看下block.go文件

package main

import (
	"crypto/sha256"
	"bytes"
	"encoding/binary"
	"time"
)

const version = 1

type Block struct {
	//1.前区块哈希值
	PrevBlockHash []byte

	//2.当前区块的哈希
	Hash []byte

	//3.数据
	Data []byte

	//4.版本
	Version uint64

	//5.梅克尔根哈希
	MerkleRoot []byte

	//6.时间戳
	TimeStamp uint64

	//7.难度值
	Bits uint64

	//8.随机数Nonce
	Nonce uint64
}

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

	timeStamp := uint64(time.Now().Unix())

	block := Block{
		PrevBlockHash: prevBlockHash,
		Hash:          nil,
		Data:          data,
		Version:       version,
		MerkleRoot:    nil,
		TimeStamp:     timeStamp,
		Bits:          0,
		Nonce:         0,
	}

	pow := NewProofOfWork(block)
	nonce, hash := pow.Run()

	block.Nonce = nonce
	block.Hash = hash

	return &block
}

func getHash(block *Block) []byte {

	version := Uint64ToBytes(block.Version)
	timeStamp := Uint64ToBytes(block.TimeStamp)
	bits := Uint64ToBytes(block.Bits)
	nonce := Uint64ToBytes(block.Nonce)

	var info []byte
	info = append(info, block.PrevBlockHash...)
	info = append(info, block.Data...)
	info = append(info, version...)
	info = append(info, block.MerkleRoot...)
	info = append(info, timeStamp...)
	info = append(info, bits...)
	info = append(info, nonce...)

	hash := sha256.Sum256(info)
	return hash[:]
}

func Uint64ToBytes(i uint64) []byte {
	var buffer bytes.Buffer
	err := binary.Write(&buffer, binary.BigEndian, i)
	if err != nil {
		panic(err)
	}
	return buffer.Bytes()
}






然后proofofwork.go文件

package main

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

type ProofOfWork struct {
	//1.区块
	block Block

	//2.目标值
	target big.Int
}

func NewProofOfWork(block Block) (*ProofOfWork) {

	targetStr := "0001000000000000000000000000000000000000000000000000000000000000"

	bigIntTemp := big.Int{}
	bigIntTemp.SetString(targetStr, 16)

	pow := ProofOfWork{
		block:  block,
		target: bigIntTemp,
	}

	return &pow
}

func (pow *ProofOfWork) Run() (nonce uint64, hash []byte) {


}




 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值