跨链消息的统一问法:ERC-7786 的 sendMessage 与属性协商 图 1
跨链消息的统一问法:ERC-7786 的 sendMessage 与属性协商 · 图 1

跨链消息的统一问法:ERC-7786 的 sendMessage 与属性协商

一条 NFT 想在两条链上联动——比如以太坊上铸造、另一条链上解锁权益——通常要写死某一家跨链消息协议的接口。换协议,合约就要重写。ERC-7786 的目标是把“发一条跨链消息”抽象成统一接口,让合约面对多家协议时用同一套函数名。该提案在 ercs 仓库的状态是 Final(最终),创建于 2024 年 10 月 14 日,依赖 ERC-7930 提供的地址格式。

一条消息由什么构成

按规范,一条跨链消息包含五部分:发送方、接收方、载荷、原生币值和一份属性列表。发送方和接收方必须用 ERC-7930 的互操作地址二进制格式书写,按 CAIP-350 序列化——这意味着收发双方各自在哪条链,天然写在消息里。载荷是一段不透明的 bytes,协议不解释内容。接收方字段允许留空或全零,用于广播式场景,由协议自己决定最终收件人。

跨链消息的统一问法:ERC-7786 的 sendMessage 与属性协商 图 2
跨链消息的统一问法:ERC-7786 的 sendMessage 与属性协商 · 图 2

属性:协商能力的口子

属性是这套接口最有设计感的部分。每个属性是一个键值对,键为四字节,规范推荐直接用 Solidity 函数选择器的写法定义,比如 minGasLimit(uint256) 这个签名对应键 39f87ba1——这样键自带可读的名字,值的编码也自动沿用 ABI 规则。属性列表按 bytes[] 编码,每个元素是键与值的拼接。源网关必须实现 supportsAttribute,让调用方先问“你支持这个属性吗”;如果消息里塞了不支持的属性,sendMessage 必须以 UnsupportedAttribute 错误回滚。网关可以升级增加属性,但规范建议一旦支持就不要撤销,以免破坏老用户。

发送与回执

源网关接口要求两个东西:sendMessage(recipient, payload, attributes),外部可调且可带原生币值,返回一个 bytes32 的 sendId;以及 MessageSent 事件,把 sendId、发送方、接收方、载荷、value 和完整属性列表全部记进日志——索引器靠它追踪消息。规范也提醒,发送函数返回不等于消息已经完成,网关可能还需要后续动作,例如为目的地链的 gas 付费,这是“后处理”阶段的事。

对 NFT 与合约作者意味着什么

属性键为什么用函数选择器

用 Solidity 函数选择器当属性键,是个一行代码省掉一整套注册表的写法。以 minGasLimit(uint256) 为例:对签名字符串做 Keccak 哈希取前四字节得到 39f87ba1,任何工具只要算一遍哈希就能还原键的含义,不需要查某个中心化登记表,也不会有两个团队抢同一个名字——不同签名的选择器几乎不会相撞。值的编码同理:网关看到 39f87ba1 就知道后面跟的是一个 abi 编码的 uint256,解析规则完全沿用 ABI,写适配器的开发者不用翻多份文档。代价是键的含义仍然要靠公开发布对应的函数签名来沟通,规范因此建议把常用属性各自发布成 ERC 固定下来。读日志时也实用:在 MessageSent 事件里看到某属性的字节串,反查已知选择器表就能大致知道这笔消息附带了什么要求。

另外留意消息值与消息gas的分离:sendMessage 可带原生币值,但目的链的执行费通常由后处理或属性约定覆盖,付款方与执行方不在同一笔账上,读跨链账单时要把两段成本分开核对。

最后补一条对开发者的提醒:网关选择仍要看各家安全模型与验证者假设,标准统一的是接口形状,跨链资产的实际安全性由被选中的那个实现决定。

对合约作者,统一接口的价值是减少供应商锁定:同一份合约逻辑可以对接原生实现,也可以套一层适配器(adapter)对接某家协议,迁移成本下降。对用户,理解这套结构有助于读懂跨链工具的状态:sendId 发出不等于到达,事件里的属性决定目的链拿到消息后怎么执行(比如最低 gas 保证)。评估任何跨链 NFT 方案时,除了接口标准,仍要看具体网关的安全模型、验证者假设和历史事故记录——标准统一的是问法,不是安全性本身。本文为机制说明,不构成任何投资建议。