如何使用Go實現區塊鏈 | 區塊鏈研究實驗室

買賣虛擬貨幣

自網際網路以來,鎖鏈技術已被某些人稱為最有影響力的發明。儘管公眾將區塊鏈與投機性加密貨幣同義解釋,但區塊鏈實際上在現代世界中具有不可思議的廣泛應用。實際上,加密貨幣只是區塊鏈領域的一小部分,生產中的許多解決方案都是由私人組織領導來實現的。



隨著區塊鏈技術的迅速發展,技術領域的專業人員越來越需要了解區塊鏈的基礎知識及其技術影響力。


畢竟,實現自己的區塊鏈實際上並不像聽起來那樣複雜。本文中,我們將使用2021年最流行的程式語言之一GoLang實現基本的區塊鏈。那麼,
讓我們開始吧!

瞭解區塊鏈

區塊鏈是名稱符合其含義的少數技術之一。我們可以將區塊鏈視為透過雜湊相互連線的資訊塊,雜湊是從輸入資料生成的加密的固定輸出。由於每個塊都透過雜湊相互引用,因此如果不大幅度更改鏈的其餘部分,就不可能更改鏈的任何部分。


區塊鏈中的每個塊都可以包含幾乎任何內容的資料。一個基本框架將包括每個塊的過去交易的所有記錄。比特幣以類似的方式工作,這就是為什麼您可以一直跟蹤比特幣交易直至Satoshi首次進行加密貨幣交易的原因。


下面我們有三個區塊來建立區塊鏈。第一塊是創世塊。由於之前沒有任何內容,因此前一個雜湊欄位為空。我們仍然使用時間戳記屬性和初始事務作為雜湊演算法的輸入。該演算法將吐出一大串數字和字母,這些數字和字母代表了創世紀塊的雜湊值。



轉到塊2,我們將創世塊的雜湊值用作塊2先前雜湊值。這個動作將創世塊與第2塊聯絡起來!接下來,我們將時間戳,交易列表和先前的雜湊值作為我們的雜湊演算法的輸入。該演算法將為我們提供一個新的雜湊值來表示塊2。


我們將繼續重複該過程任意多次,除了區塊的有效性以及儲存區塊鏈的能力(比特幣的區塊鏈約為330 GB)之外,沒有任何其他限制。

在Go中建立一個簡單的區塊鏈

建立我們的區塊鏈的第一步是定義什麼是區塊。Go使我們的生活更輕鬆地建立自定義型別,我們可以Block使用以下程式碼來定義型別。在這裡,該Block結構具有四個欄位以匹配我們上面的圖。
type Block struct { timestamp time.Time transactions []string prevHash []byte Hash []byte}


下一步是建立建構函式的Go版本,以建立新的塊。該函式的輸入將使用一個字串陣列來表示事務,以及一個位元組陣列來表示先前製作的塊所對應的先前的雜湊值。下一個要研究的NewHash()功能是我們下一步將實現的功能。
func NewBlock(transactions []string, prevHash []byte) *Block { currentTime := time.Now() return &Block { timestamp: currentTime, transactions: transactions, prevHash: prevHash, Hash: NewHash(currentTime, transactions, prevHash), }}



該NewHash()函式將時間,事務列表和以前的雜湊作為我們的輸入引數,同時返回一個位元組陣列來表示新生成的雜湊值。在此功能中,我們基本上只是將所有輸入都混入一個稱為的單個位元組陣列中input。我們這樣做是使用append()功能的附加time引數,prevHash透過轉換time為string用...,以追加作為字尾time片的prevHash切片。


然後,我們遍歷transactions並將每個個體附加transaction到input資料blob。有趣的語法string(rune(transaction))...只是Go中將其中的每個元素轉換transactions為可以附加到的切片的一種方法input。它正在輸入垃圾內容,因此,如果您真的想要,請深入研究。
func NewHash(time time.Time, transactions []string, prevHash []byte) []byte { input := append(prevHash, time.String()...) for transaction := range transactions { input = append(input, string(rune(transaction))...) } hash := sha256.Sum256(input) return hash[:]}


最後,我們使用crypto包轉到電話sha256.Sum256()與input作為它的引數。這將為我們的所有資料輸入提供新的雜湊表示。我們返回時hash[:]使用的[:]語法將hash在返回時切成適當的長度。



這實際上是我們開始連結我們的區塊鏈所需的全部。當然,我們希望在程式中看到某種輸出,以便在列印時可以使用一些輔助方法:

func printBlockInformation(block *Block) { fmt.Printf("\ttime: %s\n", block.timestamp.String()) fmt.Printf("\tprevHash: %x\n", block.prevHash) fmt.Printf("\tHash: %x\n", block.Hash) printTransactions(block)}
func printTransactions(block *Block) { fmt.Println("\tTransactions:") for i, transaction := range block.transactions { fmt.Printf("\t\t%v: %q\n", i, transaction) }}


現在剩下的就是建立新的事務,塊和雜湊。我們可以透過我們的主要方法來做到這一點。我們定義了一個字串陣列來記錄我們的區塊鏈中的交易。另請注意,我們如何傳遞一個空位元組陣列NewBlock()來生成名為的第一個塊genesisBlock。
func main() { genesisTransactions := []string{"Izzy sent Will 50 bitcoin", "Will sent Izzy 30 bitcoin"} genesisBlock := NewBlock(genesisTransactions, []byte{}) fmt.Println("--- First Block ---") printBlockInformation(genesisBlock)
block2Transactions := []string{"John sent Izzy 30 bitcoin"} block2 := NewBlock(block2Transactions, genesisBlock.Hash) fmt.Println("--- Second Block ---") printBlockInformation(block2)
block3Transactions := []string{"Will sent Izzy 45 bitcoin", "Izzy sent Will 10 bitcoin"} block3 := NewBlock(block3Transactions, block2.Hash) fmt.Println("--- Third Block ---") printBlockInformation(block3)}



為了建立新的區塊,我們將前一個區塊的雜湊值NewBlock()與對應的交易歷史記錄一起傳遞。如果您想在一個地方檢視整個程式,則為:
package main
import ( "crypto/sha256" "fmt" "time")
type Block struct { timestamp time.Time transactions []string prevHash []byte Hash []byte}
func main() { genesisTransactions := []string{"Izzy sent Will 50 bitcoin", "Will sent Izzy 30 bitcoin"} genesisBlock := NewBlock(genesisTransactions, []byte{}) fmt.Println("--- First Block ---") printBlockInformation(genesisBlock)
block2Transactions := []string{"John sent Izzy 30 bitcoin"} block2 := NewBlock(block2Transactions, genesisBlock.Hash) fmt.Println("--- Second Block ---") printBlockInformation(block2)
block3Transactions := []string{"Will sent Izzy 45 bitcoin", "Izzy sent Will 10 bitcoin"} block3 := NewBlock(block3Transactions, block2.Hash) fmt.Println("--- Third Block ---") printBlockInformation(block3)}
func NewBlock(transactions []string, prevHash []byte) *Block { currentTime := time.Now() return &Block { timestamp: currentTime, transactions: transactions, prevHash: prevHash, Hash: NewHash(currentTime, transactions, prevHash), }}
func NewHash(time time.Time, transactions []string, prevHash []byte) []byte { input := append(prevHash, time.String()...) for transaction := range transactions { input = append(input, string(rune(transaction))...) } hash := sha256.Sum256(input) return hash[:]}
func printBlockInformation(block *Block) { fmt.Printf("\ttime: %s\n", block.timestamp.String()) fmt.Printf("\tprevHash: %x\n", block.prevHash) fmt.Printf("\tHash: %x\n", block.Hash) printTransactions(block)}
func printTransactions(block *Block) { fmt.Println("\tTransactions:") for i, transaction := range block.transactions { fmt.Printf("\t\t%v: %q\n", i, transaction) }}



如果要執行此程式,將得到以下輸出:
$ go run example.go --- First Block --- time: 2021-04-05 15:12:18.813294 -0600 MDT m=+0.000074939 prevHash:  Hash: 43ec51c50d2b9565f221155a29d8b72307247b08eaf6731cca Transactions: 0: "Izzy sent Will 50 bitcoin" 1: "Will sent Izzy 30 bitcoin"--- Second Block --- time: 2021-04-05 15:12:18.813477 -0600 MDT m=+0.000257244 prevHash: 43ec51c50d2b9565f221155a29d8b72307247b08eaf6731cca Hash: fcce5323a35cb67b45fe75866582db00fd32baeb92aac448c7 Transactions: 0: "John sent Izzy 30 bitcoin"--- Third Block --- time: 2021-04-05 15:12:18.813488 -0600 MDT m=+0.000269168 prevHash: fcce5323a35cb67b45fe75866582db00fd32baeb92aac448c7 Hash: fc1d3eee286970d85812b47c3a5bf016ae8c1de4f86b8ace972ffa Transactions: 0: "Will sent Izzy 45 bitcoin" 1: "Izzy sent Will 10 bitcoin"

過程可能會很粗糙,但這是建立自己的區塊鏈的基礎!

作者:鏈三豐,來源:區塊鏈研究實驗室

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读