區(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ū)塊鏈知識(shí),共同進(jìn)步印荔,end ~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末低葫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子仍律,更是在濱河造成了極大的恐慌嘿悬,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件水泉,死亡現(xiàn)場(chǎng)離奇詭異善涨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)草则,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門躯概,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人畔师,你說我怎么就攤上這事娶靡。” “怎么了看锉?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵姿锭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我伯铣,道長(zhǎng)呻此,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任腔寡,我火速辦了婚禮焚鲜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己忿磅,他們只是感情好糯彬,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著葱她,像睡著了一般撩扒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吨些,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天搓谆,我揣著相機(jī)與錄音,去河邊找鬼豪墅。 笑死泉手,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的偶器。 我是一名探鬼主播斩萌,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼状囱!你這毒婦竟也來了术裸?” 一聲冷哼從身側(cè)響起倘是,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤亭枷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后搀崭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叨粘,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年瘤睹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了升敲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轰传,死狀恐怖驴党,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情获茬,我是刑警寧澤港庄,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站恕曲,受9級(jí)特大地震影響鹏氧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜佩谣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一把还、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦吊履、人聲如沸安皱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)练俐。三九已至,卻和暖如春冕臭,著一層夾襖步出監(jiān)牢的瞬間腺晾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工辜贵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悯蝉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓托慨,卻偏偏與公主長(zhǎng)得像鼻由,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子厚棵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容