拜占庭共识Tendermint介绍及简单入门

1.Tendermint是什么

  Tenermint 是一个软件,用于在多台机器安全一致地复制一个应用。所谓安全,指的是即使有多达 1/3 的机器出现任意故障的情况下, Tendermint 仍然能够正常工作。所谓一致,指的是每一个正常工作的机器都会有着同样的交易日志,计算相同的状态。安全一致的复制是分布式系统中一个至关重要的问题:从货币到选举,到基础设施规划,它在广泛应用的容错中承担了一个极其重要的角色。

  能够容忍机器以任何一种,甚至包括危害系统的方式发生故障,被称为拜占庭容错(BFT)。拜占庭理论已经有几十年的历史,但是很大程度上,直到最近像比特币,以太坊这样区块链技术的成功,它的软件实现才得以进一步发展。区块链技术只是以一种现代化的方式对 BFT 的再形式化,而且重点关注 p2p 网络和密码验证。区块链这个名词来源于交易的处理方式,通过区块的批量方式处理交易,每个块包含了前一个块的加密哈希,以此来形成一个链。实际上,区块链数据库真正地优化了 BFT 设计。

  Tendermint 包含了两个主要的技术组件:一个区块链共识引擎和一个通用的应用程序接口。共识引擎,叫做 Tendermint Core,保证了每一台机器以相同的顺序记录同一笔交易。应用程序接口,叫做应用程序区块链接口(ABCI),保证了交易可以通过任何一种编程语言进行处理。与其他预先打包内置状态机(比如键值存储或者一个奇怪的脚本语言)的区块链和共识方案不同,开发者可以使用 Tendermint 实现应用的 BFT 状态机复制,而这些应用可以用任何语言编写,而且开发环境对开发者也十分友好。
  Tendermint 的设计原则是易使用,易理解,高性能,对于各种分布式应用都十分有用。
  Tendermint 说明文档:https://tendermint.readthedocs.io/en/master/
  Tendermint 地址:https://github.com/tendermint/tendermint

Tendermint 与其他技术的比较

  大体上, Tendermint 与两类软件很类似。第一类包含了分布式的键值存储,比如 Zookeeper,etcd 和 consul,它们都使用了非拜占庭容错共识。第二类就是 “区块链技术”,它既包括了像比特币和以太坊这样的加密货币,也包括了像 Hyperledger Burrow 这样的分布式账本设计。

Zookeeper, etcd, consul

  Zookeeper,etcd 和 consul 都是在一个经典的非拜占庭容错共识算法上, 实现了一个键值存储。Zookeeper 使用了 Paxos 一个叫做 Zookeeper Atomic Broadcast 的版本,而 etcd 和 consul 则使用了更年轻,也更简单的 Raft 共识算法。一个典型的集群由 3-5 台机器构成,虽然可以承受 1/2 的机器发生问题,但是只要发生一次拜占庭故障,整个系统就可能被摧毁。它们每一个都提供了一个稍微有别于键值存储的实现,但是都将关注点放在提供分布式系统的基础服务上,比如动态配置,服务发现,锁定,领导人选取等等。
Tendermint 是一个本质上类似的软件,不过有两点关键不同:它是拜占庭容错的,这意味着它可以承受 1/3 机器发生任意形式的故障 – 包括黑客和恶意攻击。
  它并不像键值存储,是针对某一指定类型的应用。相反,它关注于任意的状态机复制,因此开发者可以量身打造适合自己的应用逻辑,从键值存储到加密货币到电子投票平台,甚至更多的应用都可适用。

Bitcoin, Ethereum, etc.

  在比特币和以太坊这样的传统加密货币下出现了 Tendermint,它的目的在于提供一个比比特币的工作量证明更加有效和安全的共识算法。在早期,Tendermint 内置了一个简单的货币来参与共识,用户必须向一个保证金账户中“绑定”一定数量的货币,如果他们表现不端,这些钱就会被收回 – 这一点使得 Tendermint 成为一个 POS 算法。
  自那时起,Tendermint 就进化为一个能够承载任意应用状态的通用区块链共识引擎。这意味着它可以成为其他区块链软件共识引擎的一个即插即用的替代品。所以基于当前的以太坊代码库,无论是用何种语言, Rust,Go,Haskell,任何人都可以使用 Tendermint 共识运行一个 ABCI 应用。实际上,我们已经完成了这一点(ethermint)。此外,我们也计划为 Bitcoin,ZCash,和其他确定性的应用完成同样的工作。另一个基于 Tendermint 构建的加密货币应用是 Cosmos。

Fabric, Burrow

  Fabric 0.6 采用了与 Tendermint 类似的方法,但是它更关注对状态的管理,并且要求所有的应用行为能够在多个 docker 容器,叫做 “chaincode” 的模块中运行。它使用了来自 IBM (augmented to handle potentially non-deterministic chaincode) 的 PBFT 实现。通过扩展 Tendermint 来处理未来工作中存在的不确定性,在 Tendermint 中通过一个 ABCI 应用实现这个基于 docker 的行为是完全有可能的。Burrow 是一个以太坊虚拟机和以太坊交易机制的实现,同时附带有名字注册,许可权和天然合约,可替代区块链 API 等额外特性。它使用 Tendermint 作为它的共识引擎,提供一个特殊的应用状态。

2. 什么是 ABCI (应用区块链接口)

区块链应用接口(Application BlockChain Interface,ABCI)允许应用的拜占庭容错复制可以由任意一种编程语言编写。
  Tendermint Core (“共识引擎”)通过一个满足 ABCI 标准的 socket 协议与应用进行交流。
  举个大家比较熟悉的例子,比特币。比特币是一个加密货币区块链,其中的每个节点维护了一个完全经过审计的 UTXO 数据库。如果有人想要在 ABCI 之上创建一个类似比特币的系统,Tendermint Core 将会负责:

  • 在节点间共享区块和交易
  • 建立交易(区块链)的标准/不可变顺序

而应用将会负责:

  • 维护 UTXO 数据库
  • 验证交易的加密签名
  • 阻止花费尚未存在的交易
  • 允许客户端查询 UTXO 数据库

ABCI 包含了 3 个主要的消息类型,它们由 core 发送至应用,应用会对消息产生相应的回复:
  DeliverTx 消息是应用的主要部分。链中的每笔交易都通过这个消息进行传送。应用需要基于当前状态,应用协议,和交易的加密证书上,去验证接收到 DeliverTx 消息的每笔交易,。一个经过验证的交易然后需要去更新应用状态 – 比如通过将绑定一个值到键值存储,或者通过更新 UTXO 数据库。
  CheckTx 消息类似于 DeliverTx,但是它仅用于验证交易。Tendermint Core 的内存池首先通过 CheckTx 检验一笔交易的有效性,并且只将有效交易中继到其他节点。比如,一个应用可能会检查在交易中不断增长的序列号,如果序列号过时,CheckTx 就会返回一个错误。又或者,他们可能使用一个基于容量的系统,该系统需要对每笔交易重新更新容量。
  Commit 消息用于计算当前应用状态的一个加密保证(cryptographic commitment),这个加密保证会被放到下一个区块头。这有一些比较方便的属性。现在,更新状态时的不一致性会被认为是区块链的分支,分支会捕获所有的编程错误。这同样也简化了保障轻节点客户端安全的开发,因为 Merkel-hash 证明可以通过在区块哈希上的检查得到验证,区块链哈希由一个 quorum 签署。
  一个应用可能有多个 ABCI socket 连接。Tendermint Core 给应用创建了三个 ABCI 连接:一个用于内存池广播时的交易验证,一个用于运行提交区块时的共识引擎,还有一个用于查询应用状态。
  很显然,在创建区块链时,应用的设计者需要非常小心地设计他们的消息处理,这个架构提供一个范例。下图阐释了通过 ABCI 的消息流:
  这里写图片描述

3. 共识概述

  Tendermint 是一个易于理解,大部分操作为异步的 BFT 共识协议。下图是一个简单的状态机,它展示了协议遵循的规则:
这里写图片描述
  协议中的参与者叫着 “验证人”(validator)。他们轮流对交易区块进行提议,并对这些区块进行投票。区块会被提交到链上,每一个块占据一个“高度”(height)。提交块可能会失败,如果失败,协议就会开始下一轮的提交,并且一个新的验证人会继续提交那个高度的区块。要想成功提交一个块,需要有两个阶段的投票:“预投票”(pre-vote)和“预提交”(pre-commit)。在同一轮提交中,只有超过 2/3 的验证人对同一个块进行了预提交,这个块才能被提交到链上。
  上图右下角有一对夫妇在跳波卡舞,因为验证人做的事情就像是在跳波卡舞。当超过 2/3 的验证人对同一个块进行了预投票,我们就把它叫做一个“波卡”(polka)。每一个预提交都必须被同一轮中的一个波卡所证明。
  由于一些原因,验证人可能在提交一个块时失败:当前提议者可能离线了,或者网络非常慢。Tendermint 允许他们证实一个验证人应该被跳过。在进行下一轮的投票前,验证人会等待一小段时间从提议者那里接收一个完整的提议块。这种对于超时的依赖,使得 Tendermint 成为了一个弱同步协议,而非一个异步协议。但是,协议的剩余部分都是异步的,只有在接收到超过 2/3 的验证人集合时,验证人才会采取下一步操作。Tendermint 能够简化的一个原因就是它使用了同样的机制来提交一个块和跳过直接进入下一轮。
  基于不到 1/3 的验证人是拜占庭节点的前提,Tendermint 保证了永远都不会违背其安全性 – 也就是说,验证人永远不会在同一高度提交冲突块。为了达到这一点,它引入了一些 “锁定”(locking)的规则,这些规则对流程图中的路径进行了模块化。一旦一个验证人预提交了一个块,它就被“锁定”在了那个块上。然后,
1. 它必须为被锁定的那个块进行预投票
2. 只有在之后的轮中,有了那个块的一个波卡,它才能够解锁,并为一个新块进行预提交。

4. 简单入门

下载编译

mkdir -p $GOPATH/src/github.com/tendermint
cd $GOPATH/src/github.com/tendermint
git clone https://github.com/tendermint/tendermint.git
cd tendermint

linux环境编译:

make get_tools
make get_vendor_deps
make install

Windows环境编译:

cd cmd\tendermint
go build

编程完成得到tendermint.exe文件

下载编译abci

go get -u github.com/tendermint/abci/cmd/abci-cli
cd cmd/abci-cli
go build

编程完成得到abci-cli.exe

启动KVStore 第一个例子

tendermint启动:

tendermint.exe init --home d:\tendermint
tendermint.exe node --home d:\tendermint

kvstore启动:

.\abci-cli kvstore

测试
可以使用postman进行测试

## 查看状态
curl -s localhost:46657/status
## 新建tx
curl -s 'localhost:46657/broadcast_tx_commit?tx="abcd"'
## 查询新建的tx
curl -s 'localhost:46657/abci_query?data="abcd"'

启动Counter 第二个例子

tendermint启动:

tendermint.exe unsafe_reset_all
tendermint.exe node --home d:\tendermint

kvstore启动:

.\abci-cli counter --serial

测试

## 创建成功
curl localhost:46657/broadcast_tx_commit?tx=0x00
## 创建失败
curl localhost:46657/broadcast_tx_commit?tx=0x05
##查看
curl localhost:46657/abci_query?path="tx"

总结

  tendermint是一款非常强大的共识软件,不过目前尚未到1.0版本。官方基于tendermint修改了Ethereum的共识协议完成了ethermint,同时官方基于tendermint 构建了cosmos公有链。
  tendermint还可以用于在联盟链中作为共识协议,比如秘猿cryptape联盟链使用tendermint来做共识。
  总的来说,tendermint不管在共有链还是联盟链中都是大有可为的,值得深入学习研究。笔者在后续 的文章将讲讲tendermint的深入使用和原理。

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值