區(qū)塊鏈Demo

剛接觸區(qū)塊鏈,百度了下,發(fā)現(xiàn)有人用Golang編寫了一些區(qū)塊鏈的鏈構(gòu)建過程和工作量證明的代碼,發(fā)現(xiàn)工作量證明的代碼跑不通,我將這些代碼整理了下,將報(bào)錯(cuò)的地方調(diào)試修復(fù)了下,這里給出修復(fù)后能夠跑通的代碼。
代碼如下:

package main

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

const targetBits = 24
const maxNonce int = math.MaxInt64

type Blockchain struct {
    blocks []*Block
}

type Block struct {
    Timestamp     int64
    Data          []byte
    PrevBlockHash []byte
    Hash          []byte
    Nonce         int
}

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

func NewBlockchain() *Blockchain {
    return &Blockchain{[]*Block{NewGenesisBlock()}}
}

func NewGenesisBlock() *Block {
    return NewBlock("Genesis Block", []byte{})
}

func NewBlock(data string, prevBlockHash []byte) *Block {
    block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}, 0}
    pow := NewProofOfWork(block)
    nonce, hash := pow.Run()
    block.Hash = hash[:]
    block.Nonce = nonce
    return block
}

func NewProofOfWork(b *Block) *ProofOfWork {
    target := big.NewInt(1)
    target.Lsh(target, uint(256-targetBits))
    pow := &ProofOfWork{b, target}
    return pow
}

func (pow *ProofOfWork) prepareData(nonce int) []byte {
    data := bytes.Join(
        [][]byte{
            pow.block.PrevBlockHash,
            pow.block.Data,
            []byte(strconv.FormatInt(pow.block.Timestamp,10)),
            []byte(strconv.FormatInt(int64(targetBits),10)),
            []byte(strconv.FormatInt(int64(nonce),10)),
        },
        []byte{},
    )
    return data
}

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

func (pow *ProofOfWork) Run() (int, []byte) {
    var hashInt big.Int
    var hash [32]byte
    nonce := 0
    fmt.Printf("Mining the block containing \"%s\"\n", pow.block.Data)
    for nonce < maxNonce {
        data := pow.prepareData(nonce)
        hash = sha256.Sum256(data)
        hashInt.SetBytes(hash[:])
        if hashInt.Cmp(pow.target) == -1 {
            fmt.Printf("\r%x", hash)
            break
        } else {
            nonce++
        }
    }
    fmt.Print("\n\n")
    return nonce, hash[:]
}

func (bc *Blockchain) AddBlock(data string) {
    prevBlock := bc.blocks[len(bc.blocks)-1]
    newBlock := NewBlock(data, prevBlock.Hash)
    bc.blocks = append(bc.blocks, newBlock)
}

func main() {
    bc := NewBlockchain()
    bc.AddBlock("Send 1 BTC to Ivan")
    bc.AddBlock("Send 2 more BTC to Ivan")
    for _, block := range bc.blocks {
        fmt.Printf("Prev. hash: %x\n", block.PrevBlockHash)
        fmt.Printf("Data: %s\n", block.Data)
        fmt.Printf("Hash: %x\n", block.Hash)
        pow := NewProofOfWork(block)
        fmt.Printf("PoW: %s\n", strconv.FormatBool(pow.Validate()))
        fmt.Println()
    }
}

編譯:go build -o demo,執(zhí)行:./demo,大概幾分鐘之后輸出結(jié)果(如果不驗(yàn)證節(jié)點(diǎn)的正確性,那么結(jié)果的輸出更快):

Mining the block containing "Genesis Block"
0000002116784eb8746d411854031889a4a38695605336a68cebeb93aae7a315

Mining the block containing "Send 1 BTC to Ivan"
00000053b1627863dd41cbd507870c2f76e7300623ce655ae19d18fe30890341

Mining the block containing "Send 2 more BTC to Ivan"
000000a9b3b1ca2760cdc1348fca8c94042a067e2b001f8ff3c9b95f87ce334d

Prev. hash: 
Data: Genesis Block
Hash: 0000002116784eb8746d411854031889a4a38695605336a68cebeb93aae7a315
PoW: true

Prev. hash: 0000002116784eb8746d411854031889a4a38695605336a68cebeb93aae7a315
Data: Send 1 BTC to Ivan
Hash: 00000053b1627863dd41cbd507870c2f76e7300623ce655ae19d18fe30890341
PoW: true

Prev. hash: 00000053b1627863dd41cbd507870c2f76e7300623ce655ae19d18fe30890341
Data: Send 2 more BTC to Ivan
Hash: 000000a9b3b1ca2760cdc1348fca8c94042a067e2b001f8ff3c9b95f87ce334d
PoW: true

(備注:源代碼的作者不是本人) 讓我們一起學(xué)習(xí)區(qū)塊鏈知識,共同進(jìn)步,end ~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容