Band Protocol 预言机集成
介绍如何在 TRON 上集成 Band Protocol 去中心化预言机,获取链下价格喂价数据。
Band Protocol 预言机集成
TRON 上的智能合约可以借助 Band Protocol 的去中心化预言机获取现实世界的链下数据。最典型的场景是把各类加密资产的价格喂价接入去中心化金融(DeFi)应用。
桥接合约架构
要把 Band 预言机数据集成进应用,通过 Band Protocol 的**桥接合约(Bridge Contract)**实现。该合约已部署在 TRON 测试网,地址为 TPxsemS7h9rrJPZAPDjP7rmLoA4ErYny69,Solidity 源码可在 BandChain 的 GitHub 仓库获取。
价格数据来自 BandChain 上发起的数据请求。BandChain 验证者节点从 CoinGecko、CryptoCompare、 TRON 网络、Alpha Vantage API 等多个数据源取数,计算中位数(Median)得出价格。每次请求都执行特定的价格聚合预言机脚本,脚本源码可在 BandChain 开发者网络(Devnet)查看。
Band 部署在 TRON 上的桥接合约定期获取这些请求结果,写入合约状态变量,供外界调用。
可用价格喂价数据 (Shasta 测试网)
测试网桥接合约目前存储以下价格对,每 5 分钟自动更新一次,支持列表与数据源如下:
1. 加密货币价格对 (数据源: CoinGecko、CryptoCompare、Binance)
- BTC/USD
- ETH/USD
- TRX/USD
- BAND/USD
2. 大宗商品价格对 (数据源: Alpha Vantage)
- XAU/USD (黄金)
- XAG/USD (白银)
3. 外汇汇率对 (数据源: Alpha Vantage)
- EUR/USD (欧元)
- CNY/USD (人民币)
- JPY/USD (日元)
- GBP/USD (英镑)
- KRW/USD (韩元)
除最新价格外,调用方还能从桥接合约获取以下辅助安全参数:
- 数据精度乘数 (Multiplier):用于放大存储价格精度的十进制乘数。
- 数据更新时间戳:该特定价格请求在 BandChain 上被解析完成并写入本桥接合约的 Unix 时间戳。
说明这些参数帮助调用方判断喂价是否在有效期内、数据是否仍然有效,从而防范延迟攻击和过期(stale)数据。
桥接合约数据更新维护
为方便社区开发测试,Band 基金会维护并定期更新上述测试网桥接合约的价格数据。生产环境中,开发者可参考 Band 文档,自行部署桥接合约以订阅所需数据源。
获取并使用价格数据 (Solidity 代码范例)
下面用一个简单的价格库合约 SimplePriceDB 演示如何从已部署的 Band 预言机桥接合约读取最新 BTC/USD 价格:
pragma solidity 0.5.9;
pragma experimental ABIEncoderV2;
import "./Obi.sol";
import {IBridge, IBridgeCache} from "./IBridgeWithCache.sol";
import {ParamsDecoder, ResultDecoder} from "./Decoders.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
contract SimplePriceDB {
using SafeMath for uint256;
using ResultDecoder for bytes;
using ParamsDecoder for bytes;
IBridgeCache public bridge;
IBridge.RequestPacket public req;
uint256 public current_price;
constructor(IBridgeCache bridge_) public {
bridge = bridge_;
req.clientId = "tron_testnet";
req.oracleScriptId = 76;
// OBI 编码后的 {"symbol":"BTC"} 参数:hex"00000003425443"
req.params = hex"00000003425443";
req.askCount = 4;
req.minCount = 3;
}
// 从 TRON 上的桥接合约获取最新的 BTC/USD 价格并写入本合约状态变量中
function setPrice() public {
IBridge.ResponsePacket memory res = bridge.getLatestResponse(req);
ResultDecoder.Result memory result = res.result.decodeResult();
current_price = result.px;
}
}1. 引入依赖文件说明
除标准的 SafeMath.sol 外,与 Band 预言机交互还需导入三个专用接口与编码工具文件:
Obi.sol:包含一组 OBI(Oracle Binary Encoding)函数,用于对与 BandChain 交互时的二进制数据进行序列化与反序列化。详见 BandChain OBI Wiki。Decoders.sol:辅助解码工具类,用于从预言机的响应报文中提取出结构化的价格数据(px)。IBridgeWithCache.sol:Band 预言机部署在 TRON 上的桥接合约接口。
2. 合约初始化参数说明 (Constructor)
构造函数传入桥接合约的部署地址,并初始化结构体 req(RequestPacket)的各项键值。本示例中各配置项含义如下:
clientId("tron_testnet"):由客户端自定义的预言机请求唯一标识符。oracleScriptId(76):该价格聚合脚本在 BandChain 注册时分配的预言机脚本唯一 ID。params(hex"00000003425443"):序列化后的参数,此处表示查询"BTC"。askCount(4):请求指定的验证者节点数量。minCount(3):为了通过去信任化共识,执行本请求所需的最少验证者响应数量。minCount必须小于或等于askCount。
各可用资产的价格对 Params 参数对照表如下:
| 价格资产对 | 传入参数的十六进制 (Params Hex) |
|---|---|
| BTC/USD | hex"00000003425443" |
| ETH/USD | hex"00000003455448" |
| TRX/USD | hex"00000003545258" |
| BAND/USD | hex"0000000442414e44" |
| XAU/USD | hex"00000003584155" |
| XAG/USD | hex"00000003584147" |
| EUR/USD | hex"00000003455552" |
| CNY/USD | hex"00000003434e59" |
| JPY/USD | hex"000000034a5059" |
| GBP/USD | hex"00000003474250" |
| KRW/USD | hex"000000034b5257" |
3. 数据更新函数说明 (setPrice)
setPrice)这是与预言机交互的核心方法:内部调用桥接合约的 getLatestResponse(req),传入构造函数中初始化好的请求结构体;再用导入的解码库解析响应数据,把最新 BTC/USD 价格赋给状态变量 current_price。
Updated 11 days ago