用Tendermint開發一條簡單的區塊鏈
1.初識Tendermint
Tendermint(TM)是the Cosmos network旗下的一個區塊鏈專案。TM能安全且保持一致性地在多臺機器之間複製應用程式。TM的共識演算法基於節點不可信的設計,也就是允許拜占庭錯誤。TM主要分成兩個部分。
一個是一個區塊鏈共識引擎(Tendermint Core)。他主要負責節點之間的資料同步有序傳輸,實現拜占庭共識機制。
另一個是區塊鏈應用介面(ABCI)。它是一種介面通訊協議,可以通過各種程式語言實現應用邏輯。應用邏輯和TM Core通過ABCI實現瞭解耦。
下圖對Tendermint的工作原理進行了簡單的剖析。
2.安裝Tendermint
Tendermint的安裝方法有兩種,一種是直接下載編譯好的二進位制檔案。下載地址為:
https://github.com/tendermint/tendermint/releases
另一種安裝方法是原始碼編譯安裝。這裡介紹官網推薦的安裝方式。
本次安裝需要安裝三件東西,Go,Tendermint和Glide,作業系統為Linux。
解壓縮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 , 當看到具體版本資訊返回表明已成功。
2)安裝Glide
go get github.com/Masterminds/glide (使用go get命令需要預先安裝git)
cd /mygo/src/github.com/Masterminds/glide
make && make install
執行 glide -v (當看到具體版本資訊返回表明已成功。)
3)安裝Tendermint
go get github.com/tendermint/tendermint/cmd/tendermint (此步驟需要科學上網)
cd $GOPATH/src/github.com/tendermint/tendermint
glide install (為tendermint安裝相關依賴包,此步驟需要科學上網)
go install ./cmd/tendermint (編譯安裝tendermint)
cd /mygo/bin && cp tendermint /usr/local/bin/
tendermint version
至此tendermint安裝成功了。
3. 編寫ABCI-Application
工程的目錄結構為
下面主要講解核心程式碼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目錄下
2)編譯 cd /mygo/src/abci_server/ && go build .
3)啟動abci_server ./abci_server
4)另外開啟一個終端,編寫tendermint啟動指令碼並啟動tendermint。
指令碼內容如下
啟動 ./start_tendermint
來看tendermint的log
再來看abci_server的log,已經多了一些內容了
abci_server已經接受了tendermint的三個socket連續
5)API測試
目前區塊高度為2
接下來提交一個交易 http://192.168.28.136:46657/broadcast_tx_commit?tx="2468"
可以看到高度已變成3
abci_server的log 也增加了相應內容
接下來提交一個不合規的交易
http://192.168.28.136:46657/broadcast_tx_commit?tx="2c"
這條交易在CheckTx階段不通過,此交易進不了新的區塊。
查詢校驗
5. 小結
本文簡單介紹了tendermint,並通過一個案例介紹了使用tendermint開發一條簡單區塊鏈的過程,此次案例只是部署了一個tendermint節點,關於如何部署多個節點(4,7,10...)以組成P2P網路,有待下回分解。
歡迎加入Tendermint學習群:695657335