L4
Oracle 预言机系统
Layer 1 原生预言机 - 将链外数据引入智能合约
概述
核心优势:Aeternity 的预言机是 Layer 1 原生协议,不同于以太坊上基于智能合约的 Chainlink 等 Layer 2 方案。
这意味着预言机对象(Oracles)和查询对象(Queries)是区块链状态树的一等公民,拥有:
- 专用交易类型 - OracleRegisterTx, OracleQueryTx, OracleRespondTx, OracleExtendTx
- 独立 Gas 定价 - 基于 TTL 的存储租赁模型
- 自动状态修剪 - 过期数据自动清理,保持轻量级
核心架构
状态树设计 (State Tree)
Oracle 数据存储在全局状态树的专用子树中,由模块 aeo_state_tree 管理。
预言机对象 (Oracle Object)
存储预言机的元数据:
ID- 预言机唯一标识TTL- 生存时间query_fee- 查询费用query_format- 问题格式response_format- 响应格式
查询对象 (Query Object)
独立存储,Key 为 <<OracleId, QueryId>>
- 高效查找特定预言机的所有查询
- 避免大对象序列化开销
- 支持 O(1) 复杂度过期清理
清理机制 (Pruning)
系统维护辅助的 Cache Tree,按"过期高度"索引所有对象:
%% 在每个区块生成前自动清理
aeo_state_tree:prune(Height, StateTree) ->
%% 查询 Cache,O(1) 复杂度找到过期对象
%% 批量删除过期的预言机和查询
%% 防止状态膨胀
经济模型
Oracle 系统通过 TTL 和 Gas 费用进行自我调节:
存储租赁
注册和延长预言机需要支付与 TTL 成正比的 Gas 费用。TTL 越长,费用越高。
查询费用
查询者必须支付不低于预言机设定的 query_fee。费用在响应后转移给预言机所有者。
生命周期与交易
Oracle 的生命周期由四个核心交易驱动:
1. 注册 (Register) -
OracleRegisterTx
功能:创建一个新的预言机身份
关键参数
query_format- 问题格式 (Sophia 类型签名)response_format- 响应格式query_fee- 服务定价oracle_ttl- 初始生存时间
执行逻辑
- 检查账户是否已是预言机
- 验证 TTL 合法性
- 扣除 Gas 并写入状态树
// JavaScript SDK
const oracle = await aeSdk.registerOracle(
"string", // queryFormat
"string", // responseFormat
{ queryFee: 30000, oracleTtl: { type: 'delta', value: 500 } }
);
2. 扩展 (Extend) -
OracleExtendTx
功能:延长预言机的 TTL
- 只能增加 TTL,不能减少
- 没有协议级硬性上限(受限于 Gas Limit)
- 必须由预言机所有者发起
// 续期预言机
await oracle.extendOracle({ oracleTtl: { type: 'delta', value: 1000 } });
3. 查询 (Query) -
OracleQueryTx
功能:向预言机提问
执行流程
- 验证
query_fee是否足够 - 生成唯一
QueryId(基于发送者 Nonce) - 扣除费用并锁定在状态中
- 创建查询对象,状态为
open
TTL 参数
query_ttl- 等待回答的时间response_ttl- 回答保留的时间
// 发起查询
const query = await oracleClient.query("What is the current BTC price?", {
queryFee: 30000,
queryTtl: { type: 'delta', value: 10 },
responseTtl: { type: 'delta', value: 50 }
});
4. 响应 (Respond) -
OracleRespondTx
功能:预言机提交答案
- 验证查询是否属于该预言机且处于
open状态 - 写入
response数据 - 将查询费用转移给预言机账户
- 更新查询对象的过期时间为
CurrentHeight + response_ttl
// 响应查询
await oracle.respondToQuery(queryId, "42000 USD");
智能合约交互
最大优势:Aeternity 的 Oracle 可以被智能合约(Sophia)直接调用!
ABI 版本与类型检查
- ABI Version:预言机在注册时声明
abi_version(如?ABI_FATE_SOPHIA_1) - 查询验证:FATE 虚拟机验证查询数据是否符合
query_format - 响应验证:响应数据必须符合
response_format
Sophia 高层 API
// Sophia 合约中使用 Oracle
contract OracleConsumer =
// 注册预言机
stateful entrypoint register() : oracle(string, string) =
Oracle.register(
1000000000000000, // query_fee (1 AE)
RelativeTTL(1000) // oracle_ttl
)
// 发起查询
stateful entrypoint query(o : oracle(string, string), q : string) : oracle_query(string, string) =
Oracle.query(
o,
q,
1000000000000000, // query_fee
RelativeTTL(50), // query_ttl
RelativeTTL(50) // response_ttl
)
// 响应查询
stateful entrypoint respond(o : oracle(string, string), q : oracle_query(string, string), r : string) =
Oracle.respond(o, q, r)
// 获取响应(阻塞式)
entrypoint get_answer(o : oracle(string, string), q : oracle_query(string, string)) : option(string) =
Oracle.get_answer(o, q)
开发者最佳实践
TTL 策略
避免设置过长的 TTL。建议根据业务需求(如按月/按年)定期发送 ExtendTx 续期,以平摊 Gas 成本并保持灵活性。
查询费设置
query_fee 是防止垃圾查询(Spam)的第一道防线,应根据计算成本合理设置。
格式规范
强烈建议使用标准的 Sophia 类型描述字符串作为 Format,以便合约能无缝集成。
技术优势总结
原生集成
无需部署合约即可实现预言机功能,更省 Gas,更安全
自动清理
TTL 机制确保过时数据自动下链,保持轻量级
类型安全
结合 Sophia ABI,提供端到端的类型验证
学习路径