用Tendermint開發一條簡單的區塊鏈

用Tendermint開發一條簡單的區塊鏈 

1.         初識Tendermint

Tendermint(TM)是the Cosmos network旗下的一個區塊鏈項目。TM能安全且保持一致性地在多臺機器之間複製應用程序。TM的共識算法基於節點不可信的設計,也就是允許拜占庭錯誤。TM主要分成兩個部分。

一個是一個區塊鏈共識引擎(Tendermint Core)。他主要負責節點之間的數據同步有序傳輸,實現拜占庭共識機制。

另一個是區塊鏈應用接口(ABCI)。它是一種接口通訊協議,可以通過各種編程語言實現應用邏輯。應用邏輯和TM Core通過ABCI實現瞭解耦。

下圖對Tendermint的工作原理進行了簡單的剖析。

image.png

2.         安裝Tendermint

Tendermint的安裝方法有兩種,一種是直接下載編譯好的二進制文件。下載地址爲:

https://github.com/tendermint/tendermint/releases

 

另一種安裝方法是源碼編譯安裝。這裏介紹官網推薦的安裝方式。

本次安裝需要安裝三件東西,Go,Tendermint和Glide,操作系統爲Linux。

 

1)     安裝Go
訪問下載地址https://golang.google.cn/dl/下載相應的安裝包。

解壓縮tar.gz包到安裝目錄下,

tar -zxvf go1.10.linux-amd64.tar.gz -C /usr/local/

 

設置PATH

export PATH=$PATH: /usr/local/go/bin

 

設置GOPATH

mkdir /mygo && export GOPATH=/mygo

 

創建三個文件夾

mkdir /mygo/src /mygo/bin /mygo/pkg  

 

刷新環境變量

source /etc/profile

 

然後執行go version , 當看到具體版本信息返回表明已成功。

image.png

 

2)     安裝Glide

go get github.com/Masterminds/glide (使用go get命令需要預先安裝git)

cd /mygo/src/github.com/Masterminds/glide

       make && make install

image.png

 

       執行 glide -v (當看到具體版本信息返回表明已成功。)

image.png

 

3)     安裝Tendermint

go get github.com/tendermint/tendermint/cmd/tendermint (此步驟需要科學上網)

image.png

cd $GOPATH/src/github.com/tendermint/tendermint

glide install (爲tendermint安裝相關依賴包,此步驟需要科學上網)

image.png

   go install ./cmd/tendermint   (編譯安裝tendermint)

image.png

       cd /mygo/bin && cp tendermint /usr/local/bin/ 

tendermint version

       image.png

       至此tendermint安裝成功了。

3. 編寫ABCI-Application

工程的目錄結構爲

image.png

 

下面主要講解核心代碼main.go和EvenNumberApplication.go。

1) ABCI-Server啓動入口: main.go

func main() {
   
if e := initLogger() e!=nil { //初始化Logger
      
lib.Log.Errorf("initLogger failed. ",e)
   }
   
go func() {
      err := 
runEvenNumberApplication()
      
if err != nil {
         lib.Log.
Error(err)
         os.
Exit(1)
      }
   }()
   
runConsole() //abci-server持續運行
}

 

 func runEvenNumberApplication() error {
    var app types.Application = apps.NewEvenNumberApplication()
    // 啓動監聽
    srv, err := server.NewServer("tcp://0.0.0.0:46658", "socket", app)
    if err != nil {
       return err
    }
    srv.SetLogger(logger.With("module", "abci-server"))
    if err := srv.Start(); err != nil {
       return err
    }
    // 當捕捉到中斷信號時,停止運行SERVER
    cmn.TrapSignal(func() {
       srv.Stop()
    })
    return nil
 }


 

2) ABCI-Application: EvenNumberApplication.go

(參考官網的DummyApplication例子實現,主要更改CheckTx方法,其他接口方法只是加入了日誌打印功能。下面主要貼出CheckTx方法的實現)

func (app *EvenNumberApplication) CheckTx(tx []byte) types.ResponseCheckTx {
    lib.Log.Debug("CheckTx")
    txs := string(tx)
    lib.Log.Noticef("tx is %s " , txs)
    if tx_int, err:=strconv.Atoi(txs) ; err!=nil{
       lib.Log.Warning("tx must be integer! ")
       return types.ResponseCheckTx{Code: code.CodeTypeBadNonce}
    }else{
       if tx_int % 2 !=0{
          lib.Log.Warning("tx must be even! ")
          return types.ResponseCheckTx{Code: code.CodeTypeBadNonce}
       }
    }
    return types.ResponseCheckTx{Code: code.CodeTypeOK}
 }


4   部署運行

1) 將abci_server工程上傳至/mygo/src目錄下

image.png

 

2)     編譯 cd /mygo/src/abci_server/ && go build .

image.png

3)     啓動abci_server   ./abci_server
image.png

4)     另外開啓一個終端,編寫tendermint啓動腳本並啓動tendermint。

腳本內容如下

image.png

 

啓動 ./start_tendermint

來看tendermint的log

image.png

 

再來看abci_server的log,已經多了一些內容了

image.png

 

abci_server已經接受了tendermint的三個socket連續

 

5)     API測試

全部API詳見 http://192.168.28.136:46657

 

觀察 http://192.168.28.136:46657/status

image.png

 

目前區塊高度爲2

 

接下來提交一個交易 http://192.168.28.136:46657/broadcast_tx_commit?tx="2468"

image.png

 

可以看到高度已變成3

abci_server的log 也增加了相應內容

image.png

 

接下來提交一個不合規的交易

http://192.168.28.136:46657/broadcast_tx_commit?tx="2c"

image.png

image.png

這條交易在CheckTx階段不通過,此交易進不了新的區塊。

 

查找校驗

image.png

 

image.png

 

image.png

 

5. 小結

       本文簡單介紹了tendermint,並通過一個案例介紹了使用tendermint開發一條簡單區塊鏈的過程,此次案例只是部署了一個tendermint節點,關於如何部署多個節點(4,7,10...)以組成P2P網絡,有待下回分解。

     歡迎加入Tendermint學習羣:695657335



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章