跳到主要内容

创建你自己的钩子和ISM

钩子和ISM具有互补关系:你可以从源链自定义行为,并在目标链上使用配对的ISM合约来验证你的自定义钩子行为。

你可以根据自己的需求实现和使用自己的钩子和ISM模式。你可以通过在源链上实现IPostDispatchHook接口和在目标链上实现IInterchainSecurityModule来使用像Wormhole或Chainlink的CCIP这样的外部桥接提供商。

IPostDispatchHook接口
interface IPostDispatchHook {
enum Types {
UNUSED,
ROUTING,
AGGREGATION,
MERKLE_TREE,
INTERCHAIN_GAS_PAYMASTER,
FALLBACK_ROUTING,
ID_AUTH_ISM,
PAUSABLE,
PROTOCOL_FEE,
LAYER_ZERO_V1,
RATE_LIMITED,
ARB_L2_TO_L1,
OP_L2_TO_L1
}

/**
* @notice Returns an enum that represents the type of hook
*/
function hookType() external view returns (uint8);

/**
* @notice Returns whether the hook supports metadata
* @param metadata metadata
* @return Whether the hook supports metadata
*/
function supportsMetadata(
bytes calldata metadata
) external view returns (bool);

/**
* @notice Post action after a message is dispatched via the Mailbox
* @param metadata The metadata required for the hook
* @param message The message passed from the Mailbox.dispatch() call
*/
function postDispatch(
bytes calldata metadata,
bytes calldata message
) external payable;

/**
* @notice Compute the payment required by the postDispatch call
* @param metadata The metadata required for the hook
* @param message The message passed from the Mailbox.dispatch() call
* @return Quoted payment for the postDispatch call
*/
function quoteDispatch(
IInterchainSecurityModule接口
interface IInterchainSecurityModule {
enum Types {
UNUSED,
ROUTING,
AGGREGATION,
LEGACY_MULTISIG,
MERKLE_ROOT_MULTISIG,
MESSAGE_ID_MULTISIG,
NULL, // used with relayer carrying no metadata
CCIP_READ,
ARB_L2_TO_L1,
WEIGHTED_MERKLE_ROOT_MULTISIG,
WEIGHTED_MESSAGE_ID_MULTISIG,
OP_L2_TO_L1
}

/**
* @notice Returns an enum that represents the type of security model
* encoded by this ISM.
* @dev Relayers infer how to fetch and format metadata.
*/
function moduleType() external view returns (uint8);

/**
* @notice Defines a security model responsible for verifying interchain
* messages based on the provided metadata.
* @param _metadata Off-chain metadata provided by a relayer, specific to
* the security model encoded by the module (e.g. validator signatures)
* @param _message Hyperlane encoded interchain message
* @return True if the message was verified
*/
function verify(
信息

钩子目前期望元数据使用StandardHookMetadata进行格式化。

你也可以继承我们的AbstractMessageIdAuthorizedIsm,它允许对中间的verifyMessageId函数调用进行访问控制,如果从授权的AbstractMessageIdAuthHook钩子接收到消息ID,则将其在存储中设置为true。这种模式目前用于OpStackHook <> OpStackIsm模式。

工作流程

接口

在实现上述接口后,你可以通过使用我们邮箱中的重载dispatch调用来覆盖默认钩子和钩子元数据:

* @notice Dispatches a message to the destination domain & recipient.
* @param destinationDomain Domain of destination chain
* @param recipientAddress Address of recipient on destination chain as bytes32
* @param messageBody Raw bytes content of message body
* @param metadata Metadata used by the post dispatch hook
* @param hook Custom hook to use instead of the default
* @return The message ID inserted into the Mailbox's merkle tree

示例

// 从abstracttestnet发送消息到alephzeroevmtestnet TestRecipient
IMailbox mailbox = IMailbox("0x28f448885bEaaF662f8A9A6c9aF20fAd17A5a1DC");
IPostDispatchHook merkleTree = IPostDispatchHook("0x7fa6009b59F139813eA710dB5496976eE8D80E64");
mailbox.dispatch(
2039,
"0x0000000000000000000000009EC79CA89DeF61BFa2f38cD4fCC137b9e49d60dD",
bytes("Hello, world"),
"0x", // 空 元数据
merkleTree
);
  • 在源链上,

    • mailbox.dispatch()通过AbstractMessageIdAuthHook.postDispatch()调用你的自定义钩子。
    • _postDispatch检查latestDispatchedId是否是从钩子分发的ID,以确保调用钩子的是邮箱合约(因为调用postDispatch不受访问控制)
    • _sendMessageId调用你的自定义外部桥接逻辑,比如调用CCIP路由器合约。
  • 在目标链上,

    • 外部桥接将调用verifyMessageId函数(该函数受访问控制)并将messageIdverifiedMessages映射中设置为true。
    • 在接收到中继器的消息时,邮箱将调用你的ISM合约(在你的接收者地址中指定),该合约检查verifiedMessages映射中的messageId是否为true,并相应地向邮箱返回true或false。
注意

AbstractMessageIdAuthorizedIsm可以通过postDispatch调用发送msg.value,我们利用verifiedMessages的小端序255位来存储msg.value,顶部位用于实际接收messageId传递。因此,你可以从源链发送最多2^255数量的原生代币,目标ISM在目标链上只能接收2^255数量的原生代币。

访问控制

如果postDispatch必须只能用刚刚分发的message调用,可以使用邮箱上的latestDispatchedId函数来验证消息是否真的被分发了。

信息

这是用来代替类似require(mailbox == msg.sender)的方式,以支持组合,其中一个钩子可能将message传递给另一个钩子。

为了方便起见,MailboxClient提供了以下实用工具。

* @notice Sets the address of the application's custom interchain security module.
* @param _module The address of the interchain security module contract.
*/