版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_32023305/article/details/81947667
-
简单实现
-
代码思路
-
具体代码(在简单区块链实现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{})
}
-
总结(思维导图)