只要支持验证来自输出链的有效负载,就可以添加任何验证层。
在最简单的实现中,验证层需要支持以下内容:
-
求解器可以提交其填充输出的提交接口。提交接口应接受任意包进行验证,然后调用关联的输出结算合约以检查有效负载是否有效。
interface IPayloadCreator {
function arePayloadsValid(
bytes[] calldata payloads
) external view returns (bool);
}
-
实现关联的验证接口,以便输入结算实现可以准确验证输出是否已填充。
interface IOracle {
function efficientRequireProven(
bytes calldata proofSeries
) external view;
}
重要的是,提交接口不必标准化;它只需要准确记录,以便求解器可以实现它。
已实现的验证接口
有三种类型的验证接口:
- 自助服务:提交有效负载会生成必须在输入链上收集和提交的链下证明的验证接口。
- 自动:提交有效负载会自动在输入链上交付关联证明的验证接口。
目前,所有支持的预言机系统都是自助服务。
速度和价格Polymer 比大多数其他预言机系统快得多。虽然速度不会影响用户的资产交付,但对求解器很重要。选择具有快速还款的预言机系统会导致更便宜的意图,因为求解器可以更快地轮换其资本。
Polymer
Polymer 允许验证发出的事件。验证的目标事件是 OutputFilled
事件,在输出已填充时发出。
event OutputFilled(bytes32 indexed orderId, bytes32 solver, uint32 timestamp, MandateOutput output);
使用 Polymer prove API,可以生成事件的证明。生成后,可以将其提交到 receivedMessage
。
有关此类集成的示例,请参阅 lintent.org 实现。
Polymer 一次只能证明一个已填充的输出。
Wormhole
Wormhole 实现基于 Wormhole 的广播功能。消息必须通过 submit
接口提交到 Wormhole 实现。消息必须编码为 FillDescription
,然后提交:
function submit(address source, bytes[] calldata payloads) public payable returns (uint256 refund);
然后将此消息发送到 Wormhole 守护者集。一旦关联的证明可用,求解器可以将证明提交到输入链上的 receiveMessage
以验证其意图。
注意:Wormhole 实现使用比 Wormhole 的 Implementation.sol
更高效的验证算法。
Bitcoin
LI.FI 意图有一个比特币简化支付验证 (SPV) 客户端实现。此实现既作为输出结算实现,又作为验证层。
比特币 SPV 客户端需要持续维护——区块链必须大约每 10 分钟更新一次,或者每当需要证明交易时——才能正确验证交易。
要生成交易证明,请参考以下代码:
import mempoolJS from "@catalabs/mempool.js";
const mainnet: boolean;
const {
bitcoin: { transactions, blocks },
} = mempoolJS({
hostname: "mempool.space",
network: mainnet ? undefined : "testnet4",
});
export async function generateProof(
txid: string,
): Promise<{ blockHeader: string; proof: Proof; rawTx: string }> {
const tx = await transactions.getTx({ txid });
const merkleProof = await transactions.getTxMerkleProof({ txid });
// TODO: 序列化版本 1。
const rawTx = await transactions.getTxHex({ txid });
const blockHash = await blocks.getBlockHeight({
height: merkleProof.block_height,
});
// 大多数端点提供交易见证编码。
// 以下函数用于剥离见证数据。
const rawTxWitnessStripped = removeWitnesses(rawTx);
const blockHeader = await blocks.getBlockHeader({ hash: blockHash });
return {
blockHeader,
proof: {
txId: txid,
txIndex: merkleProof.pos,
siblings: merkleProof.merkle.reduce(
(accumulator, currentValue) => accumulator + currentValue,
),
},
rawTx: rawTxWitnessStripped,
};
}