自省 - OpenZeppelin 文档

本文档介绍了OpenZeppelin Contracts库中与合约自省相关的接口和合约,包括IERC165、ERC165、ERC165Checker、IERC1820Registry、IERC1820Implementer和ERC1820Implementer。这些工具允许合约声明并查询其他合约实现的接口,以防止错误并实现复杂的交互。

你当前阅读的不是此文档的最新版本。5.x 是当前版本。

内省

最好在 https://docs.openzeppelin.com/contracts/api/introspection 查看此文档

这组接口和合约处理合约的类型内省,即检查可以在其上调用哪些函数。这通常被称为合约的 interface

以太坊合约没有 interface 的原生概念,因此应用程序通常必须简单地信任它们不会进行不正确的调用。对于受信任的设置,这不是问题,但通常需要与未知和不受信任的第三方地址进行交互。甚至可能没有任何直接调用它们!(例如,ERC20 代币可能会被发送到缺少将其转移出去的方式的合约,从而永远锁定它们)。在这些情况下,合约 声明interface 可以非常有用地防止错误。

有两种主要方法可以解决这个问题。

  • 本地,合约实现 IERC165 并声明一个 interface,第二个合约通过 ERC165Checker 直接查询它。

  • 全局,全局和唯一的注册表(IERC1820Registry)用于注册特定 interfaceIERC1820Implementer)的实现者。然后查询注册表,这允许更复杂的设置,例如为外部拥有的帐户实现 interface 的合约。

请注意,在所有情况下,帐户只是 声明 它们的 interface,但它们不需要实际实现它们。因此,该机制可用于防止错误并允许复杂的交互(请参阅 ERC777),但不能依赖它来保证安全性。

本地

IERC165

ERC165 标准的 interface,如 EIP 中定义。

实现者可以声明对合约 interface 的支持,然后可以由其他人查询(ERC165Checker)。

有关实现,请参见 ERC165

函数

supportsInterface(bytes4 interfaceId) → bool external

如果此合约实现了由 interfaceId 定义的 interface,则返回 true。请参阅相应的 EIP section 以了解有关如何创建这些 id 的更多信息。

此函数调用必须使用少于 30 000 的 gas。

ERC165

IERC165 interface 的实现。

合约可以从中继承并调用 _registerInterface 来声明 它们对 interface 的支持。

函数

constructor() internal
supportsInterface(bytes4 interfaceId) → bool public

参见 IERC165.supportsInterface

时间复杂度 O(1),保证始终使用少于 30 000 的 gas。

_registerInterface(bytes4 interfaceId) internal

将合约注册为由 interfaceId 定义的 interface 的实现者。对实际 ERC165 interface 的支持是自动的, 不需要注册其 interface id。

参见 IERC165.supportsInterface

要求:

  • interfaceId 不能是 ERC165 无效 interface0xffffffff)。

ERC165Checker

用于查询通过 IERC165 声明的 interface 支持的库。

请注意,这些函数返回查询的实际结果:如果不支持 interface,它们不会 revert。由调用者决定 在这种情况下该怎么做。

函数

supportsERC165(address account) → bool internal

如果 account 支持 IERC165 interface,则返回 true。

supportsInterface(address account, bytes4 interfaceId) → bool internal

如果 account 支持由 interfaceId 定义的 interface,则返回 true。对 IERC165 本身的支持会自动查询。

参见 IERC165.supportsInterface

getSupportedInterfaces(address account, bytes4[] interfaceIds) → bool[] internal

返回一个布尔数组,其中每个值对应于传入的 interface 以及它们是否受支持。这允许 你可以批量检查合约的 interface,在你期望某些 interface 可能不受支持的情况下。

参见 IERC165.supportsInterface

自 v3.4 起可用。

supportsAllInterfaces(address account, bytes4[] interfaceIds) → bool internal

如果 account 支持 interfaceIds 中定义的所有 interface,则返回 true。对 IERC165 本身的支持会自动查询。

批量查询可以通过跳过重复检查来节省 gas IERC165 支持。

参见 IERC165.supportsInterface

全局

IERC1820Registry

全局 ERC1820 注册表的 interface,如 EIP 中定义。帐户可以在此注册表中注册 interface 的实现者,以及查询支持。

实现者可以由多个帐户共享,并且还可以为每个帐户实现多个 interface。合约可以为自己实现 interface,但外部拥有的帐户 (EOA) 必须将其委托给 合约。

IERC165 interface 也可以通过注册表查询。

有关深入的解释和源代码分析,请参见 EIP 文本。

函数

事件

setManager(address account, address newManager) external

newManager 设置为 account 的管理器。帐户的管理器能够为其设置 interface 实现者。

默认情况下,每个帐户都是自己的管理器。在 newManager 中传递值 0x0 将管理器重置为此初始状态。

发出一个 ManagerChanged 事件。

要求:

  • 调用者必须是 account 的当前管理器。
getManager(address account) → address external

返回 account 的管理器。

参见 setManager

setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external

implementer 合约设置为 accountinterfaceHash 的实现者。

account 为零地址是调用者地址的别名。零地址也可以在 implementer 中使用以删除旧的地址。

参见 interfaceHash 以了解如何创建它们。

发出一个 InterfaceImplementerSet 事件。

要求:

getInterfaceImplementer(address account, bytes32 _interfaceHash) → address external

返回 accountinterfaceHash 的实现者。如果未注册任何此类 实现者,则返回零地址。

如果 interfaceHashIERC165 interface id(即,它以 28 结尾 零),将查询 account 以获取对其的支持。

account 为零地址是调用者地址的别名。

interfaceHash(string interfaceName) → bytes32 external

返回 interfaceNameinterface 哈希,如相应的 EIP 的 section

updateERC165Cache(address account, bytes4 interfaceId) external
implementsERC165Interface(address account, bytes4 interfaceId) → bool external
implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) → bool external
InterfaceImplementerSet(address account, bytes32 interfaceHash, address implementer) event
ManagerChanged(address account, address newManager) event

IERC1820Implementer

ERC1820 实现者的 interface,如 EIP 中定义。 由将注册为 IERC1820Registry 中的实现者的合约使用。

函数

canImplementInterfaceForAddress(bytes32 interfaceHash, address account) → bytes32 external

如果此合约 对 account 实现了 interfaceHash,则返回一个特殊值(ERC1820_ACCEPT_MAGIC)。

参见 IERC1820Registry.setInterfaceImplementer

ERC1820Implementer

IERC1820Implementer interface 的实现。

合约可以从中继承并调用 _registerInterfaceForAddress 来 声明他们愿意成为实现者。 然后应该调用 IERC1820Registry.setInterfaceImplementer 以完成注册。

函数

canImplementInterfaceForAddress(bytes32 interfaceHash, address account) → bytes32 public
_registerInterfaceForAddress(bytes32 interfaceHash, address account) internal

将合约声明为愿意成为 accountinterfaceHash 的实现者。

参见 IERC1820Registry.setInterfaceImplementerIERC1820Registry.interfaceHash

← GSN

Math →

  • 原文链接: docs.openzeppelin.com/co...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
OpenZeppelin
OpenZeppelin
江湖只有他的大名,没有他的介绍。