-
一个提交接口,供求解器提交其已填充的输出。它应接受任意的待验证载荷,然后调用相关的输出结算合约以检查这些载荷是否有效。如果预言机能够自行证明合约调用、事件或存储,则提交是自动的,此要求不适用。
预言机实现可以通过
IAttester接口来验证输出是否已被填充: -
实现验证接口,使输入链能够检查某个输出是否已被填充:
- 提交或接收接口不必标准化,但你必须记录文档,以便求解器能够实现它们。
- 预言机系统可以采用自动中继或手动中继。
- 预言机系统的信任假设必须明确,以便意图签发者和求解器能够做出明智的决策。
已实现的验证接口
有三种类型的验证接口:- 自助式(Self-serve):在此类验证接口中,提交有效载荷会生成一个链下证明,该证明必须被收集并提交到输入链上。
- 自动式(Automatic):在此类验证接口中,提交有效载荷会自动将相关证明送达输入链上。
- 同链式(Same Chain):使用输出结算为其自身生成预言机证明,从而跳过专用的预言机系统。
速度与价格
某些预言机系统比其他预言机系统快得多。虽然速度不影响用户的资产交付,但它对求解器很重要。选择还款速度快的预言机系统能带来更便宜的意图,因为求解器可以更快地周转其资金。
某些预言机系统比其他预言机系统快得多。虽然速度不影响用户的资产交付,但它对求解器很重要。选择还款速度快的预言机系统能带来更便宜的意图,因为求解器可以更快地周转其资金。
OutputSettlerSimple
你可以将 OutputSettlerSimple——一个输出结算器——用作同链意图的预言机。要使用它,请在填充输出后调用setAttestation。
setAttestation 将会公开已填充的输出,供输入结算进行验证。
Solana 上的同链意图
在 Solana 上,不存在setAttestation 这一步——填充本身就会生成证明。output_settler_simple::fill(或 native_fill)会在填充成功时创建一个 LocalAttestation PDA,而 finalise 会直接验证该账户。整个过程不涉及任何预言机程序,也没有回调流程。作为替代,单输出订单可以使用先释放输入的结算:托管程序向求解器付款,紧凑填充在同一笔交易中交付输出,全程不产生任何认证。账户模型请参阅认证。
Polymer
Polymer 是一个基于事件的系统,以低成本提供实时证明。其安全性基于通过 Polymer 打包的状态,区块头来源于定序器的预确认。- gas 成本低。
- 延迟低,可实现快速结算。
- Polymer 一次只能证明一个输出,因此求解器必须自行实现批量证明才能保持效率。
- 广播(Broadcast)
OutputFilled,它在输出被填充时发出。
receiveMessage。
有关获取 Polymer 证明的集成示例,请参阅 lintent.org/polymer 或所进行的 receiveMessage 调用。
Solana 上的 Polymer
Solana 上的 Polymer 预言机是oracle_polymer 这个 Anchor 程序(部署名称:polymer;IDL:polymer.json)。其流程与 EVM 版本一致——验证填充、发出可证明的日志、在输入链上验证证明——但机制上是 Solana 式的:
-
输出侧(Solana 上的一次填充):填充之后,求解器通过以下两条指令之一导出该填充。两者都会针对每个描述对应的
LocalAttestation进行验证,并发出一行Prove:日志,供 Polymer 在输入链上进行证明:submit(source, fill_descriptions)—— 无需许可,且不消费认证。它唯一的具名账户是oracle_polymer状态 PDA;remaining_accounts为每个载荷放入一个只读认证。认证会原样保留,因此如果日志丢失或未能被证明,可以直接再次提交。submit_consume(source, fill_descriptions)—— 还会消费每个认证,即关闭它并退还其租金(如果记录中的支付方是可执行账户,该认证只会被标记为已消费,租金则被推迟退还)。具名账户:submitter(签名者)、oracle_polymer、Polymer 的local_consumerPDA(2m1udXnYmaxjSXBBE88yZZcwrtT127DqLcwK9B3WCAus)以及intents_protocol。remaining_accounts为交错排列的可写账户对[attestation_0, rent_refund_0, attestation_1, rent_refund_1, …]。对于每个填充载荷,submitter必须是该认证中记录的租金支付方——即签署该次填充的 Solana 账户,而不是filler_data中的求解器 id——否则会以UnauthorizedFillSubmitter失败。因此,一个消费型批次不能混合来自不同填充者的填充。未填充载荷则任何人都可以提交。
submit的日志已经被证明之后。 -
输入侧(等待远程证明的 Solana 订单):接收流程最终都会以
receive_attest()结束,它从证明器的结果账户读取已验证的事件,通过ChainMapping映射源链 id,并注册认证。
1
在 Solana 上填充,然后提交
fill 会创建 LocalAttestation;oracle_polymer::submit(或 submit_consume)对其进行验证并发出 Prove: 日志。二者可以是两笔独立的交易,如果放得下也可以合并为一笔;关键在于哪笔交易携带了 Prove: 日志。2
请求 submit 交易的证明
请 Polymer 的 Prove API 证明包含
Prove: 日志的那笔交易——即包含 submit 的交易,而不是只有填充的交易。如果对不含该日志的交易请求证明,会失败并提示 “transaction does not contain a Polymer Prove log”。将 srcChainId 设为 2。这是 Polymer 自己为 Solana 分配的协议 id,并非 LI.FI 的规范链 id——参见链 id 命名空间。3
在输入链上交付给 receiveSolanaMessage
源自 Solana 的证明要交付给 EVM 预言机的
receiveSolanaMessage,而不是 receiveMessage。这两个入口点解析不同的载荷格式,并写入不同的存储,因此如果证明交付给错误的入口点会导致回滚。请根据输出链的类型选择正确的入口点。- 调用
create_polymer_accounts()。 - 每个分块调用一次
load_proof_chunk(chunk)。 - 以约 1,000,000 CU 的计算预算调用
validate_event()。 - 调用
receive_attest()。
receive_load_proof(proof),然后是 receive_attest()。在这两条路径中,receive_attest() 都会关闭证明器的临时 PDA,并将其租金返还给出资签名者。
证明器的临时账户仅由签名者派生,因此同一签名者下两个并发的接收流程会发生冲突。第二次调用
create_polymer_accounts 会因账户已存在而失败,交错的分块加载也会写入同一个证明缓冲区并使其损坏。请按签名者串行化接收流程,或为并行的证明使用不同的签名者。Wormhole
Wormhole 是一个基于消息传递的系统,允许合约广播 VAA(Verified Action Approvals,已验证操作批准)。VAA 是由 Wormhole Guardian 网络签名的消息。- 通过去中心化的 guardian 集合来保障安全。
- 支持在单个 VAA 中批量证明多个输出。
- 与替代方案相比速度较慢。
- 广播(Broadcast)
submit 接口提交到 Wormhole Implementation。消息必须被编码为 FillDescription 然后提交:
receiveMessage 来验证其意图。
获取 Wormhole VAA 有很多方式,例如 Wormholescan api 或 Wormhole SPY。
Wormhole 的实现出于节省 gas 的目的,使用了比 Wormhole 的
Implementation.sol 效率高得多的验证算法。部署
Wormhole oracle 已部署在 EVM 主网上;请参阅 Wormhole Oracle Mainnet 地址表。Solana 实现已部署在主网上;请参阅 Solana 程序地址。- 在 EVM 上,
submit以 consistency level15发布 Wormhole 消息。 - 通过 Wormholescan API 获取已签名的 VAA。
- 投递不是自动的:求解器(或任何调用者)必须将 VAA 提交到输入链上的
receiveMessage。
Solana 上的 Wormhole
Solana 上的 Wormhole 预言机实现是oracle_wormhole 这个 Anchor 程序(程序名称:wormhole;IDL:wormhole.json)。其主网部署地址见部署概览:
- 输出侧:
submit(source, fill_descriptions)会验证并消费各笔填充的LocalAttestation账户,然后发出一条覆盖所有这些填充的 Wormhole 消息(finality:finalized)。remaining_accounts为交错排列的可写账户对[attestation_0, rent_refund_0, …],且批次不能为空。由具名的submitter和一个全新的post_message账户签名;没有填充者签名的要求。VAA emitter 即为该预言机的 PDA。 - 输入侧:
receive指令验证一条已发布的 VAA,通过ChainMapping映射 emitter 链,并为每个载荷创建一个Attestation。remaining_accounts为每个解码出的载荷放入一个可写的目标认证 PDA,按载荷顺序排列,不含租金退还槽位;由具名签名者为其创建付费。
Hyperlane
Hyperlane 是一个高度可定制的、基于消息传递的系统,允许合约通过选定的链间安全模块(ISM)发送和接收经过验证的消息。- 高度可定制的安全模块。
- 支持在单条消息中批量证明多个输出。
- 强抗审查保证。
- 自动或手动中继。
dispatch 函数。要配置 Hyperlane 中继,请在调用 submit 时提供相关的 customHook 和 customHookMetadata。
Chainlink CCIP
Chainlink CCIP 是一个基于消息传递的系统,允许合约通过 Chainlink 预言机发送和接收经过验证的消息。- 通过 Chainlink 的预言机网络来保障安全。
- 支持在单条消息中批量证明多个输出。
- 符合 SOC2 和 ISO 27001 标准
EVM2AnyMessage 的 CCIP router ccipSend。要将已填充的输出提交到 CCIP 预言机,首先调用报价端点 getFee 来估算消息传递费用。然后在输出链上连同所需费用调用 submit,将消息发送到输入链。如果使用 ERC20 代币支付费用,请先批准代币转账。
Axelar
Axelar 是一个基于消息传递的系统,允许合约发送和接收由 Axelar 的 Proof of State 网络验证的消息。- 通过 Axelar 的 Proof of State 网络来保障安全。
- 支持在单条消息中批量证明多个输出。
- 自动中继。
callContract 函数。要将已填充的输出提交到 Axelar 预言机,首先使用 gasService 来估算费用。然后在输出链上连同所需费用调用 submit,将消息发送到输入链。
LayerZero
LayerZero 是一个安全性可定制的、基于消息传递的系统,允许合约通过一组选定的去中心化验证网络(DVN)发送和接收经过验证的消息。- 可定制的安全性
- 广受欢迎且链兼容性广泛。
- 支持在单条消息中批量证明多个输出。
- 费用较高
send。要将已填充的输出提交到 LayerZero 预言机,首先使用 quote 函数来估算费用,然后在输出链上连同所需费用调用 submit,将消息发送到输入链。

