1. 程式人生 > >Golang實現區塊鏈(一)—簡單區塊鏈

Golang實現區塊鏈(一)—簡單區塊鏈

隨著比特幣、以太坊等虛擬貨幣的越來越火,作為這些虛擬貨幣背後支撐的區塊鏈技術,也被越來越多的人提及。下面我們將使用go語言對區塊鏈進行探討,並實現一個簡易的區塊鏈,本文暫不涉及poW、poS等共識演算法。

通過本文,你可以做到:

  • 瞭解區塊
  • Hash演算法
  • 區塊鏈的構建

Block/區塊基礎##

瞭解區塊鏈,我們就得先了解它的塊。在區塊鏈中,塊儲存了一些資訊,比如,區塊所在的位置、區塊建立的時間、區塊儲存的變數資訊、區塊的當前Hash值、以及上一個區塊的Hash值等。

設計邏輯

  • 區塊設計
  • 雜湊計算
  • 生成新塊
  • 構建區塊鏈

區塊結構程式碼

 type Block struct {
	Index  int64
	TimeStamp int64
	Data  []byte
	PrevBlockHash []byte
	Hash []byte
}

Hash演算法

區塊鏈使用的是Hash驗證,那為什麼使用Hash計算呢?

  1. 計算Hash非常困難,使在牛逼的計算機中也要花上一些時間計算出來,這樣可以增加建立新塊的難度。
  2. 只要區塊的資訊有任意一點變化,Hash值也會隨著變化,下一個塊Hash驗證就通過不了,這就保證的區塊的安全性。 3.每個塊上的資訊,都儲存在當前塊的Hash上,這就節省了空間。

設定雜湊函式

下面我們對區塊資訊進行hash加密

func (b *Block)CalHash()  {
	timestamp :=[]byte(strconv.FormatInt(b.TimeStamp,10))
	index := []byte(strconv.FormatInt(b.Index,10))
	headers :=bytes.Join([][]byte{timestamp,index,b.PrevBlockHash},[]byte{})
	hash:=sha256.Sum256(headers)
	b.Hash =hash[:]
}

建立區塊

下面我們來建立新的區塊

func  NewBlock(index int64,data ,prevBlockHash []byte) *Block  {
	block :=&Block{index,time.Now().Unix(),data,prevBlockHash,[]byte{}}
	block.CalHash()
	return  block
}

區塊鏈

區塊鏈,顧名思義區塊鏈就是一個一個有序的區塊連線而成。它的本質就是一個一定結構的資料庫。我們要特別注意前面的詞“有序”。

區塊鏈抽象圖

區塊鏈抽象圖

定義簡單區塊鏈

在golang裡可以使用陣列、map來實現,陣列可以保證順序,map實現hash->block組合的對映 不過,針對目前的進度,我們不需要實現能過hash找到區塊的方法,所以這裡只用陣列來保證順序即可。

	type Blockchain struct {
  blocks []*Block
}

構建創世區塊

為了能建立區塊鏈,我們必須要一個已經存在的區塊,才能鏈下去。在區塊鏈中,這個第一個區塊,即是“創世區塊”。

func NewGenesisBlock() *Block  {
	return  NewBlock(0,[]byte("first block"),[]byte{})
}
}

然後我們把這個創世區塊新增到區塊鏈中,來引導下面的區塊。

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

執行

基本的區塊鏈功能我們已經實現,下面我們就開看看它的效果。

func main(){
	bc :=NewBlockchain()
	bc.AddBlock(bc.blocks[len(bc.blocks)-1].Index+1,"Joy send 1 BTC to Jay")
	bc.AddBlock(bc.blocks[len(bc.blocks)-1].Index+1,"Jakc sent 2 BTC to Jay")

	for  _,block := range bc.blocks{
		fmt.Printf("Index :%d\n" ,block.Index)
		fmt.Printf("TimeStamp: %d\n",block.TimeStamp)
		fmt.Printf("Data: %s\n",block.Data)
		fmt.Printf("PrevHash: %x\n",block.PrevBlockHash)
		fmt.Printf("Hash: %x\n",block.Hash)
		fmt.Println("_____________________________")
	}
	                 nnnnnnnnnnnnnnnnnnnnnnnnnnnn
}

執行結果

Index :0
TimeStamp: 1538560879
Data: first block
PrevHash: 
Hash: 4f72e1adeaf4c2c3953465dea1d7224280014128f972554724fe93cf2c6760a7
_____________________________
Index :1
TimeStamp: 1538560879
Data: Joy send 1 BTC to Jay
PrevHash: 4f72e1adeaf4c2c3953465dea1d7224280014128f972554724fe93cf2c6760a7
Hash: 070b089b9a7128dcfaca53258f004b3797e22c416c48faae1c6a3cefccc975c4
_____________________________
Index :2
TimeStamp: 1538560879
Data: Jakc sent 2 BTC to Jay
PrevHash: 070b089b9a7128dcfaca53258f004b3797e22c416c48faae1c6a3cefccc975c4
Hash: da1244af0658655ac8f82fec235acfe5dab47ce0f58b9afe75ac821c406c1dc6
_____________________________

總結

本篇文章介紹了怎麼建立簡單的區塊鏈原型:只有一個數組來維護的鏈,每個塊都擁有前一個塊的hash值來保證彼此的連線。但是我們還有很多沒有實現,比如說區塊驗證、分叉主鏈選擇、共識演算法等。