基於Go語言構建區塊鏈:part1

Golang語言和區塊鏈理論學習完畢後,快速入門方法無疑是項目實戰。本文將參考https://jeiwan.cc/tags/blockchain/教程,學習如何基於Go語言構建區塊鏈。數據庫

一、編程環境設置

編程工具使用GoLand,前文已介紹軟件安裝經驗。軟件安裝完成後,還須要設置工做路徑「GOPATH」。在電腦上新建一個空白目錄,而後點擊點擊Goland菜單按鈕:「File」->「Settings」->"GO"->"GOPATH",添加本身的工做目錄便可,還能夠根據本身的喜愛,設置不一樣的代碼呈現顏色、字體、字號等。編程

二、簡化的block實現

block結構以下所示:
app

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

Timestamp表示Block被建立的時間戳,Data表示block中實際的價值信息,PrevBlockHash
表示上一個Blockhash值,Hash表示該block自己的Hash值。
如今,咱們首先SetHash方法,將Block中的字段信息組合後,
生成該blockSHA-256 Hash值:
// SetHash calculates and sets block hash
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[:]
}
接下來,實現NewBlock方法用於建立一個Block
// NewBlock creates and returns Block
func NewBlock(data string, prevBlockHash []byte) *Block {
   block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}}
   block.SetHash()
   return block
}
OKblock實現完成啦! 

三、簡化的blockchain實現

本質上,blockchain僅僅是具有某種特殊結構的數據庫:有序,反向連接鏈表。這意味着,block按照插入的順序存放,同時每一個block都保存指向上一block的連接。這種結構保證能夠快速獲取最新插入的block同時獲取它的hash值。 ide

Go語言中,能夠經過slicemap來實現該結構。slice(有序)用於保存有序的hash值,map()用於保存hash->block對。對於咱們的blockchain原型,目前不須要根據hash值來獲取block所以僅僅使用slice可知足需求。blockchain結構以下: 工具

type Blockchain struct {
   blocks []*Block
}

接下來,咱們實現AddBlock方法,用於將block添加到blockchain中:
// AddBlock saves provided data as a block in the blockchain
func (bc *Blockchain) AddBlock(data string) {
   prevBlock := bc.blocks[len(bc.blocks)-1]
   newBlock := NewBlock(data, prevBlock.Hash)
   bc.blocks = append(bc.blocks, newBlock)
}
新增一個block的前提是另外一個block已經存在,可是一開始blockchain中並無任何block。因此,在任何blockchain中都必須有一個特殊的block存在,稱之爲GenesisBlock。下面實現NewGenesisBlock方法用於建立GenesisBlock
func NewGenesisBlock() *Block {
   return NewBlock("Genesis Block", []byte{})
}
接下來,實現NewBlockchain方法,該方法會建立一個包含Genesis Blockblockchain
func NewBlockchain() *Blockchain {
   return &Blockchain{[]*Block{NewGenesisBlock()}}
}

四、測試Blockchain是否能夠正常工做

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)
fmt.Println()
}
}


若直接選擇RUN 'go build main.go',會出現以下報錯:學習

# command-line-arguments
.\main.go:8:8: undefined: NewBlockchain

Compilation finished with exit code 2

這是由於「block.go」和「blockchain.go」沒有同時編譯。選擇整個項目「Blockchain」選擇Run 'go build Blockchain'便可成功,結果以下:區塊鏈

Prev. hash: 
Data: Genesis Block
Hash: aa6085b7b44bcc1d878c6a28a3d98a665f8e1522da8093defee6a61e06aeac67

Prev. hash: aa6085b7b44bcc1d878c6a28a3d98a665f8e1522da8093defee6a61e06aeac67
Data: Send 1 BTC to Ivan
Hash: 835c7514ce8b54b83add05c41977bf5f50dfec7791e12e6912feb1d9c286f7b4

Prev. hash: 835c7514ce8b54b83add05c41977bf5f50dfec7791e12e6912feb1d9c286f7b4
Data: Send 2 more BTC to Ivan
Hash: cfbd89e2384d7caabc7ff58ed0a27a5172a18fc381b0b87d990e989d55b98ecdProcess finished with exit code 0
相關文章
相關標籤/搜索