摘要:在區塊鏈中,存儲有效信息的是區塊。存儲的是前一個塊的哈希。正是由于這個特性,才使得區塊鏈是安全的。這樣的結構,能夠讓我們快速地獲取鏈上的最新塊,并且高效地通過哈希來檢索一個塊。
翻譯的系列文章我已經放到了 GitHub 上:blockchain-tutorial,后續如有更新都會在 GitHub 上,可能就不在這里同步了。如果想直接運行代碼,也可以 clone GitHub 上的教程倉庫,進入 src 目錄執行 make 即可。
區塊鏈是 21 世紀最具革命性的技術之一,它仍然處于不斷成長的階段,而且還有很多潛力尚未顯現出來。 本質上,區塊鏈只是一個分布式數據庫而已。 不過,使它獨一無二的是,區塊鏈是一個公開的數據庫,而不是一個私人數據庫,也就是說,每個使用它的人都有一個完整或部分的副本。 只有經過其他數據庫管理員的同意,才能向數據庫中添加新的記錄。 此外,也正是由于區塊鏈,才使得加密貨幣和智能合約成為現實。
在本系列文章中,我們將實現一個簡化版的區塊鏈,基于它來構建簡化版的加密貨幣。
區塊讓我們從 “區塊鏈” 中的 “區塊” 談起。在區塊鏈中,存儲有效信息的是區塊。比如,比特幣區塊存儲的有效信息,就是比特幣交易,交易信息也是所有加密貨幣的本質。除此以外,區塊還包含了一些技術信息,比如版本,當前時間戳和前一個區塊的哈希。
在本文中,我們并不會實現一個像比特幣技術規范所描述的區塊鏈,而是實現一個簡化版的區塊鏈,它僅包含了一些關鍵信息。看起來就像是這樣:
type Block struct { Timestamp int64 Data []byte PrevBlockHash []byte Hash []byte }
Timestamp 是當前時間戳,也就是區塊創建的時間。
Data 是區塊存儲的實際有效的信息。
PrevBlockHash 存儲的是前一個塊的哈希。
Hash 是當前塊的哈希。
在比特幣技術規范中,Timestamp, PrevBlockHash, Hash 是區塊頭(block header),區塊頭是一個多帶帶的數據結構。而交易,也就是這里的 Data, 是另一個多帶帶的數據結構。為了簡便起見,我把這兩個混合在了一起。
那么,我們要如何計算哈希呢?如何計算哈希,是區塊鏈一個非常重要的部分。正是由于這個特性,才使得區塊鏈是安全的。計算一個哈希,是在計算上非常困難的一個操作。即使在高速電腦上,也要花費不少時間 (這就是為什么人們會購買 GPU 來挖比特幣) 。這是一個有意為之的架構設計,它故意使得加入新的區塊十分困難,因此可以保證區塊一旦被加入以后,就很難再進行修改。在本系列未來幾篇文章中,我們將會討論和實現這個機制。
目前,我們僅取了 Block 結構的一些字段(Timestamp, Data 和 PrevBlockHash),并將它們相互連接起來,然后在連接后的結果上計算一個 SHA-256 的哈希. 讓我們在 SetHash 方法中完成這個任務:
func (b *Block) SetHash() { timestamp := []byte(strconv.FormatInt(b.Timestamp, 10)) headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{}) hash := sha256.Sum256(headers) b.Hash = hash[:] }
接下來,按照 Golang 的慣例,我們會實現一個用于簡化創建一個區塊的函數:
func NewBlock(data string, prevBlockHash []byte) *Block { block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}} block.SetHash() return block }
這就是區塊部分的全部內容了!
區塊鏈下面讓我們來實現一個區塊鏈。本質上,區塊鏈僅僅是一個有著特定結構的數據庫,是一個有序,后向連接的列表。這也就是說,區塊按照插入的順序進行存儲,每個塊都被連接到前一個塊。這樣的結構,能夠讓我們快速地獲取鏈上的最新塊,并且高效地通過哈希來檢索一個塊。
在 Golang 中,可以通過一個 array 和 map 來實現這個結構:array 存儲有序的哈希(Golang 中 array 是有序的),map 存儲 hask -> block 對(Golang 中, map 是無序的)。 但是在基本的原型階段,我們只用到了 array,因為現在還不需要通過哈希來獲取塊。
type Blockchain struct { blocks []*Block }
這就是我們的第一個區塊鏈!我從來沒有想過它會是這么容易。
現在,讓我們能夠給它添加一個塊:
func (bc *Blockchain) AddBlock(data string) { prevBlock := bc.blocks[len(bc.blocks)-1] newBlock := NewBlock(data, prevBlock.Hash) bc.blocks = append(bc.blocks, newBlock) }
完成!不過,真的就這樣了嗎?
為了加入一個新的塊,我們必須要有一個已有的塊,但是,現在我們的鏈是空的,一個塊都沒有!所以,在任何一個區塊鏈中,都必須至少有一個塊。這樣的塊,也就是鏈中的第一個塊,通常叫做創世塊(genesis block). 讓我們實現一個方法來創建一個創世塊:
func NewGenesisBlock() *Block { return NewBlock("Genesis Block", []byte{}) }
現在,我們可以實現一個函數來創建有創世塊的區塊鏈:
func NewBlockchain() *Blockchain { return &Blockchain{[]*Block{NewGenesisBlock()}} }
來檢查一個我們的區塊鏈是否如期工作:
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 ", block.PrevBlockHash) fmt.Printf("Data: %s ", block.Data) fmt.Printf("Hash: %x ", block.Hash) fmt.Println() } }
輸出:
Prev. hash: Data: Genesis Block Hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168 Prev. hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168 Data: Send 1 BTC to Ivan Hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1 Prev. hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1 Data: Send 2 more BTC to Ivan Hash: 561237522bb7fcfbccbc6fe0e98bbbde7427ffe01c6fb223f7562288ca2295d1總結
我們創建了一個非常簡單的區塊鏈原型:它僅僅是一個數組構成的一系列區塊,每個塊都與前一個塊相關聯。真實的區塊鏈要比這復雜得多。在我們的區塊鏈中,加入新的塊非常簡單,而且很快,但是在真實的區塊鏈中,加入新的塊需要很多工作:你必須要經過十分繁重的計算(這個機制叫做工作量證明),來獲得添加一個新塊的權力。并且,區塊鏈是一個沒有單一決策者的分布式數據庫。因此,一個新的塊必須要被網絡的其他參與者確認和同意(這個機制叫做共識(consensus))。還有一點,我們的區塊鏈還沒有任何的交易!
在接下來的文章的我們將會一一覆蓋這些特性。
本文涉及的源代碼:part_1
區塊哈希算法:https://en.bitcoin.it/wiki/Bl...
原文:
Building Blockchain in Go. Part 1: Basic Prototype
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/23945.html
摘要:盡管我們不會實現一個真實的網絡,但是我們會實現一個真是,也是比特幣最常見最重要的用戶場景。不過,這并不是處于禮貌用于找到一個更長的區塊鏈。意為給我看一下你有什么區塊在比特幣中,這會更加復雜。 翻譯的系列文章我已經放到了 GitHub 上:blockchain-tutorial,后續如有更新都會在 GitHub 上,可能就不在這里同步了。如果想直接運行代碼,也可以 clone GitHu...
摘要:到目前為止,我們幾乎已經實現了一個區塊鏈數據庫的所有元素。使用根據在區塊鏈中找到一筆交易。是一個比特幣輕節點,它不需要下載整個區塊鏈,也不需要驗證區塊和交易。到目前為止,我們只是將一個塊里面的每筆交易哈希連接了起來,將在上面應用了算法。 翻譯的系列文章我已經放到了 GitHub 上:blockchain-tutorial,后續如有更新都會在 GitHub 上,可能就不在這里同步了。如果...
摘要:哈希函數被廣泛用于檢測數據的一致性。在區塊鏈中,哈希被用于保證一個塊的一致性。比特幣使用,一個最初用來防止垃圾郵件的工作量證明算法。下面是與前面例子哈希的形式化比較第一個哈希基于計算比目標要大,因此它并不是一個有效的工作量證明。 翻譯的系列文章我已經放到了 GitHub 上:blockchain-tutorial,后續如有更新都會在 GitHub 上,可能就不在這里同步了。如果想直接運...
摘要:引言到目前為止,我們已經構建了一個有工作量證明機制的區塊鏈。在今天的內容中,我們會將區塊鏈持久化到一個數據庫中,然后會提供一個簡單的命令行接口,用來完成一些與區塊鏈的交互操作。這同樣也意味著,一個也就是區塊鏈的一種標識符。 翻譯的系列文章我已經放到了 GitHub 上:blockchain-tutorial,后續如有更新都會在 GitHub 上,可能就不在這里同步了。如果想直接運行代碼...
摘要:引言交易是比特幣的核心所在,而區塊鏈的唯一目的,也正是為了能夠安全可靠地存儲交易。比特幣使用了一個更加復雜的技術它將一個塊里面包含的所有交易表示為一個,然后在工作量證明系統中使用樹的根哈希。 翻譯的系列文章我已經放到了 GitHub 上:blockchain-tutorial,后續如有更新都會在 GitHub 上,可能就不在這里同步了。如果想直接運行代碼,也可以 clone GitHu...
閱讀 1324·2021-11-24 10:24
閱讀 4167·2021-11-22 15:29
閱讀 1101·2019-08-30 15:53
閱讀 2801·2019-08-30 10:54
閱讀 1988·2019-08-29 17:26
閱讀 1293·2019-08-29 17:08
閱讀 613·2019-08-28 17:55
閱讀 1591·2019-08-26 14:01