2.1 基本概念
區塊鏈是21世紀重要的技術革命之一,雖然還沒有成熟,但是仍然有很多潛力尚待發掘。基於區塊鏈的本質,它就是一個分散式記錄資料庫。但是和私有資料庫不同的是,區塊鏈是公開的(私有鏈在域內也是公開的),也就是說每一個使用它的人都會有完整或者說部分副本。而且新的記錄要增加的話,需要得到鏈中其它擁有者的同意。而且,區塊鏈使得加密貨幣和智慧合約成為可能。這一系列文章,將會闡述和實現基於簡單的區塊鏈來生成簡單的加密貨幣。
Block 塊/區塊
先從“區塊鏈”中的“區塊”說起。在區塊鏈中,塊儲存了變數資訊,比如,比特幣的區塊儲存了交易、還有加密貨幣除了這些,區塊包含了一些技術資訊,比如版本、時間戳、還有排在前面的一個區塊的hash值
1. Timestamp 時間戳也即是在區塊被建立時的時間
2. Data 就是這個區塊儲存的變數資訊
3. PrevBlockHash 前一區塊的hash值
4. Hash 是當前區塊的hash值
和比特幣分開儲存的資料結構不同的是 Timestamp、PrevBlockHash、Hash是區塊的頭(headers)資訊,交易(transactions,我們這裡轉成Data來稱呼)是在資料(data)資訊中。這裡把這些概念放在一塊,方便些:
塊程式碼結構
type Block struct {
Timestamp int64
Data []byte
PrevBlockHash []byte
Hash []byte
}
hash
那為什麼要計算hash呢?計算hash值在區塊鏈中是非常重要的特點,這使得區塊鏈是安全的。因為計算有指定特徵的hash非常困難,即使在牛逼的計算機中也要花上一些時間計算出來(所以有的人就買更適合簡單浮點運算的GPU去挖Bitcoin礦)。這麼做是故意的,因為這樣可以增加建立新塊的難度,導致增加了區塊的節點無法在增加後改動這個區塊,而改動後,這個區塊也就失效了,不被大家承認。 區塊鏈的hash演算法。為了簡單,我們現在基於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[:]
}
建立區塊
實現一個簡單的建立區塊方法:
func NewBlock(data string, prevBlockHash []byte) *Block {
block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}}
block.SetHash()
return block
}
blackchain 區塊鏈
開篇說過,區塊鏈的本質就是一個一定結構的資料庫。它是一個有序的、首尾相連的鏈狀列表,區塊們都是順序、每一個塊都連線著前面的一個塊。這個結構使得可以在區塊鏈中快速找到最後一個區塊,尤其是可以通過hash值找到區塊。
定義簡單的區塊鏈
在golang裡可以使用陣列、map來實現,陣列可以保證順序,map實現hash->block組合的對映不過,針對目前的進度,我們不需要實現能過hash找到區塊的方法,所以這裡只用陣列來保證順序即可。
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)
}
創世區塊
為了建立新的區塊,需要一個已經存在的區塊,但是現在還沒有任何一個區塊。而在區塊鏈中,第一個區塊,就是“創世區塊”。
func NewGenesisBlock() *Block {
return NewBlock("Genesis Block", []byte{})
}
使用創世區塊來引導區塊鏈
func NewBlockchain() *Blockchain {
return &Blockchain{[]*Block{NewGenesisBlock()}}
}
執行
現在可以在命令列時輸入 go run *.go執行建立區塊鏈
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()
}
}
控制檯會輸出區塊鏈的內部資訊:
Prev. hash:
Data: Genesis Block
Hash: 4f729464de88e6a01c59a54707b11d3efd5fb036637fa81f4fbcce437b7b0738
Prev. hash: 4f729464de88e6a01c59a54707b11d3efd5fb036637fa81f4fbcce437b7b0738
Data: Send 1 BTC to Ivan
Hash: 53655b661290d9d4c9973618dfd2b5cb71c8c2981b5c955fa70af5d6a30b02be
Prev. hash: 53655b661290d9d4c9973618dfd2b5cb71c8c2981b5c955fa70af5d6a30b02be
Data: Send 2 more BTC to Ivan
Hash: 22cbee453308893beca8fd023c77d61a05eca29db99272a2795d0ae7af7d306d
本章總結
我們建立了簡單的區塊鏈原型:只有一個陣列來維護的鏈,每個塊都擁有前一個塊的hash值來保證彼此的連線。真正的區塊鏈自然是要比這裡的複雜得多的。這裡的區塊鏈產生很簡單也很快,但是真正的區塊鏈產生需要做很多工作,如果要獲得一個區塊,那麼需要做大量而繁重的計算,這一機制被稱為工作量證明(Proof-of-Work)。區塊鏈是分散式的且沒有決定者(去中心化)。這就是說,新的區塊增加需要得到其它網路中參與運算的節點認可(共識)。在我們上面的例子中,還沒有一筆交易,所以,不算正式意義上的區塊鏈。
-
學院Go語言視訊主頁
https://edu.csdn.net/lecturer/1928 -
掃碼獲取海量視訊及原始碼 QQ群:721929980
相關文章
- 2.1 !
- OAuth 2.1 框架OAuth框架
- crntan 2.1 原理
- 基本概念
- 2.1 CDB容器概述
- 2.1 TF-IDF
- 2.1線性表
- CSAPP-2.1-程式APP
- sicp每日一題[2.1]每日一題
- TiDB 2.1 GA Release NotesTiDB
- babel基本概念Babel
- mongodb 基本概念MongoDB
- OpenGL基本概念
- Spring 基本概念Spring
- Kafka基本概念Kafka
- PMP基本概念
- RocketMQ基本概念MQ
- Mysql基本概念MySql
- mobx基本概念
- JMS基本概念
- javascript:基本概念JavaScript
- OAuth 2.1 的進化之路OAuth
- 2.1 常用資料型別資料型別
- tapinradioprov2.1破解版API
- 03. Django2.1 路由Django路由
- Django2.1視訊教程Django
- 2.1個股指標設定指標
- 樹的基本概念
- lipaper-基本概念
- 微服務基本概念微服務
- RabbitMQ(1)---基本概念MQ
- 圖的基本概念
- GacUI基本概念(一)UI
- 01-基本概念
- redux的基本概念Redux
- Docker的基本概念Docker
- influxdb的基本概念UX
- 進步神速,Pandas 2.1來了!