跳到主要内容

发送消息

开发者通过调用 Mailbox.dispatch() 来发送跨链消息。

该函数接收消息内容、目标链 ID 和接收者地址作为参数。每条消息都会作为叶子节点插入到 Mailbox 存储的增量默克尔树中。Hyperlane 的权益证明协议使用这个默克尔树来验证欺诈证明。

Dispatch

调用此函数可将消息发送到目标域和接收者。

注意

Hyperlane 只能向实现了 handle 函数的智能合约投递消息。查看接收消息文档获取更多信息。

根据post-dispatch 钩子配置,可能需要支付一些费用。查看 quoteDispatch 部分获取更多信息。

function dispatch(
uint32 destinationDomain,
bytes32 recipientAddress,
bytes calldata messageBody
) external payable returns (bytes32 messageId);
信息

为了兼容不同寻址方式的虚拟机,接收者地址会左填充至 bytes32TypeCasts提供了以下实用工具:

// alignment preserving cast
function addressToBytes32(address _addr) internal pure returns (bytes32) {
return bytes32(uint256(uint160(_addr)));
}

示例

// 从 abstracttestnet 发送消息到 alephzeroevmtestnet 的 TestRecipient
IMailbox mailbox = IMailbox("0x28f448885bEaaF662f8A9A6c9aF20fAd17A5a1DC");
bytes32 messageId = mailbox.dispatch{value: msg.value}(
2039,
"0x0000000000000000000000009EC79CA89DeF61BFa2f38cD4fCC137b9e49d60dD",
bytes("Hello, world")
);

查询发送费用

通常会配置费用来支付 IGP 支付以及协议成本。这包括目标链上的交易提交、安全保障和维护费用。你可以通过调用 quoteDispatch 函数来获取相应 dispatch 调用的费用报价。

function quoteDispatch(
uint32 destinationDomain,
bytes32 recipientAddress,
bytes calldata messageBody
) external view returns (uint256 fee);

必须将报价的 fee 作为 value 传递给 dispatch 调用以确保它不会回滚。

示例

// 查询从 abstracttestnet 发送消息到 alephzeroevmtestnet TestRecipient 的费用
IMailbox mailbox = IMailbox("0x28f448885bEaaF662f8A9A6c9aF20fAd17A5a1DC");
uint32 destination = 2039;
bytes32 recipient = "0x0000000000000000000000009EC79CA89DeF61BFa2f38cD4fCC137b9e49d60dD";
bytes memory body = bytes("Hello, world");
uint256 fee = mailbox.quoteDispatch(destination, recipient, body);
mailbox.dispatch{value: fee}(destination, recipient, body);
危险

dispatch 支付的费用不足会导致回滚。如果你组合使用多个钩子,超额支付的费用可能不会退还给消息发送者。

Post-Dispatch 钩子配置

Mailbox 上配置了两个钩子:

  • required: 对所有支付了所需费用的 dispatch 调用都会触发
  • default: 在 required 钩子之后使用剩余 value 触发(除非被覆盖)

Required 钩子

你可以调用 requiredHook 函数查询 required 钩子配置。

function requiredHook() external view returns (IPostDispatchHook);

Default 钩子

你可以调用 defaultHook 函数查询 default 钩子配置。

function defaultHook() external view returns (IPostDispatchHook);

要在 dispatch 调用中用自定义钩子覆盖默认钩子,请参阅钩子参考