区块链应用已经从单纯电子现金发展到去中心化投票等更多的领域,但是区块链这样的分布式系统的开发还存在一些困难的问题:安全、可靠性、敏捷度、以及一致性保证等等。Tendermint的目的就是致力于解决分布式系统开发中像公示算法这样的技术难点,而让Tendermint区块链应用开发者可以将关注点集中在业务逻辑上。
Tendermint简介
Tendermint萌芽于比特币、以太坊这样的加密货币,它的目标是提供一个比比特币的工作量证明(PoW)更加高效和安全的共识算法。简单地说,Tendermint是一个可供二次开发的软件包,可以在多台机器上安全、一致地实现应用状态的复制。
- Tendermint可以在不超过1/3的机器失效时依然正常工作,无论失效的原因 是什么。Tendermint实现了拜占庭容错。
- 任何正常工作的机器都会收到相同的交易日志,并分别推导出相同的状态
Tendermint的特性如下图所示:
Tendermint包含两个主要的组件:
- 区块链共识引擎,即:Tendermint内核
- 应用与区块链接口,即:Application BlockChain Interface
Tendermint内核可以托管任意的应用状态,因此可以使用任何语言开发区块链软件:Haskell、GoLang、或者Rust都可以用来开发ABCI应用。
其他区块链的一个问题是,它们都是单体设计思维的软件。以比特币为例,比特币的设计就是单体的,其区块链技术栈都包含在单一程序里,需要处理从P2P链接到交易广播、达成共识乃至检查账户余额的一切事情。
单体应用通常不容易扩展、升级或再利用,而Tendermint则致力于将区块链技术栈的两个核心组件与其他部分解耦:共识引擎和P2P连接 —— 事实上这也是开发区块链的最困难的两个技术环节 —— 从而可以使用任何开发语言来开发ABCI应用。
废话不多说了,让我们撸起袖子开干!
Tendermint开发环境搭建与测试
STEP 1:下载Tendermint内核
tendermint内核采用Go开发,有官方预编译程序,下载地址:Tendermint Core。
下载后直接解压,并将tendermint程序目录添加到环境变量PATH的设置里。
STEP 2:初始化Tendermint
执行如下命令初始化Tendermint:
代码语言:javascript复制~$ tendermint init
应当可以在终端看到tendermint的输出信息:
代码语言:javascript复制I[10–18|20:14:08.996] Generated private validator module=main path=/Users/niharikasingh/.tendermint/config/priv_validator.json
I[10–18|20:14:08.996] Generated node key module=main path=/Users/niharikasingh/.tendermint/config/node_key.json
I[10–18|20:14:08.996] Generated genesis file module=main path=/Users/niharikasingh/.tendermint/config/genesis.json
STEP 3:启动Tendermint节点
使用node子命令启动Tendermint节点:
代码语言:javascript复制~$ tendermint node -proxy_app=kvstore
-proxy_app
运行标志用来指定一个内置的ABCI应用,例如kvstore是tendermint程序内置的键值对状态机。你应该可以看到如下的tendermint程序输出:
I[10–18|20:16:40.037] Starting multiAppConn module=proxy impl=multiAppConn
...
I[10–18|20:16:42.051] enterPropose: Our turn to propose module=consensus height=2 round=0 proposer=601302EBD1F8B4BCE9F99B219965F2796AB6BB10 privValidator=”PrivValidator{601302EBD1F8B4BCE9F99B219965F2796AB6BB10 LH:1, LR:0, LS:3}”
I[10–18|20:16:42.055] Signed proposal module=consensus height=2 round=0 proposal=”Proposal{2/0 1:48B45F4423A5 (-1,:0:000000000000) F52DF1F111D8 @ 2018–10–18T14:46:42.051967933Z}”
I[10–18|20:16:42.056] Received proposal module=consensus proposal=”Proposal{2/0 1:48B45F4423A5 (-1,
STEP 4:提交交易
要提交一个交易,可以使用curl向Tendermint节点的RPC服务发出请求,例如:
代码语言:javascript复制~$ curl http://localhost:26657/broadcast_tx_commit?tx="niharika"
响应结果如下:
代码语言:javascript复制{
"jsonrpc":"2.0",
"id": "",
"result": {
"check_tx": {
"gasWanted": "1"
},
"deliver_tx": {
"tags": [
{
"key": "YXBwLmNyZWF0b3I=",
"value": "amFl"
},
{
"key": "YXBwLmtleQ==",
"value": "bmloYXJpa2E="
}
]
},
"hash": "EAAD936D3EDCCCF5DD214E02BB4065E5511CA5AC",
"height": "3533"
}
}
注意结果中的value字段,例如bmloYXJpa2E
,这其实是字符串niharika
的base64编码。
现在让我们查询一下:
代码语言:javascript复制~$ curl -s 'localhost:26657/abci_query?data="niharika"'
响应结果如下:
代码语言:javascript复制{
"jsonrpc":"2.0",
"id": "",
"result": {
"response": {
"log": "exists",
"index": "-1",
"key": "bmloYXJpa2E=",
"value": "bmloYXJpa2E="
}
}
}
很好,看起来我们的Tendermint内核与ABCI接口的工作一切正常!
在本文中,我们成功安装并启动了tendermint内核,然后通过节点旳ABCI接口提交了一个交易来更新内置键值库应用的状态,最后通过ABCI接口查询了ABCI应用的状态。这就是基于Tendermint进行应用开发的核心模型:可以使用任何开发语言来代替curl完成这些操作,实现自己的ABCI应用!