區塊鏈研究實驗室 | 如何從0構建區塊鏈(一)

買賣虛擬貨幣

什麼是區塊鏈?建造一個難嗎?從哪裡開始?使用哪種程式語言?

相信我,在遇到對區塊鏈技術感興趣的人時,我經常會遇到這些問題,您也可能遇到其中的一些問題。

線上上有大量的區塊鏈資源,但是將它們理解為這項蓬勃發展的技術的新手,這讓人感到不知所措。

在這篇文章中,我將step by step給你展示,你就會明白blockchain以及如何的基本概念,採用方案一的Python,Javascript,或Golang 。

我選擇這些語言是因為大多數人都熟悉它們,尤其是Javascript和Python。但是出於速度,耐用性和安全性的考慮,大多數區塊鏈核心引擎都是內建的c / c ++(比特幣,EOS),Go(超級賬本結構,以太坊),Java(以太坊),Rust,Haskell和/或Ruby(以太坊)然後提供與其他易於使用的程式語言。

此外,一些區塊鏈引擎結合了多種程式語言,以實現健壯性並易於開發人員使用,以太坊是最佳用例。

先決條件:

  • 網路

  • 密碼學

  • 資料結構與演算法

  • 分散式系統

  • Javascript / Go / Python

您只需要基本概念即可對拳頭區塊鏈原型進行程式設計。

什麼是區塊鏈?

讓我們先了解一下,區塊鏈不是比特幣,區塊鏈不是數字貨幣, 區塊鏈是一套已經存在的不同技術。

讓我們透過舉一個例子來簡化事情,因為工程師對數字的理解會更好。讓我們來看一個儲存一些資訊的MySQL資料庫。

使用上述資料庫,我們可以:

  • 做一些CRUD(建立,檢索,更新和刪除)操作,

  • 將相同的資訊儲存兩次,

  • 刪除整個資料庫,

  • 我們不能與他人共享敏感資訊,

  • 資料庫可以集中化(單點故障,安全問題),

  • 無法信任儲存在其中的所有內容。

  • 一些資料庫可以允許表之間的關係(例如RDBMS),而另一些資料庫則不能容忍這種關係(例如NoSQL資料庫),

  • 惡意的人可能會炸燬資料庫

  • 需要一名資料庫管理員(他/她可以更改或洩露資訊)

  • 使用者無法控制自己的資料

  • 等等…

那麼,為什麼我們需要不同的東西,可靠的東西,獨立於人的東西,自動的東西,不可變的東西呢?那就是區塊鏈開始的地方。

區塊鏈是一個安全,可信的去中心化資料庫和網路。

“Truth can only be found in one place: the code. ”

區塊鏈是一連串的區塊,區塊類似於資料庫中的表,但是它們不能被刪除或更新,區塊包含稱為交易的資訊和其他附加資料。這些區塊經過密碼驗證並連結形成一個不變的區塊鏈,稱為區塊鏈或分類賬。

然後,同一條鏈透過P2P網路分佈到整個網路中的所有節點。

因此,代替集中式資料庫,跨節點共享的所有事務(資料)都包含在塊中,這些塊連結在一起以建立分類帳。該分類賬代表區塊鏈中的所有資料。分類賬中的所有資料均透過加密雜湊和數字簽名進行保護,並透過共識演算法進行驗證。網路上的節點參與以確保跨網路分佈的所有資料副本都是相同的。

在區塊鏈生態系統中要記住的5個關鍵概念:

  • 加密雜湊和數字簽名

  • 不變的分類帳

  • P2P網路

  • 共識演算法(PoW,PoS,PBFT,ETc…)

  • 塊驗證(採礦,鍛造等)

我們將繼續詳細解釋這些概念。

使用區塊鏈的好處:

  • 刪除中介組織

  • 不變的分類帳

  • 透明度

  • 安全

何時使用區塊鏈?

區塊鏈不是靈丹妙藥,因此在以下情況下使用它:

  • 儲存的資料無需修改(存在證明)

  • 資料不能被其所有者拒絕(不可否認)

  • 你想權力下放

  • 你想要一個真理的源頭

  • 您想要高安全性

  • 您不必擔心速度(例如,比特幣平均需要10分鐘才能驗證一筆交易)。

    但是某些區塊鏈速度更快,因為它們使用除PoW之外的不同共識演算法

我們稍後再討論。


區塊鏈用例

區塊鏈應用領域

  • 房地產:土地所有權

  • 醫療保健:安全記錄患者的資料

  • 財務:減少稅收和中介機構,反洗錢,跨境支付

  • 供應鏈:跟蹤從供應商到客戶的商品(真實性,原創內容的建立)

  • 網路安全:DDOS攻擊

  • 將權力交還給使用者:擁有資料並與所需的人安全地共享(DID)

  • 加密貨幣兌換

  • 投票機制

區塊鏈平臺和應用

  • 比特幣

  • 以太坊

  • 織物

  • EOS

  • 鏈環

  • 卡爾達諾

  • 等等…

區塊鏈型別

  • 私有:僅在內部使用,並且在我們更瞭解使用者的情況下使用(例如Hyperledger Fabric)

  • 公開:每個人都可以看到正在發生的事情(比特幣,以太坊)

  • 混合:合併前兩個。

“Talk is cheap. Show me the code.”

有兩種方法可以構建區塊鏈:

  • 一種簡單的方法是使用現有的預先構建的區塊鏈開源資源,例如以太坊,Fabric,EOS等…

  • 如果它們都不符合您的要求,那麼請從頭開始構建

在本系列中,我們將從頭開始構建一個,以便您可以徹底瞭解區塊鏈的狀態機。

如何建立區塊鏈?

好的,現在讓我們用三種不同的程式語言Go,Python和Javascript建立第一個小區塊鏈demo。這些原型可以幫助您理解我們前面介紹的概念。

首先,我們將建立一個塊,第二,我們將新增資料(標題和正文)給它,第三,我們將雜湊塊,和最後但並非最不重要,我們將鏈中的所有塊了。

一個塊包含前面提到的資訊,但是為了簡化起見,我們將刪除一些資訊。讓我們深入研究細節!

希望您像我之前提到的那樣熟悉Go程式設計,如果不嘗試學習基礎知識:函式,方法,資料型別,結構,流控制,迭代等…

建立一個資料夾並向其中新增2個檔案, main.go and block.go

資料夾結構:

go // the folder main.go // file 1 block.go // file 2

main.go

// use the main packagepackage main//import the fmt packageimport ("fmt")func main(){fmt.Println("I am building my first blockchain") // print thisCreateBlock("The hearder will be shown here", "the body will be shown here") // call the function that will create the block and pass some parameters in it.}

如果您執行此程式,則由於該CreateBlock函式尚未定義,因此將顯示錯誤訊息,因此請繼續在其中建立它block.go:

block.go

package mainimport ("fmt" // this will help us to print on the screen)func CreateBlock(Header, Body string){fmt.Println(Header ,"\n", Body) // Show me the block content}

Go的優點在於您不必匯入或匯出函式,只需使用大寫字母宣告它們,Go就會為您找到它們。現在開啟終端並移至您建立的資料夾,run go build然後.\go在Windows,./goLinux和Macbook上執行。

我們剛剛建立了一個簡單的Go程式,該程式呼叫一個函式並傳遞一些字串資料。讓我們繼續做更多美好的事情。讓我們新增2個檔案,blockchain.go而structures.go現在我們有4個檔案:main.go, block.go, structures.go, and blockchain.go

我將在程式碼的每一行中新增一些註釋,以使您瞭解我在做什麼。

structures.go

package main //Import the main package// Create the Block data structure// A block contains this info:type Block struct { Timestamp int64 // the time when the block was created PreviousBlockHash []byte // the hash of the previous block MyBlockHash []byte // the hash of the current block AllData []byte // the data or transactions (body info)}
// Prepare the Blockchain data structure :type Blockchain struct { Blocks []*Block // remember a blockchain is a series of blocks}

block.go

package main
import ( // We will need these libraries: "bytes" // need to convert data into byte in order to be sent on the network, computer understands better the byte(8bits)language "crypto/sha256" //crypto library to hash the data "strconv" // for conversion "time" // the time for our timestamp)
// Now let's create a method for generating a hash of the block// We will just concatenate all the data and hash it to obtain the block hashfunc (block *Block) SetHash() { timestamp := []byte(strconv.FormatInt(block.Timestamp, 10)) // get the time and convert it into a unique series of digits headers := bytes.Join([][]byte{timestamp, block.PreviousBlockHash, block.AllData}, []byte{}) // concatenate all the block data hash := sha256.Sum256(headers) // hash the whole thing block.MyBlockHash = hash[:] // now set the hash of the block}
// Create a function for new block generation and return that blockfunc NewBlock(data string, prevBlockHash []byte) *Block { block := &Block{time.Now().Unix(), prevBlockHash, []byte{}, []byte(data)} // the block is received block.SetHash() // the block is hashed return block // the block is returned with all the information in it}
/* let's now create the genesis block function that will return the first block. The genesis block is the first block on the chain */func NewGenesisBlock() *Block { return NewBlock("Genesis Block", []byte{}) // the genesis block is made with some data in it}

blockchain.go

package main
// create the method that adds a new block to a blockchainfunc (blockchain *Blockchain) AddBlock(data string) { PreviousBlock := blockchain.Blocks[len(blockchain.Blocks)-1] // the previous block is needed, so let's get it newBlock := NewBlock(data, PreviousBlock.MyBlockHash) // create a new block containing the data and the hash of the previous block blockchain.Blocks = append(blockchain.Blocks, newBlock) // add that block to the chain to create a chain of blocks}
/* Create the function that returns the whole blockchain and add the genesis to it first. the genesis block is the first ever mined block, so let's create a function that will return it since it does not exist yet */func NewBlockchain() *Blockchain { // the function is created return &Blockchain{[]*Block{NewGenesisBlock()}} // the genesis block is added first to the chain}

main.go

//Time to put everything together and testpackage mainimport ( "fmt" // just for printing something on the screen)func main() { newblockchain := NewBlockchain() // Initialize the blockchain // create 2 blocks and add 2 transactions newblockchain.AddBlock("first transaction") // first block containing one tx newblockchain.AddBlock("Second transaction") // second block containing one tx // Now print all the blocks and their contents for _, block := range newblockchain.Blocks { // iterate on each block fmt.Printf("Hash of the block %x\n", block.MyBlockHash) // print the hash of the block fmt.Printf("Hash of the previous Block: %x\n", block.PreviousBlockHash) // print the hash of the previous block fmt.Printf("All the transactions: %s\n", block.AllData) // print the transactions } // our blockchain will be printed}

讓我們現在執行它,go build然後.\go

我們在區塊鏈中的區塊沒有任何ID和時間戳,因此讓我們透過修改main.go檔案來新增該資訊,並在中新增這兩行for loop:

fmt.Printf("Block ID : %d \n", i) fmt.Printf("Timestamp : %d \n", block.Timestamp+int64(i))
//Time to put everything together and testpackage main
import ( "fmt" // just for printing something on the screen)
func main() { newblockchain := NewBlockchain() // Initialize the blockchain // create 2 blocks and add 2 transactions newblockchain.AddBlock("first transaction") // first block containing one tx newblockchain.AddBlock("Second transaction") // second block containing one tx // Now print all the blocks and their contents for i, block := range newblockchain.Blocks { // iterate on each block fmt.Printf("Block ID : %d \n", i) // print the block ID fmt.Printf("Timestamp : %d \n", block.Timestamp+int64(i)) // print the timestamp of the block, to make them different, we just add a value i fmt.Printf("Hash of the block : %x\n", block.MyBlockHash) // print the hash of the block fmt.Printf("Hash of the previous Block : %x\n", block.PreviousBlockHash) // print the hash of the previous block fmt.Printf("All the transactions : %s\n", block.AllData) // print the transactions } // our blockchain will be printed}

讓我們儲存程式碼,go build然後再次執行它,然後./go

如您所見,區塊鏈結構良好。除創世塊外,每個塊均包含其雜湊值和上一個塊的雜湊值,這使其不可變,如果更改了該塊中的資料,則雜湊值將自動更改,並且該塊將被丟棄。創世塊沒有任何先前的雜湊,因為它是第一個雜湊,沒有先前的塊。

全部完成!恭喜,您剛剛在Go created中建立了自己的區塊鏈DEMO!

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

免責聲明:

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

推荐阅读