项目简介
Band Protocol 项目最初于 2017年成立并建立在 ETH 之上。后于2020年转移到了 Cosmos 网络上,基于 Cosmos SDK 搭建了一条 Band Chain 。这是一条 oracle-specific chain,主要功能是提供跨链预言机服务。Cosmos生态上第一个,也是目前最火的去中心化的跨链预言机。
架构总览
Band Protocol 通过发布在链上的 Oracle Script 提供预言机服务。(任何用户都可以定制和发布自己的 Oracle Script)
本地用户,可以通过直接向 Band Chain 发送 MsgRequestData 的方式 (一种Tx) ,向指定的 Oracle Script 申请预言机服务。(Oracle Script中指定了 data sources 和聚合方法)
Cosmos生态的项目可以通过 IBC 发送 MsgRequestDataPacket 给 Band Chain 申请预言机服务。
每一次预言机请求产生的最终结果都会存储在链上并产生一个 Proof (基于 Merkel Proof) 。异构链在使用 Band Chain 上的预言机数据的时候,可以通过 Bridge Contract 将 (data, proof) 交给 Lite Client 去验证其是否合法。
基于 Band Protocol 的特点,主要分为以下三个板块进行分析
- 可定制的预言机服务 基于 Oracle Script 和 Data Source Script,用户可以自由定制预言机服务
- 去中心化的预言机服务 基于Cosmos SDK开发了一条 Oracle-Specific 的 Band Chain
- 跨链交互 基于Cosmos,可以通过 IBC 与其他 Cosmos 链交互。使用 relayer + tx proof ,使其预言机数据在异构链跨链使用时,也可以通过 Lite Client 进行可信验证。
可定制的预言机服务
所有的去中心化预言机服务,都免不了两个行为
-
【多个节点】从【多个数据来源】获取数据
-
将来自【多个节点】的数据结果,聚合成一个最终答案
Band Protocol 使上面两个行为变得可以定制。
通过 Data Source script ,用户可以自由构建并发布【数据来源服务】到链上。
而通过 Oracle Script ,用户可以自由的选择多个链上存在的【数据来源服务】作为预言机服务的数据来源,并且定制最终结果的聚合方法。
Data Source Script
指定脚本规范和构建支持多语言的执行器。
用户需要编写一个【可执行文件】,用于抓取指定的链外数据,样例如下
Executable例子 展开源码
创建Data Source的过程,可以看做是发起交易将【可执行文件】上链的过程。任何用户都可以发送 MsgCreateDataSource 给 chain 去创建 data source 服务。其中包含的参数如下
参数 | 类型 | 描述 |
---|---|---|
Sender | sdk.AccAddress | 消息发送者的地址 |
Owner | sdk.AccAddress | (可选)这个data source服务的拥有者地址 |
Name | string | 这个data source服务的名字 |
Description | string | 这个data source服务的描述 |
Executable | []byte | 可执行文件,这个data source服务的请求者会执行这个文件去获取数据。(支持多种语言) |
Treasury | sdk.AccAddress | 服务费的收款地址 |
Fee | sdk.Coins | 这个data source服务的服务费 |
Data Source的【可执行文件】的执行是发生在链外,所以不会产生gas费用。
Oracle Script
指定规范,并使用了 WebAssembly 来执行。
任何人都可以通过Oracle Script去创建自己的Oracle服务。
可以用WebAssembly支持的语言编写以下两个方法:
- Preparation Method:这个方法会构建 data source queries ,其中包含data source script ID 和 input params 。 (data source query 会用于执行指定的 data source script ,来获取数据)
- Execution Method:这个方法会将来自多个Validator的数据报告聚合成一个最终的数据结果
将脚本代码编译成二进制的wasm code后,就可以通过发送 MsgCreateOraceScript 将其上链。
这两个方法分别会在 Preparation 阶段和 Execution 阶段在链上执行:
- 节点收到 Oracle Request ,进入Preparation阶段。节点需要执行Preparation方法,去构建出多个Data Source Queries (其中指定Data Source脚本和入参)。
- 节点根据 Data Queries 执行 Data Sources 脚本,获取到数据结果并提交报告
- 当报告的数量满足一定需求时,进入Execution 阶段。节点会执行Execution方法,从所有报告中聚合出一个最终结果并保存
去中心化的预言机服务
预言机服务流程
技术点:将预言机服务本地化,植入到了链本身层面。
(MsgRequestData 和 MsgReportData 本质上都是发起一笔交易)
-
用户发出 MsgRequestData 请求链外数据,其中包含信息:
Parameter
Type
Description
OracleScriptID
int64
Oracle Script的ID
Sender
sdk.AccAddress
消息发送者的地址
Calldata
string
传给Oracle Script的执行参数
AskCount
int64
需要随机选择多少个Validator来执行此请求
MinCount
int64
需要至少【MinCount】个Validator提交结果才算请求成功
ClientID
string
Client ID,由用户自己设定,聚合结果回传的时候也会带上这个ID
- 通知节点网络执行数据请求
- Validator根据请求中的 Calldata 在 wasm 环境下执行 Oracle Script 的 【Preparation方法】,构建出一系列的data source queries
- 根据请求中指定的 AskCount 随机选出一组 Validator 子集 (随机规则 Validator Sampling)
- 被选中的 Validator 在链下执行 data source queries ,获取到数据结果 (这里属于链下执行,和链上无关)
-
子集中的 Validator 将数据结果封装成 MsgReportData 并提交到链上,其中包含以下信
Parameter
Type
Description
RequestID int64 请求的ID Validator sdk.ValAddress 验证者的真实地址 Reporter sdk.AccAddress 验证者用于签名的地址 Data []struct'{ externalDataId: int64, data: []byte }' 从data sources那里查询到的数据结果 - 在【区块执行的 execute tx 阶段】发现提交的报告数量大于等于 MinCount 则会在 【区块执行的 end block 阶段】对 reports 进行聚合
- 聚合是,Validator 会执行 Oracle Script 中的 【Execution方法】来聚合出最终结果并持久化到区块当中。
(同时也会产生一个包含本次【请求和结果信息】的Merkle Proof,用于跨链验证数据结果的有效性) - 如果超过设定时间,数量还是小于MinCount,则本次数据请求失败
随机采样 Validator Sampling
技术点
和大多数的链上随机数方案差不多,引入多个最近历史区块hash构建seed,防止随机数被控制
因为Band Chain中Validator数量很多,如果让所有节点去执行Oracle请求会导致性能瓶颈。所以Band Chain会通过Decentralized Validator Sampling(去中心化的验证者采样)去随机挑选出一个验证者子集去执行Oracle请求。
选举规则的设计如下
- 构建随机seed
- RollingSeed,是从前 n 个 blockhash 中各取出 32/n 个 bytes组合成的一串新的 bytes 。(目前 n = 32 ,也就是从前 32 个 blockhash 中各取一个 byte 来组成 rollingSeed)
防止Validator控制seed,因为其作为出块人一般只能控制其中的 n/32 个 bytes (或者说一个 blockhash) - Oracle请求的requestID
- BandChain的chainID
- RollingSeed,是从前 n 个 blockhash 中各取出 32/n 个 bytes组合成的一串新的 bytes 。(目前 n = 32 ,也就是从前 32 个 blockhash 中各取一个 byte 来组成 rollingSeed)
- 生成随机数rng
- 将Validator按照权重降序排序,并将其按照权重值展开,例子如下:
- 所有Validator的权重求和,得到sum
- 将 rng%sum ,取余后获得 luckyNumber
- 根据luckyNumber落于哪个{X,Y}区间,选择Validator。(例如,luckyNumber = 178,则选中Validator #2 ,因为其区间为{101,185})
选取多个 Validator 时,只需要将上一个选中的Validator从列表中移除,然后重复上面的步骤 3 - 6 即可。
跨链交互
Cosmos链 - IBC
技术点:得益于Cosmos的IBC
- 用户在 Counterparty chain 上创建请求并通过IBC中继到 Band chain 上
- 根据请求指定的Oracle Script,执行其Preparation阶段,分解出一系列需要执行的data sources queries
- 进行 gas 费用检查
- 发送一个包含【错误信息】或者【请求标识符】的ack给 Counterparty chain
- 如果检查通过,广播该request
- 被随机选中的Validator会执行data source queries去获取到数据结果,并构成报告提交到band chain
- 如果成功提交的report数量满足request中设定的minCount要求,则在Band chain上聚合并存储最终数据结果
- 最终结果会被打包成 OracleResponsePacketData 并通过IBC中继回 Counterparty chain
异构链 - Lite Client
技术点
基于Merkel Proof构建数据证明。其实和很多跨链项目的原理差不多
异构链可以通过 Lite Client (轻客户端) 来验证自己收到的 result 的合法性。
- user contract 发送 【需要验证的result】和【encode proof】给 bridge contract ,并由 bridge contract 抛出事件
- 轻客户端通过三个步骤来执行验证
- 重构区块头
- 恢复参与该区块构建的所有签名者的地址
- 检查所有签名者的总票权是否足够
- 返回验证结果给 bridge contract
- bridge contract 将结果转发给 user contract
Cosmos中区块执行的阶段
在 Cosmos 当中,区块执行有三个阶段,before block → execute tx → end block。使用 Cosmos SDK 允许自定义设计 before block 和 end block 的处理逻辑。
Band chain 当中,如果提交的 report 的数量满足了用户的 minCount 要求,就会在 execute tx 阶段识别并加入到 pending list,然后在 end block 阶进行聚合处理。