• [GO]使用go语言实现比特币的工作量证明


    之前的博文已经实现了区块连的基本的工作原理,但在比特币系统中有一个很重要的概念:工作量证明POW,在比特币系统中它的作用就是在十分钟左右的时间内只有一个有能够记帐并得到奖励

    在之前的博文中,区块的哈希值是我自己创建的,那么在这里需要将原区块函数更改为以下的样子

    func NewBlock(data string, prevBlockHash []byte) *Block {
        //initial block data
        block := &Block{
            Version:1,
            PreBlockHash:prevBlockHash,
            //Hash:[]
            TimeStamp:time.Now().Unix(),
            TargetBits:targetBits,
            Nonce:0,
            MerkelRoot:[]byte{},
            Data:[]byte(data),
        }
        //block.SetHash() //get block hash
        pow := NewProofOfWork(block)
        nonce, hash := pow.Run()
        block.Nonce = nonce
        block.Hash = hash
        return block
    }

    新建一个工作证明proofofwork.go的文件

    package main
    
    import (
        "math/big"
        "bytes"
        "math"
        "crypto/sha256"
        "fmt"
    )
    
    const targetBits  = 24
    
    type ProofOfWork struct {
        block     *Block
        targetBit *big.Int
    }
    
    func NewProofOfWork(block *Block) *ProofOfWork {
        var IntTarget = big.NewInt(1)
        IntTarget.Lsh(IntTarget, uint(256 - targetBits))
        return &ProofOfWork{block, IntTarget}
    }
    
    func (pow *ProofOfWork)PrepareRowData(nonce int64) []byte {
        block := pow.block
        tmp := [][]byte{
            IntToByte(block.Version),
            block.PreBlockHash,
            IntToByte(block.TimeStamp),
            block.MerkelRoot,
            IntToByte(nonce),
            IntToByte(targetBits),
            block.Data,
        }
        data := bytes.Join(tmp, []byte{})//join接收两个参数,第一个二维数组,第二个这里设置为空的连接符
        return data
    }
    
    func (pow *ProofOfWork)Run() (int64, []byte) {
        var nonce int64
        var hash [32]byte
        var HashInt big.Int
        fmt.Printf("Begin mining....")
        fmt.Printf("Target Hash : %x
    ", pow.targetBit.Bytes())
        for nonce < math.MaxInt64 {
            data := pow.PrepareRowData(nonce)
            hash = sha256.Sum256(data)
            HashInt.SetBytes(hash[:])
            if HashInt.Cmp(pow.targetBit) == -1 {
                fmt.Printf("found hash: %x
    ", hash)
                break
            } else {
                nonce++
            }
        }
        return nonce, hash[:]
    }
    
    func (pow *ProofOfWork)IsValid() bool  {
        data :=    pow.PrepareRowData(pow.block.Nonce)
        hash := sha256.Sum256(data)
        var IntHash big.Int
        IntHash.SetBytes(hash[:])
        return IntHash.Cmp(pow.targetBit) == -1
    }

    系统就会自动进行运算,go build *.go之后 ,执行结果为

    baylor@baylor-virtual-machine:~/go/src/v2$ ./blockchain 
    Begin mining....Target Hash : 010000000000000000000000000000000000000000000000000000000000
    found hash: 0000009d511471179142f674a5efc491ce2e6c53aa941866037eaceb2864c364
    Begin mining....Target Hash : 010000000000000000000000000000000000000000000000000000000000
    found hash: 000000dc2edb49477aef1e99eb9dfd50c54ce5978a105071006a9ce0095de6fa
    Begin mining....Target Hash : 010000000000000000000000000000000000000000000000000000000000
    found hash: 000000c983192057f57ecfa3da5dab35701f67daa9a3556674e5d93bb75be142
    ============= block num :  0
    Version 1
    PreBlockHash: 
    Hash: 0000009d511471179142f674a5efc491ce2e6c53aa941866037eaceb2864c364
    TimeStamp: 5bc053cb
    Nonce: 25d497c
    MerkelRoot: 
    Data: Gensis Block!
    IsValid : true
    ============= block num :  1
    Version 1
    PreBlockHash: 0000009d511471179142f674a5efc491ce2e6c53aa941866037eaceb2864c364
    Hash: 000000dc2edb49477aef1e99eb9dfd50c54ce5978a105071006a9ce0095de6fa
    TimeStamp: 5bc053f2
    Nonce: 19a5b8
    MerkelRoot: 
    Data: 班长转给老师一枚BTC
    IsValid : true
    ============= block num :  2
    Version 1
    PreBlockHash: 000000dc2edb49477aef1e99eb9dfd50c54ce5978a105071006a9ce0095de6fa
    Hash: 000000c983192057f57ecfa3da5dab35701f67daa9a3556674e5d93bb75be142
    TimeStamp: 5bc053f4
    Nonce: 943496
    MerkelRoot: 
    Data: 班长又转给老师一枚BTC
    IsValid : true
  • 相关阅读:
    题解——loj6279 数列分块入门3 (分块)
    题解——loj6278 数列分块入门2 (分块)
    题解——loj6277 数列分块入门1(分块)
    题解——P1133 教主的花园DP
    题解——P1108低价购买(DP)
    题解——UVA11997 K Smallest Sums
    题解——洛谷P1550 [USACO08OCT]打井Watering Hole(最小生成树,建图)
    题解——CodeForces 438D The Child and Sequence
    题解——ATCoder AtCoder Grand Contest 017 B
    题解——洛谷P2827 NOIP提高组 2016 蚯蚓
  • 原文地址:https://www.cnblogs.com/baylorqu/p/9778701.html
Copyright © 2020-2023  润新知