用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。
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 , 當看到具體版本信息返回表明已成功。
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測試
全部API詳見 http://192.168.28.136:46657
觀察 http://192.168.28.136:46657/status
目前區塊高度爲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