用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/ <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/>

 

观察 http://192.168.28.136:46657/status <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


友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信