Cosmos被誉为“区块链的互联网”,旨在解决区块链可互操做性和可扩展性问题。其区块链间通信协议能够实现区块链的互联,支持不一样区块链之间的资产转移。随着区块链协同操做的需求愈加强烈, Cosmos做为跨链技术的佼佼者,值得咱们关注和学习。算法
摘要
本文给出了Cosmos IBC(互联链通讯)协议的技术规范,这个协议在2016年6月Cosmos白皮书中有过首次描述[1]。其它一些技术也能够在一个原子操做中涵盖两个链,好比“哈希时间锁定合同”[2],不过不少(此类技术)都仅限于保证两个交易同时成功或失败。IBC则建立了完整的双向“侧链”,真正地容许跨链传递价值,并充分利用Tendermint的即时最终性来实现代币的快速传递。数据库
IBC使用消息传递范式,并容许参与链保持独立。每一个链都维护一个局部的部分顺序,而消息则用于跟踪全部跨链的因果关系。一旦两个链之间注册了信任关系,就能够安全地将数据包从一个链发送到另外一个链上,表明从一个链上的一个帐户转移代币到另外一个链上的帐户。该协议也可扩展到代币转移以外(的其它功能) – 尽管为其余应用类型设计安全的通讯逻辑还待深刻研究。该协议对链之间传输数据包时的阻塞时间或网络延迟不作假设,所以在异构环境中具备很强的鲁棒性。安全
本文阐述了Cosmos IBC协议的要求和结构,目标是提供足够的细节来充分理解和分析协议的安全性。微信
如下是《Cosmos互联链通讯技术规范》译文的前半部分。网络
一 、简介架构
Cosmos IBC是围绕Cosmos网络和Tendermint共识引擎而设计的,从根本上依赖于Tendermint的即时最终性属性(意味着永远不会建立分叉)。Cosmos网络将由Cosmos枢纽和多个独立的分区组成,这些分区都经过IBC与枢纽进行通讯。Cosmos枢纽还能够经过在它们之间中继IBC消息来桥接不一样的分区。框架
咱们从一个简单情形的具体例子入手,它可用于为后续的抽象解释提供一个形式框架。在此以后,将解释这个例子中使用的消息传递语义。接下来就是安全证实和数据包传输所依赖的技术基础。异步
在此以后,将讨论更高级的消息类型,例如超时和路由(以使更大的网络在至关长时间内能高效运做),还要对协议处理全部可能状况的能力予以充分考虑。分布式
除了为IBC协议提供理论理解和参考文档以外,本文还旨在为协议的安全基础提出使人信服的论据。本文是对正在进行的Cosmos项目的一个报告,随着来自实践的数据不断更新理论,咱们也将持续调整它的内容。微服务
2、 示例场景
为了使讨论不那么抽象,这里用例子说明一个具体情形是如何工做的。Alice想从她在Cosmos分区X上的帐户发送30个wink币(示例代币名称)给Cosmos枢纽上的Bob。假设分区X已经跟枢纽创建了一个IBC链接,Alice将在分区X上建立一个交易来发起传输。分区X会将那些代币冻结在某个托管帐户,而后建立一个IBC数据包请求枢纽在Bob的帐户中建立相应数量的代币。本质上,分区X上的验证节点集合会保证销毁这些代币以换取在枢纽上重铸它们。
一个独立的中继进程(任何人均可运行的客户端软件)能够从分区X提取那个IBC数据包的证实并将其发布到枢纽。枢纽将验证区块头,Merkle证实和顺序号来确保这是一个从分区X来的有效的IBC数据包。这下咱们面临两个选择:要么分区X在枢纽上有足够信用来铸这30个wink币从而数据包被接受,要么信用不够而数据包被拒绝。若是数据包被接受,枢纽就在Bob的帐户中铸30个新鲜的wink币,并将数据包连同成功记录存在它的传入队列中;若是数据包被拒绝,则不会建立代币,且队列中会存入一个失败记录。
我说的“信用”指的是什么?咱们不但愿每一个链接到枢纽的链都能在枢纽上随意建立任意数量的任意代币,不然全部经济保证很快就变得毫无心义。枢纽必须使用它本身的逻辑来验证它是否足够信任分区X并接受那30个wink币。若是分区X是wink币的本源(X的原生代币),那么在发送wink币到枢纽这件事上,它将获得枢纽的极大信任。若是枢纽以前已经向分区X发送过500个wink币,那么它必须记住这个信息并容许分区X将(不超过)那500个wink币发送回枢纽,从而实现代币的自由流动。这个逻辑能够为代币传输提供安全性,其它应用则须要在不彻底信任网络中全部分区的状况下,运用它们本身的逻辑来维护全局约束条件。
在枢纽成功或不成功地执行了那个交易以后,咱们但愿将交易的收据(连同证实)传回到分区X以完成这个循环。此收据只是另外一种类型的IBC数据包,其执行方式与发送同样。惟一区别是,在发起分区处理收据毫不能产生错误。(根据收据内容)若是交易是成功的,则分区X将销毁托管的30个wink币,代币在分区间转移成功;若是交易因任何缘由被拒绝,那么托管代币就会释放回Alice的帐户 – 就像什么都没有发生过同样。
这意味着,在收到响应(成功或失败)以前,谁也不能碰分区X上的托管代币。除非咱们有证据证实该数据包被接收链拒绝,已经发出的代币不会被释放。没有代币会被无故建立或销毁,也不可能执行双花,代币不会莫名消失在跨链操做中。发送方只须要等待两个数据包的转发和执行(不少状况下是十来秒钟)。对处理硬分叉分区(如ETH/ETC或BTC/BCH)的考虑会在下面的高级章节讨论。
3、 消息传递语义
在试图扩展区块链时,必须找到一种不违反任何安全保证的可行方法,来增长并行写的数量。防止双花须要为任何给定帐户提供严格的串行访问(读和写),可是咱们须要一些安全的方法来容许多个交易同时执行,而又不给恶意利用竞态条件提供可能性。
经过IBC协议,咱们寻求避免一个问题,那就是容许多个独立节点将交易应用到相同的状态空间。若是你不想丢失任何数据(好比:强最终一致性),这个问题即使不考虑拜占庭角色也是困难的,在面对恶意行动人寻求利用任何不一致为自身牟利的状况下,则变得极其困难。安全地将不一样的部分排序协调成一致的全局排序的最严谨方法是CRDTs(无冲突数据复制类型),它保证一组固定交易的全部可选的部分排序都将收敛到相同结果。CRDTs确实颇有趣,但因为其固有特性,不容许在区块链用例中强制执行约束条件(例如,帐户余额永远不能为负数)。
这个问题的另外一个解决方案是使用分片,每一个分片都只能访问状态空间的一部分。这能够增长吞吐量,但也会使任何涉及多个分片的交易极难正确执行。触及多个分片并须要一致视图的查询能够经过使用快照来执行,可是在高度分布的环境中这可能很困难。若是您想在两个分片上安全地、原子地查询和修改数据,就须要相似锁和三阶段提交的机制,这在许多数据库中都使用过。可是,若是您想要保证顺序并在通讯层引入同步和定时假设,这就是一个阻塞操做,这使得它不适合分布式(多)区块链的场景。
咱们经过定义“分区”而走了一条不一样的路。每一个分区都是一个独立的区块链,有本身的应用逻辑,本身的交易和数据存储。分区应该沿使用界线分开,所以绝大多数交易只影响一个分区,但咱们能够保证任何跨链交易拥有安全和非阻塞的语义。每一个分区都是一个完整的独立系统,它们使用消息传递进行通讯。它们可以保证本地分区中的交易正确排序和执行,同时容许其它分区里的交易并行执行。惟一须要全局排序的东西是系统之间发送的消息。
分布式系统中的消息传递是一个已经被深刻研究的领域,也是许多其它系统的搭建基础。咱们可以对异步消息进行建模,且对信道不作时序假设。这样的结果是,咱们容许每一个分区以本身的速度行动,不被任何其它分区阻塞,却可以以当时网络容许的最快速度通讯。
使用消息传递做为原语的另外一个好处是,接收方可以对传入的消息应用本身的安全检查。仅仅由于一个咱们了解的分区发送了一条消息给某个特定账户添加50个以太币,并不意味着咱们必须增长余额。咱们能够在接收消息时添加咱们本身的业务逻辑,以决定咱们是否想拒绝该消息,以及咱们想如何处理它(若是咱们接受它)。在一个共享状态的场景中,很难甚至不可能作到这一点。消息传递容许每一个分区确保其安全性和自治性,同时容许不一样的系统做为一个总体协同工做。这能够看做是微服务体系架构的一个类比,可是跨越了组织边界。
为了在一个可证实的异步消息传递原语上构建有用的算法,咱们须要定义一些更高阶的结构在全部系统间共享,从而容许咱们和一些更容易的保证打交道。
3.1 可靠消息队列
咱们在这里引入的第一个原语是可靠的消息队列(如下简称队列),这是异步消息传递的典型构造,它使咱们可以确保因果排序并避免阻塞。
这个队列在每一个区块链的Merkle数据存储中以多个键值对的形式永续保存。每一个队列有一个独特的前缀,键是经过把一个表明其顺序号的8字节大端模式整数追加在这个前缀后面生成的。注意这个编码方式为咱们提供了一个与键的顺序号相一致的键的字典序,这让咱们能快速找到最新的数据包,也能证实在某个给定顺序位的数据包内容(或没有数据包) -- 假设像在咱们的IAVL+ Merkle树[3]里那样访问范围证实。
新增的任何一个数据包的顺序号只能比当前最高数据包的顺序号大1。为了使证实更容易,咱们会将顺序号也存在数据包自己(键值对的值)里面。一旦一个数据包被写入,它就是不可变的(除了在清理期间删除,这在后面会解释)。这使得接收分区能够接受位于源分区高度H的数据包Z的证实,而接收分区处理交易时尽可放心数据包在源分区里仍然以相同状态存在(异步性的要求)。区块链应用逻辑必须为全部队列保证这些约束条件,以确保消息层的正常运行。
假设咱们的IBC队列的前缀是0xCAFE,咱们能够看到多个数据包是如何存在Merkle树中的,而它们的顺序号又是如何追加(生成键)的,这样咱们就能够轻松地为某个给定数据包的存在(或不存在)提供一个Merkle证实。下面图示了构建顺序号为2的数据包的Merkle证实的路径,用橙色高亮显示。
本节的其他部分将定义可经过此队列发送的基本消息类型。
3.2 注册链(需经许可)
在两个链之间创建起链接以前,咱们须要先让它们彼此注册。这一点尤其重要,由于全部轻客户端证实都须要一个对验证消息头相当重要的信任种子,当有未经共识算法批准的恶意分支存在时,它能让咱们确认那条真的链。
为了在A和B之间造成链接,咱们必须在B上注册A,也要在A上注册B。这些过程是对称的,因此在这里咱们只描述如何在A上注册B。在注册时,A为B添加一个可信的消息头和验证节点集合,保存在它的安全数据存储中。这用于验证来自B的全部将来的消息头,以及验证节点集合的变动。A还要建立两个具备不一样名称(前缀)的队列。
ibc:<B的链标识>:out – 存放全部以B为目的地的传出数据包
ibc:<B的链标识>:in – 存放全部来自B的传入数据包连同它们的执行结果
注意,注册链应该是一个须要得到许可的操做,且执行时要有人工验证。这将产生一个信任声明,即这个消息头和验证节点集合表明了对应链的正确状态,它们不属于试图镜像这条链的某些影子链。不像PoW的最长链胜出算法,对权益证实而言信任必须在某个时点被明确授予。
并且,注册过程还必须定义好咱们用来验证Merkle证实的算法(这些证实存在于队列中的IBC数据包里)。缺省设置是来自咱们的IAVL树的Merkle证实格式,可是其余Merkle化的数据存储,好比Patricia Trie,也能够获得支持。这个算法必须在注册时设置一次,而且必须被参与链所支持。队列的整个生命周期都会基于可信的消息头,一致地使用该算法验证每一个数据包或收据。
3.3 验证节点变动
任何生产链的验证节点集合都会随着时间推移而发展变化。当咱们注册一个新链时,会针对一个特定的验证节点集合作一个信任声明 (更具体而言,咱们的信任绑定的是这样一个条件:消息头拥有超过必定阈值数量的与给定公钥集相匹配的数字签名)。当咱们信任的这组公钥变化时,咱们须要一个消息来把这个变动通知给其它链。因为验证节点变动对共识算法相当重要,因此咱们用一个标准格式把它存储在Tendermint的区块头内。
咱们定义一个特殊的更新数据包,它包含一个Tendermint区块头和新的验证节点集合,咱们能够将它发送给接收链。接收链能够核实验证节点集合变动的有效性,并使用它来验证全部将来的数据包。
3.4 发送数据包
发送一个IBC数据包涉及区块链应用逻辑调用IBC模块,告诉它须要发送的数据包以及目标链的标识。若是目标链已经注册好,IBC模块只需计算下一个顺序号并将其添加到传出队列out queue。顺序号与特定链接相关并由发送链生成,它们必须是单调递增和连续的。
数据包被写入Merkle化的数据存储,这样它就嵌入了和区块头相关联的证实当中。这些表明了数据包的键值对证实接下来就会被传送给其它链。
区块链应用程序必须对谁能够写一个队列的键空间作出限制,不是随便哪一个智能合约均可以在那里写交易数据,只有当区块链逻辑断定数据包有效,且与数据包类型相关的全局约束条件获得知足(好比:上面例子中的托管代币被冻结),才会生成(并写入)数据包。
3.5 中继数据包
为了让数据包到达目标链,咱们依靠一个或多个中继进程把链A上的传出证实out proof发布到链B的传入队列in queue中。因为这里只须要轻客户端证实,中继进程不须要是验证节点,甚至都不须要是全节点。实际上,若是每一个发起建立IBC数据包的用户也负责将它中继到接收链,那就太理想了。惟一的限制是,中继进程必须可以在目标链上支付适当的费用。
为了系统自举,链开发人员能够提供一个有足够资金的特殊帐号给中继进程,为全部数据包支付费用,直到用户在两个链上都有代币。不过,使用IBC的人应该本身负责支付这些费用。注意,更新消息头是一种代价高昂的交易(大约100个数字签名校验),而为一个已知消息头发布证实则要便宜得多(大约20个哈希计算)。所以,为了优化,许多数据包能够捆绑在一块儿在同一区块高度发送,即便它们是在不一样的区块高度建立的,这样能够经过增长一点延迟来节省计算成本。
系统必须容许多个中继进程安全地并行运行,拒绝掉任何重复的消息发布。但更理想的是能在起初就防止他们尝试重复发布,由于这会浪费带宽和链上的计算时间。
3.6 收据
当一个IBC数据包发布到另外一个链上并被认为是有效的(即,数据包的证实跟源链的已知消息头相匹配),则无论执行是否成功,咱们都必须将它存储在传入队列in queue里,这样就有证据代表它已经被处理过。相关交易应该发送到合适的智能合约加以验证和执行,而后返回标准的ABCI结果(成功或错误);收到的数据包连同处理结果被写进传入队列。
另外一个中继进程能够得到这个数据包已经在链B上处理过的证实,把它做为收据发布到链A。此收据将由链A处理,触发进一步的应用逻辑,以及对队列的清理(参见高级部分)。将请求从A中继到B的那个进程能够将响应从B中继回A,但也可使用一个不一样的进程来作这件事。
做者:Ethan Frey, frey@tendermint.com
译者:奚海峰 Haifeng Xi
校对:曹恒 Harriet Cao
本文首发于万云Wancloud微信号,未经受权不容许转载。
。