工作量证明pow / go实现简易区块链 #3

in STEEM CN/中文2 years ago

混迹币圈的人一般都知道工作量证明pow,它就是计算一组数据的哈希值,这个哈希值要达到一定的要求,这也就是所谓的难度。比特币和以太坊都是使用工作量证明的方法,在理论和实际层面都经受了严酷的考验,到目前为目,是最为成功的算法了。

下面就是在前面的基础上加上工作量证明的方法,如下:

package main

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

type ProofOfWork struct {
    block *Block
    target *big.Int
}

const targetBits = 6  //难度值

func NewProofOfWork(block *Block) *ProofOfWork {
    target := big.NewInt(1)
    target.Lsh(target, uint(256-targetBits))

    pow := ProofOfWork{block: block, target: 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) {
    var hash [32]byte
    var nonce int64 = 0
    var hashInt big.Int

    for nonce < math.MaxInt64 {
        data := pow.PrepareData(nonce)

        hash = sha256.Sum256(data)  //计算哈希值
        hashInt.SetBytes(hash[:])

        if hashInt.Cmp(pow.target) == -1 {
            fmt.Printf("fond nonce,%d,%x", nonce, hash)
            break
        } else {
            nonce++

        }
    }
    return nonce, hash[:]
}

//验证
func (pow *ProofOfWork) IsValid() bool {
    var hashInt big.Int

    data := pow.PrepareData(pow.block.Nonce)
    hash := sha256.Sum256(data)
    hashInt.SetBytes(hash[:])

    return hashInt.Cmp(pow.target) == -1
}

工作量证明就是:穷举nonce值,计算出符合条件(前面是几个零)的哈希。因为哈希是一种随机运算,没有规律,只能穷举。所以,挖矿就要比拼算力啰!

Coin Marketplace

STEEM 0.28
TRX 0.12
JST 0.032
BTC 68321.15
ETH 3140.45
USDT 1.00
SBD 3.69