您正在查看: Other Chain 分类下的文章

Cosmos之Tendermint架构分析

一、介绍

有人把Tendermint当成一个共识,有人把它当成一个通信组件。这都是可以理解的。Tendermint融合了共识和网络通信部分。它类似于一个软件包,通过使用Tendermint可以很容易的开发一个和Cosmos相兼容的区块链(当然,如果使用Cosmos-sdk会更简单,但是会屏蔽更多的细节)。可以把它理解成Cosmos的一个底层架构,提供类似于基础服务的一个平台。Tendermint可以提供一个Cosmos标准的跨链的基础应用。

通过上面这个图可以看出Tendermint在整个Cosmos生态中的位置。Tendermint Core是所有Cosmos生态中区块链的核心(上图中的淡绿色部分),提供了DPOS+BFT的共识机制。Cosmos Hub提供了不同区块链的之间的交互和价值转移。各个区块链应用之间通过IBC接口进行通信。

二、整体架构

1、BFT

Tendermint使用的共识算法是拜占庭容错共识协议,它是来源于DLS共识算法。使用这种算法的目的是可以简单方便的解决区块链的分叉机制。这种BFT的机制要求有固定的一组验证人,然后他们会尝试在某个区块上达成共识。每个区块的共识轮流进行,每一轮都有一个提议者来发起区块,之后由验证人来决定是否接受区块或者进入下一轮投票。

Tendermint采用由绝对多数的选票(三分之二)待定的最优拜占庭算法。因此它可以确定的做到:

如果想做恶,必须要有三分之一以上的选票出现问题,并且提交了两个值。
如果任何验证组引起安全问题,就会被发现并对冲突进行投票,同时广播有问题的那些选票。
因为使用了BFT,所以其共识的速度在所有的共识中最相当快速的,很容易达到并维持每秒千笔交易的速度。

2、P2P

Tendermint中的网络底层通信,使用的是一种普通的反应器,它通过参数来查找需要连接的P2P节点,在Tendermint的节点连接中,维护着两组映射来管理连接自己和自己连接的对象,分别称做inbound,outbound.
outbound中,有两种连接,一种是连接时指定的seed,一种是在初始化时检测出来的节点。一般情况下,outbound的数量少于10个。而inbound控制在50个左右的连接。
既然是基于反应器的,那么编程的复杂性就大大降低了。只需要服务监听就可以了。这里不再细节赘述网络通信部分。
网络在启动时,会启动一个协程,定时轮询outbound的数量,来控制连接的稳定性。

3、架构

Tendermint的设计目的是为了创建一个统一的区块链开发的基础组件。通过将区块链中主要的P2P和共识抽象出来,实现区块链开发过程中的组件式管理。这样做的优势有以下几点:

一个是代码重用。对通用的网络通信和共识就不必再重复的造轮子。

二是解放了区块链编程的语言。比如以太坊用go,c++,但是通过Tendermint的抽象后,可以使用任何语言(觉得和当初JAVA才提出时一次编译的想法有些相似啊)。特别是对于智能合约,这个优点就更显得明显了。

4、Tendermint的共识过程

Tendermint共识机制中通过作验证人(Validators)来对区块达成共识,这个在前面已经介绍过,一组验证人负责对每一轮的新区块进行提议和投票。整个共识达成的过程如下图所示。

每一轮的开始(New Round),节点对新一轮的区块进行提议。之后,合格的提议区块首先经过一轮预投票(Prevote)。在提议区块获得2/3以上的投票后,进入下一轮的预认可(Precommit),同样是待获得2/3以上的验证人预认可后,被提议区块就正式获得了认可(Commit)。而得到认可的这个区块就被添加的到区块链中。

下面为详细的过程:

在Tendermint算法中,如果遇到对同一特定区块的同意及否决信息同时超过2/3的情况,需要启用外部的维护机制去核查是否存在超过1/3的验证节点伪造签名或者投出双重选票。

5、Tendermint的交易流程

当一个Tx进来时, Tmcore的mempool(MP)会通过mempool connection(一个socket连接,由abci-server提供)调用Application Logic(AL:也就是abci-app,我们自己用任何语言编写的APP逻辑)里的checkTx方法,AL向MP返回验证结果。MP根据验证结果通过或者拒绝该Tx。

Tendermint(TM)把tx暂存在内存池(mempool)里,并把这条Tx通过P2P网络复制给其它TM节点。TM发起了对这条Tx的拜占庭共识投票,所有Tendermint节点都参与了。投票过程分三轮,第一轮预投票(PreVote),超过2/3认可后进入第二轮预提交(PreCommit),超过2/3认可后进入最后一轮正式提交(Commit)

TM提交Tx时依次通过Consensus Connection(一个socket连接,由abci-server提供)向ABCI-APP发送指令BeginBlock-->多次DeliverTx-->EndBlock-->Commit,提交成功后会将StateRoot(application Merkle root hash)返回给TM,TM New出一个区块。

如下图所示的交易流程图:

三、总结

通过上面的分析可以看到,其实Tendermint的重点在于共识和P2P,将二者抽象出来的有利之处在于,可以让开发者忽略对网络通信和共识的复杂性。直接进行业务层面的开发,而SDK的封装,进一步减少了业务上对非相关的逻辑的考虑,大大减少了开发者生产一条区块链的复杂度,而这也恰恰是Tendermint和cosmos-sdk所想达到的目的。

转载自:https://zhuanlan.zhihu.com/p/295557240

Delivery层初始化配置

Delivery层初始化配置

首先需要和bttc层一样准备一个genesis配置,如果是同步现有测试网或者主网,可以官方仓库拿到

主网:https://github.com/bttcprotocol/launch/blob/master/mainnet-v1/without-sentry/delivery/config/genesis.json

测试网:https://github.com/bttcprotocol/launch/blob/master/testnet-1029/without-sentry/delivery/config/genesis.json

如果是启动私链也可以自己创建,deliveryd程序也提供了初始化测试链的功能,比如需要创建一个私链,3个验证者2个同步节点

./deliveryd create-testnet --v 3 --n 2 --output-dir ./output --chain-id delivery-9528

执行完成后,会自动创建5个节点对应的配置文件,每份主要的配置如下

genesis.json

初始化链配置,主要关心以下字段

  • chain_id 链id

  • app_state->accounts 初始化账户资金等信息

  • bor->spans->validator_set->validators 初始化验证者信息

  • bor->spans->validator_set->proposer 初始化提案者信息

  • bor->spans->selected_producers 初始化当前生产者信息

  • bor->spans->bor_chain_id bttc层链id

  • chainmanager->chain_params 链合约相关地址

  • checkpoint 配置相关参数

  • gov 治理相关参数

  • slashing 惩罚相关参数

  • staking 初始化相关地址抵押量

对于私链,在初始化数据基础上,主要关注chain_id和chain_params,其余地址相应数据使用默认即可

config.toml

链基础配置,主要关心参数如下

  • fast_sync:是否开始快速同步

  • db_dir: 数据的存放位置

  • genesis_file:genesis.json存放位置

  • priv_validator_key_file:验证者私钥文件位置

  • priv_validator_state_file:验证者状态文件位置

  • node_key_file:节点密钥存放位置

  • persistent_peers:持久链接的peer地址,类同于eth的staticnode

  • private_peer_ids: 私有的节点id, 用于隐私接入,比如哨兵节点

    • 登录验证人节点.
    • 运行 deliveryd tendermint show-node-id. 示例: private_peer_ids = "e2c6a611e449b61f2266f0054a315fad6ce607ba"
delivery-config.toml

RPC和 REST配置,主要关心参数如下

  • eth_rpc_url:eth链RPC地址

  • bsc_rpc_url:bsc链RPC地址

  • bttc_rpc_url:bttc层RPC地址

  • tron_rpc_url:tron链RPC地址

  • 测试网:47.252.19.181:50051

  • tron_grid_url:tron链grid地址

  • 测试网:https://test-tronevent.bt.io

  • amqp_url:AMQP地址,在bridge过程中会用于任务的消息队列

node_key.json

节点的密钥信息,可以使用工具自动生成

priv_validator_key.json

节点验证者的密钥信息,可以使用工具自动生成

对于单节点测试,也可以直接执行初始化

./deliveryd init --chain-id delivery-9528 --home ./

plasma与侧链区别

侧链

优点

实现上相对简单易用

缺点

但需要在信任侧链的基础之上,如果侧链失败(意味着共识机制受到损害),您可能会损失所有资金。

相对解决

通常是只跨小额临时使用的代币,将风险人为控制降低。

plasma

优点

plasma在设计上比侧链更安全。(用户可以使用区块根来表明他们在 Plasma 链上收到了资金,如果 Plasma 链共识机制停止创建区块,用户可以使用区块根向以太坊提出索赔)

缺点

不能真正进行与侧链相同的复杂操作。不做信任假设来保证资金安全,所以我们总是不得不假设 Plasma 链共识机制随时可能失败,需要围绕它进行设计。这对 Plasma 链上可能发生的事情增加了额外的限制。主要缺点是你不能真正进行与侧链相同的复杂操作

参考

https://docs.plasma.group/en/latest/src/plasma/sidechains.html

VRF可验证随机函数

Why VRF?

场景

在区块链场景中,有的框架会用算法随机产生出块节点与验证节点(如Algorand),甚至解决分叉。按传统的随机算法,按一定的哈希规则随机轮询,选出一个节点来记账/验证。如果这个随机轮询的规则是谁都可以复现的,那么可以推测出将来的某个记账/验证节点,集中攻击它。
为了解决这个问题,就引入了VRF,只有自己能够完成这个哈希过程,而别人只能在他声明之后验证这个过程,防止有人可以提前推测出将来的记账节点。

POS中的权益研磨(Grinding)

(以下来源于以太坊Github上的《Proof of Stake FAQ》)
在任何基于区块链的权益证明算法中,都需要某种机制,来随机从当前活跃验证者集合中选择能够产生下一个区块的验证者。举个例子,如果当前活跃的验证者集合由持有40以太币的Alice,持有30以太币的Bob,持有20以太币的Charlie与持有10以太币的David组成,那么你想让Alice成为下一个区块的创建者的概率为40%,而Bob的概率为30%等(在实践中,不仅要随机选择一个验证者,而是要(随机产生)一个无限验证者序列,只有这样如果Alice不在线的时候,就可以有其他人在过段时间替代她,但是这并没有改变问题的本质)。在非基于区块链的算法中,出于不同的原因也经常需要考虑随机性。
(以下来源Ouroboros白皮书《Ouroboros: A Provably Secure Proof-of-Stake Blockchain Protocol》)
基于PoS的区块链协议最基本的一个问题就是模拟领导者选举过程。为了在股东们之间的选举达到一个真正的随机性,系统中就必须要引入熵(entropy),但引入熵的机制可能会容易被敌手操作。例如,一个控制一群股东的敌手可能会试图模拟协议的执行,尝试不同的股东参与者的顺序以此来找到对敌对股东有力的继续者。这会导致一个叫做"grinding"的致命弱点,敌对参与者可能会使用计算资源来倾斜领导者选举。

VRF的目的

VRF的目的就是要生成随机值,且无法被预测,同时还要可验证,可重放。

VRF是什么?

VRF是可验证随机函数(verifiable random function),一方面具有伪随机性,另一方面它还具有可验证性(输出包括一个非交互零知识证明)

  • 伪随机性
  • 可验证性
    VRF的方式是,实现本地抽签,各个节点自己抽签,如果抽中了之后,大家可以很容易地验证这个结果确实是你生成的。

eg. 假设现在是round 10(第10 轮),节点们可能会轮流抽签,以节点自己的私钥+ 一个全网都知道的随机数(比如是这轮的轮次10)作为输入,生成了一个随机数(0-100);设置一个条件:100 个节点轮流抽签,谁先抽出来的随机数大于10,就是这一轮的打包者。假设5 号节点抽到了11,可是只有5 号知道其他人不知道,因此他在广播这个随机的同时还需要广播一个零知识证明。通过零知识证明,全网只需要通过5 号的公钥就可以验证,接受5 号为这轮打包者。图解如下:

VRF具体的操作流程?

  • 证明者生成一对密钥,PK、SK;
  • 证明者计算result = VRF_Hash(SK,info),proof = VRF_Proof(SK,info);
  • 证明者把result,proof,PK递交给验证者;
  • 验证者计算result = VRF_P2H(proof),True/False = VRF_Verify(PK, info, proof)

True表示验证通过,False表示验证未通过。所谓的验证通过,就是指proof是否是通过info生成的,通过proof是否可以计算出result,从而推导出info和result是否对应匹配、证明者给出的材料是否有问题。

抽签有没有必要用VRF?

相比随机预言机

  1. 普通哈希Hash(a)=b,所有人都可以重现,检验正确性;
  2. VRF是Hash(SIG(sk, a))=b,别人无法复现这个过程。但是可以拿b,pk,和中间信息验证b是跟a对应的。

    相比非对称加密

  3. 在密码学签名算法中,大都会引入随机性,也就是对相同信息的多次签名会得到不同的签名值,因此矿工可以不断对相同的输入SK和block,计算签名,以满足结果小于D。那么理论上任何人都会成为出块者,只要计算足够多次的签名。
  4. 有些非对称加密方式得到的随机数不是均匀分布的,如RSA
  5. 缺乏零知识,不管使用确定性签名还是随机性签名,都存在个安全隐患。就是一旦将自己的出块凭证公布,任何人都可以公开验证,包括攻击者。那么攻击者可以对出块节点进行攻击,使其不能出块。使用VRFs的方式,矿工只需要公布自己的R表明自己的出块权,当出完块的时候再公布P,那么攻击者就无法在出块之前知道谁具有出块权,因此也就无法实施针对性的攻击。

应用

  1. Consensus:共识算法中安全性
    VRF Sortition,Smart Contracts,例如本体,Cardano,Dfinity,Algorand等,不同点在于如何产生输入以及输出怎样用。VRF的返回结果可以用来公开或私密地完成节点或节点群体的选择。eg. Dfinity利用mod操作来唯一,公开的确定一个group。Algorand,Ouroboros Praos是私密选择,即计算出哈希值后,如果哈希值小于某个阈值,节点可以私密地知道自己被选中。

本体-VBFT共识算法:

  1. 根据VRF 从共识网络中选择备选提案节点,各个备选节点将独立提出备选区块;
  2. 根据VRF 从共识网络中选择多个验证节点,每个验证节点将从网络中收集备选的区块,进行验证,然后对最高优先级的备选区块进行投票;
  3. 根据VRF 从共识网络中选择多个确认节点,对上述验证节点的投票结果进行统计验证,并确定出最终的共识结果。
  4. 所有节点都将接收确认节点的共识结果,并在一轮共识确认后开启新的共识。

Algorand中:

  1. 先选打包者,选完打包者选委员会,委员会用BA*进行选区块。
  2. 输入值由前一个随机数(最初的随机数是协议给定的)和某种代表高度,轮次的变量进行组合,然后用私钥对之进行签名(或者先签名再组合),最后哈希一下得出最新的随机数。
  3. 条件:①签名算法应当具有唯一性;②避免在生成新随机数时将当前块的数据作为随机性来源之一。

Dfinity中:

交保证金提高门槛,并降低参与节点的数量,然后选打包者,选完打包者选公证人,对区块权重进行排序,选出区块。

Cardano的共识机制-Ouroboros Praos:

在根据Random seed选举slot leader时,通过VRF确保slot leader不被事先计算出来被攻击。


  1. IOST的高效分布式分配片
    使用了VRF来进行领头节点的选举,通过VRF得到随机数之后,会将结果进行广播,然后其他节点会进行统计,得到随机数值最小的作为分片领头节点。是一种交互式的选举方式。
  2. Key Transparency
    密钥管理系统,使消息传递在不相信服务端的情况下做到点对点的安全上的提升。
  3. DNSSEC
    DNS服务的安全性。

参考文献

  1. Randao可证公平随机数白皮书
  2. 一文看懂可验证随机函数VRF
  3. Ouroboros:一个可证明安全的PoS区块链协议 白皮书
  4. Proof of Stake FAQ
  5. 黄祺-区块链中VRF的应用及原理解析 视频资源
  6. Cardano(ADA)的共识算法Ouroboros
  7. 对可验证随机函数VRF的简明解释
  8. VRF wiki
  9. VRF原文
  10. VRF在区块链中的应用

原文链接:https://blog.csdn.net/shangsongwww/article/details/88797403