拓冰建站拓冰建站
首页 / 资讯中心 / 正文

WTF-Solidity 深度解析:基于 ERC-7786 的 ERC1155Crosschain 原生跨链桥扩展

WTF-Solidity 深度解析基于 ERC-7786 的 ERC1155Crosschain 原生跨链桥扩展【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-Solidity导读本篇围绕 OpenZeppelin Contracts 新增的ERC1155Crosschain扩展展开讲解如何将 ERC-7786 标准下的跨链桥逻辑直接内嵌进 ERC-1155 代币合约使代币原生具备跨链能力。通过阅读仓库源码与测试用例你将掌握跨链发送/接收的完整调用链、burn/mint 桥接模式、网关授权校验机制以及如何在自己的多链合约中正确配置与部署该扩展。变更记录背景一条 changeset 引发的核心功能本仓库 lib/openzeppelin-contracts/.changeset/blue-jars-lay.md 记录了一次面向openzeppelin-solidity包的重要功能变更版本级别为minorERC1155Crosschain: Added an ERC-1155 extension to embed an ERC-7786 based crosschain bridge directly in the token contract.这条变更虽然仅一句话但它对应着仓库中一整套完整的跨链基础设施包括扩展实现 ERC1155Crosschain.sol、底层多代币桥抽象 BridgeMultiToken.sol、消息链路管理 CrosschainLinked.sol、接收端基类 ERC7786Recipient.sol以及完整的 Hardhat 测试套件 ERC1155Crosschain.test.js 和共享行为测试 BridgeERC1155.behavior.js。在 OpenZeppelin 的跨链架构中跨链消息遵循 ERC-7786 标准由各链上的网关gateway负责消息的发送与投递。仓库在 contracts/crosschain/README.adoc 中给出了完整的桥接体系核心辅助合约CrosschainLinked通过网关与远端合约通信、ERC7786Recipient从受信任网关接收消息的通用接收器桥抽象层BridgeFungibleERC-20/ERC-7802 跨链、BridgeNonFungibleERC-721 跨链、BridgeMultiTokenERC-1155 跨链独立桥合约BridgeERC20、BridgeERC721、BridgeERC1155、BridgeERC7802内嵌式扩展ERC20Crosschain、ERC721Crosschain、以及本次的ERC1155Crosschain。ERC1155Crosschain属于内嵌式路线把桥接逻辑直接写进代币合约代币自己就是桥而独立桥合约如BridgeERC1155则是面向存量 ERC-1155 代币的外挂式方案。ERC1155Crosschain 扩展源码剖析扩展本体位于 ERC1155Crosschain.sol其继承结构为abstract contract ERC1155Crosschain is ERC1155, BridgeMultiToken即同时继承标准 ERC1155 与多代币桥抽象基类BridgeMultiToken。源码注释明确了它的兼容目标与其他链上的ERC1155Crosschain实例互操作与其他链上通过BridgeERC1155桥接的普通ERC1155实例互操作。对外接口crosschainTransferFrom 的两个重载扩展对外暴露了两个crosschainTransferFrom重载均基于 ERC-1155 的授权模型调用者需对from拥有授权function crosschainTransferFrom( address from, bytes memory to, uint256 id, uint256 value ) public virtual returns (bytes32) { _checkAuthorized(_msgSender(), from); uint256[] memory ids new uint256[](1); uint256[] memory values new uint256[](1); ids[0] id; values[0] value; return _crosschainTransfer(from, to, ids, values); } function crosschainTransferFrom( address from, bytes memory to, uint256[] memory ids, uint256[] memory values ) public virtual returns (bytes32) { _checkAuthorized(_msgSender(), from); return _crosschainTransfer(from, to, ids, values); }单币种重载uint256 id, uint256 value适用于转移单个 token id批量重载uint256[] ids, uint256[] values支持一次跨链转移多个 id对应 ERC-1155 的批量特性to参数是完整的互操作地址Interoperable Address即链引用 链上地址的二进制编码而非普通address返回值bytes32是本次跨链消息的sendId可用于后续跟踪消息投递状态。桥接的核心burn 与 mint 对等与托管式桥不同ERC1155Crosschain采用销毁即锁定、铸造即解锁的原生代币桥模式通过两个内部虚函数实现/// dev Locking tokens is achieved through burning function _onSend(address from, uint256[] memory ids, uint256[] memory values) internal virtual override { _burnBatch(from, ids, values); } /// dev Unlocking tokens is achieved through minting function _onReceive(address to, uint256[] memory ids, uint256[] memory values) internal virtual override { _mintBatch(to, ids, values, ); }源链发出代币时直接调用_burnBatch把用户余额销毁相当于锁定在代币自身的总供应之外目标链收到消息时调用_mintBatch按相同 id 与数量铸造给接收者该模式天然保证跨链后的总供应守恒且无需在桥合约中维护托管余额。底层桥逻辑BridgeMultiToken 与消息流转BridgeMultiToken位于 BridgeMultiToken.sol是BridgeERC1155与ERC1155Crosschain共用的核心逻辑负责 ERC-1155 的跨链传输编排。跨链发送_crosschainTransferfunction _crosschainTransfer( address from, bytes memory to, uint256[] memory ids, uint256[] memory values ) internal virtual returns (bytes32) { _onSend(from, ids, values); (bytes2 chainType, bytes memory chainReference, bytes memory addr) to.parseV1(); bytes memory chain InteroperableAddress.formatV1(chainType, chainReference, hex); bytes32 sendId _sendMessageToCounterpart( chain, abi.encode(InteroperableAddress.formatEvmV1(block.chainid, from), addr, ids, values), new bytes[](0) ); emit CrosschainMultiTokenTransferSent(sendId, from, to, ids, values); return sendId; }发送流程分四步调用_onSend由子类实现ERC1155Crosschain中即销毁代币解析to中的目标链引用构造仅含链信息的互操作地址用于定位链路通过_sendMessageToCounterpart向目标链网关发送消息payload 编码了源链from地址含本链 chainid、目标地址、ids与values发出CrosschainMultiTokenTransferSent事件并返回sendId。跨链接收_processMessagefunction _processMessage( address /*gateway*/, bytes32 receiveId, bytes calldata /*sender*/, bytes calldata payload ) internal virtual override { (bytes memory from, bytes memory toEvm, uint256[] memory ids, uint256[] memory values) abi.decode( payload, (bytes, bytes, uint256[], uint256[]) ); address to address(bytes20(toEvm)); _onReceive(to, ids, values); emit CrosschainMultiTokenTransferReceived(receiveId, from, to, ids, values); }接收端由网关投递消息后触发先abi.decode还原 payload取目标 EVM 地址bytes20截断调用_onReceive完成铸造最后发出CrosschainMultiTokenTransferReceived事件。需要注意的是网关的合法性校验在_processMessage之前由_isAuthorizedGateway完成因此该函数内不再重复校验。BridgeMultiToken还定义了两个关键事件event CrosschainMultiTokenTransferSent( bytes32 indexed sendId, address indexed from, bytes to, uint256[] ids, uint256[] values ); event CrosschainMultiTokenTransferReceived( bytes32 indexed receiveId, bytes from, address indexed to, uint256[] ids, uint256[] values );链路与授权CrosschainLinked 如何保证消息可信跨链桥最关键的安全问题是消息来源是否可信。CrosschainLinkedCrosschainLinked.sol负责维护链 → 网关 对端合约的映射并以Link结构体存储struct Link { address gateway; bytes counterpart; // Full InteroperableAddress (chain ref address) } mapping(bytes chain Link) private _links;链路注册与校验构造函数接收Link[] memory links逐个调用_setLink完成初始化注册_setLink会先调用IERC7786GatewaySource(gateway).supportsAttribute(bytes4(0))做冒烟校验非 ERC-7786 实现如 EOA会在此失败从根源上杜绝把地址配成网关同一链不允许重复注册否则抛出LinkAlreadyRegistered(chain)错误注册成功后发出LinkRegistered(gateway, counterpart)事件提供公开只读查询getLink(bytes memory chain)返回(gateway, counterpart)。双向消息安全发送方向_sendMessageToCounterpart(chain, payload, attributes)从映射中取出目标链的网关与对端地址调用IERC7786GatewaySource(gateway).sendMessage(...)投递消息接收方向_isAuthorizedGateway(instance, sender)校验msg.sender等于已注册网关且sender互操作地址等于已注册对端合约。两者同时匹配才放行消息防止任意地址冒充对端或网关发起跨链投递。接收端基类ERC7786RecipientERC7786Recipient.sol 是 ERC-7786 兼容的消息接收器基类对外暴露唯一入口function receiveMessage( bytes32 receiveId, bytes calldata sender, // Binary Interoperable Address bytes calldata payload ) external payable returns (bytes4) { if (!_isAuthorizedGateway(msg.sender, sender)) { revert ERC7786RecipientUnauthorizedGateway(msg.sender, sender); } _processMessage(msg.sender, receiveId, sender, payload); return IERC7786Recipient.receiveMessage.selector; }receiveMessage是网关投递消息的统一入口必须先通过_isAuthorizedGateway校验否则回滚ERC7786RecipientUnauthorizedGateway校验通过后调用_processMessage执行业务逻辑按 ERC-7786 约定网关需保证消息不会重复投递因此接收方无需自行记录已处理的receiveId源码注释强调_processMessage失败必须回滚静默失败会导致消息被标记为已接收且不可重试。接口层draft-IERC7786跨链收发两端的标准接口定义在 draft-IERC7786.sol包含IERC7786GatewaySource源网关事件MessageSent(sendId, sender, recipient, payload, value, attributes)函数supportsAttribute(bytes4) external view returns (bool)与sendMessage(bytes recipient, bytes payload, bytes[] attributes) external payable returns (bytes32 sendId)。若sendId非零则还需网关侧额外的非标准化处理若为 0 表示消息已直接发出。对不支持的 attribute 应回滚UnsupportedAttribute(bytes4 selector)IERC7786Recipient接收端函数receiveMessage(bytes32 receiveId, bytes sender, bytes payload) external payable returns (bytes4)可由网关直接调用。测试驱动的行为验证仓库对ERC1155Crosschain的测试分为两层部署夹具与共享行为测试。部署夹具ERC1155Crosschain.test.js 展示了双链部署与链路配置的标准流程// Chain A: ERC1155 with native bridge integration const tokenA await ethers.deployContract($ERC1155Crosschain, [https://token-cdn-domain/{id}.json, []]); const bridgeA tokenA; // self bridge // Chain B: ERC1155 with native bridge integration const tokenB await ethers.deployContract($ERC1155Crosschain, [ https://token-cdn-domain/{id}.json, [[gateway, chain.toErc7930(bridgeA)]], ]); const bridgeB tokenB; // self bridge // deployment check counterpart setup await expect(bridgeA.$_setLink(gateway, chain.toErc7930(bridgeB), false)) .to.emit(bridgeA, LinkRegistered) .withArgs(gateway, chain.toErc7930(bridgeB));要点链 A 在构造函数传入空链路数组随后通过_setLink补充对端配置链 B 则直接在构造参数中声明链路。由于ERC1155Crosschain自身就是桥注释self bridgebridgeA/bridgeB直接指向代币合约本身。测试还使用$ERC7786GatewayMock作为模拟网关getLocalChain()提供本地链与互操作地址编码工具toErc7930。行为测试覆盖矩阵共享行为测试 BridgeERC1155.behavior.js 对桥接行为做了全面验证链路配置getLink返回正确的(gateway, counterpart)对单向/双向跨链发送分别验证单个与批量场景断言源链发出TransferSingle/TransferBatch销毁、桥发出CrosschainMultiTokenTransferSent、网关发出MessageSent、目标链桥发出CrosschainMultiTokenTransferReceived、目标链铸造TransferSingle/TransferBatch的完整事件链授权模式crosschainTransferFrom支持调用者即 owner与被授权者代转两种场景setApprovalForAll非法转移未授权ERC1155MissingApprovalForAll与余额不足ERC1155InsufficientBalance均正确回滚安全限制非网关地址调用receiveMessage回滚ERC7786RecipientUnauthorizedGateway网关以非对端地址发送消息同样被拒链路重配置_setLink在allowOverridetrue时允许更新并发出事件allowOverridefalse时重复注册回滚LinkAlreadyRegistered非网关地址注册被拒。使用方法与注意事项部署配置要使用ERC1155Crosschain需要继承ERC1155Crosschain或直接使用本仓库 ERC1155.sol 与扩展组合部署构造函数传入 URI 模板如https://token-cdn-domain/{id}.json与Link[]链路数组在每个参与跨链的链上各部署一份实例通过构造函数参数或_setLink把各链的实例互相对端注册到对应网关。关键操作步骤用户调用源链合约的crosschainTransferFrom(from, to, ids, values)其中to为目标的互操作地址可通过InteroperableAddress.formatEvmV1(chainId, addr)生成合约校验授权后销毁本地代币并经网关把编码消息投递到目标链目标链网关调用receiveMessage经_isAuthorizedGateway校验后_processMessage解码 payload 并向接收者铸造等量代币全程可监听CrosschainMultiTokenTransferSent/CrosschainMultiTokenTransferReceived与标准 ERC-1155 的TransferSingle/TransferBatch事件确认状态。注意事项发送端to参数必须是完整互操作地址链引用 地址而非普通address桥接采用 burn/mint 模式源链销毁与目标链铸造必须严格等量才能保证供应守恒网关授权是安全核心_setLink会做supportsAttribute冒烟校验但任何被_isAuthorizedGateway放行的地址都能以任意账户身份发送消息见 ERC7786Recipient.sol 源码注释因此必须确保网关与对端地址配置正确当前实现基于 ERC-7786 draft 接口draft-IERC7786.sol标准仍在演进使用时需关注接口版本兼容性。小结ERC1155Crosschain以最少的代码量约 50 行让 ERC-1155 代币开箱即跨链通过继承BridgeMultiToken获得完整的 ERC-7786 消息发送/接收能力以 burn/mint 实现锁定与解锁以CrosschainLinked的链路映射保证消息来源可信。配合仓库中的共享行为测试与独立桥BridgeERC1155开发者既可以为新代币内嵌原生跨链能力也可以为存量代币部署外挂桥为多链资产流通提供了统一、可验证的参考实现。仓库参考路径变更记录lib/openzeppelin-contracts/.changeset/blue-jars-lay.md扩展实现lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Crosschain.sol桥抽象层lib/openzeppelin-contracts/contracts/crosschain/bridges/abstract/BridgeMultiToken.sol链路管理lib/openzeppelin-contracts/contracts/crosschain/CrosschainLinked.sol接收基类lib/openzeppelin-contracts/contracts/crosschain/ERC7786Recipient.sol标准接口lib/openzeppelin-contracts/contracts/interfaces/draft-IERC7786.sol跨链架构总览lib/openzeppelin-contracts/contracts/crosschain/README.adoc部署夹具lib/openzeppelin-contracts/test/token/ERC1155/extensions/ERC1155Crosschain.test.js共享行为测试lib/openzeppelin-contracts/test/crosschain/BridgeERC1155.behavior.js代币基础lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-Solidity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门