实用工具 - OpenZeppelin 文档

本文档介绍了OpenZeppelin Contracts库中的实用工具合约和库,用于提高智能合约的安全性、处理新型数据类型以及安全地使用底层原语。包括安全工具(如Pausable和ReentrancyGuard),以及用于处理地址、数组和字符串的库。此外,还介绍了用于处理计数器、可枚举映射和集合的实用工具,以及安全使用CREATE2操作码的工具。

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

实用工具

https://docs.openzeppelin.com/contracts/api/utils 查看此文档效果更佳

包含实用函数的各种合约和库,你可以使用它们来提高安全性、处理新的数据类型或安全地使用底层原语。

安全工具包括:

AddressArraysStrings 库提供了更多与这些原生数据类型相关的操作,而 SafeCast 增加了在不同的有符号和无符号数字类型之间安全转换的方法。

对于新的数据类型:

  • Counters: 一种获取只能递增或递减的计数器的简单方法。对于 ID 生成、计数合约活动等非常有用。

  • EnumerableMap: 类似于 Solidity 的 mapping 类型,但具有键值枚举:这将让你知道映射有多少条目,并遍历它们(mapping 无法做到)。

  • EnumerableSet: 类似于 EnumerableMap,但用于集合。可用于存储特权帐户、已颁发的 ID 等。

因为 Solidity 不支持泛型类型,EnumerableMapEnumerableSet 被专门用于有限数量的键值类型。<br>从 v3.0 开始,EnumerableMap 支持 uint256 → address ( UintToAddressMap),EnumerableSet 支持 addressuint256 ( AddressSetUintSet)。

最后,Create2 包含安全使用 CREATE2 EVM 操作码的所有必要实用工具,而无需处理底层汇编。

合约

Pausable

合约模块,允许子项实现紧急停止机制,该机制可以由授权帐户触发。

此模块通过继承使用。它将提供修饰符 whenNotPausedwhenPaused,这些修饰符可以应用于合约的函数。请注意,仅仅包含此模块不会使它们可暂停,只有在修饰符就位后才会可暂停。

修饰符

函数

事件

whenNotPaused() 修饰符

修饰符,使函数仅在合约未暂停时可调用。

要求:

  • 合约不得暂停。
whenPaused() 修饰符

修饰符,使函数仅在合约暂停时可调用。

要求:

  • 合约必须暂停。
constructor() 内部函数

以未暂停状态初始化合约。

paused() → bool 公共函数

如果合约已暂停,则返回 true,否则返回 false。

_pause() 内部函数

触发停止状态。

要求:

  • 合约不得暂停。
_unpause() 内部函数

返回正常状态。

要求:

  • 合约必须暂停。
Paused(address account) 事件

当暂停由 account 触发时发出。

Unpaused(address account) 事件

当暂停由 account 解除时发出。

ReentrancyGuard

合约模块,有助于防止对函数的重入调用。

继承自 ReentrancyGuard 将使 nonReentrant 修饰符可用,该修饰符可应用于函数以确保没有对它们的嵌套(重入)调用。

请注意,由于存在单个 nonReentrant 保护,因此标记为 nonReentrant 的函数可能不会相互调用。可以通过使这些函数成为 private,然后向它们添加 external nonReentrant 入口点来解决此问题。

如果你想了解更多关于重入以及防止重入的替代方法,请查看我们的博文 伊斯坦布尔之后的重入

修饰符

函数

nonReentrant() 修饰符

防止合约直接或间接地调用自身。 不支持从另一个 nonReentrant 函数调用 nonReentrant 函数。可以通过使 nonReentrant 函数为 external,并使其调用执行实际工作的 private 函数来防止这种情况发生。

constructor() 内部函数

Address

与地址类型相关的函数的集合

函数

isContract(address account) → bool 内部函数

如果 account 是合约,则返回 true。

假设此函数返回 false 的地址是外部拥有的帐户 (EOA) 而不是合约是不安全的。<br>其中,isContract 将为以下类型的地址返回 false:<br>- 外部拥有的帐户<br> <br>- 正在构造的合约<br> <br>- 将创建合约的地址<br> <br>- 曾经存在合约但已被销毁的地址
sendValue(address payable recipient, uint256 amount) 内部函数

Solidity 的 transfer 的替代方案:将 amount wei 发送到 recipient,转发所有可用的 gas 并在出错时恢复。

EIP1884 增加了某些操作码的 gas 成本,可能会使合约超过 transfer 施加的 2300 gas 限制,从而使它们无法通过 transfer 接收资金。sendValue 消除了此限制。

了解更多

因为控制权已转移到 recipient,因此必须小心不要创建重入漏洞。考虑使用 ReentrancyGuardchecks-effects-interactions 模式
functionCall(address target, bytes data) → bytes 内部函数

使用底层 call 执行 Solidity 函数调用。plain`call` 是函数调用的不安全替代方案:请改用此函数。

如果 target 恢复并带有恢复原因,则此函数会将其弹出(类似于常规的 Solidity 函数调用)。

返回原始返回的数据。要转换为预期的返回值,请使用 abi.decode

要求:

  • target 必须是合约。

  • 使用 data 调用 target 不得恢复。

自 v3.1 起可用。

functionCall(address target, bytes data, string errorMessage) → bytes 内部函数

functionCall 相同,但 errorMessage 作为 target 恢复时的回退恢复原因。

自 v3.1 起可用。

functionCallWithValue(address target, bytes data, uint256 value) → bytes 内部函数

functionCall 相同,但也向 target 转移 value wei。

要求:

  • 调用合约必须具有至少 value 的 ETH 余额。

  • 调用的 Solidity 函数必须是 payable

自 v3.1 起可用。

functionCallWithValue(address target, bytes data, uint256 value, string errorMessage) → bytes 内部函数

functionCallWithValue 相同,但 errorMessage 作为 target 恢复时的回退恢复原因。

自 v3.1 起可用。

functionStaticCall(address target, bytes data) → bytes 内部函数

functionCall 相同,但执行静态调用。

自 v3.3 起可用。

functionStaticCall(address target, bytes data, string errorMessage) → bytes 内部函数

functionCall 相同,但执行静态调用。

自 v3.3 起可用。

functionDelegateCall(address target, bytes data) → bytes 内部函数

functionCall 相同,但执行委托调用。

自 v3.4 起可用。

functionDelegateCall(address target, bytes data, string errorMessage) → bytes 内部函数

functionCall 相同,但执行委托调用。

自 v3.4 起可用。

Arrays

与数组类型相关的函数的集合。

函数

findUpperBound(uint256[] array, uint256 element) → uint256 内部函数

搜索已排序的 array 并返回包含大于或等于 element 的值的第一个索引。如果不存在此类索引(即,数组中的所有值都严格小于 element),则返回数组长度。时间复杂度 O(log n)。

array 预计按升序排序,且不包含重复元素。

Counters

提供只能递增或递减 1 的计数器。这可以用于例如跟踪映射中的元素数量、颁发 ERC721 id 或计数请求 id。

包含 using Counters for Counters.Counter; 由于不可能通过递增 1 使 256 位整数溢出,因此 increment 可以跳过 SafeMath 溢出检查,从而节省 gas。但这确实假设了正确的使用,即永远不会直接访问底层的 _value

函数

current(struct Counters.Counter counter) → uint256 内部函数
increment(struct Counters.Counter counter) 内部函数
decrement(struct Counters.Counter counter) 内部函数

Create2

帮助程序,使 CREATE2 EVM 操作码的使用更容易、更安全。 CREATE2 可用于提前计算智能合约的部署地址,从而实现有趣的新机制,称为“反事实交互”。

有关更多信息,请参见 EIP

函数

deploy(uint256 amount, bytes32 salt, bytes bytecode) → address 内部函数

使用 CREATE2 部署合约。可以通过 computeAddress 提前知道合约的部署地址。

合约的字节码可以从 Solidity 中通过 type(contractName).creationCode 获得。

要求:

  • bytecode 不得为空。

  • salt 必须尚未被用于 bytecode

  • 工厂必须具有至少 amount 的余额。

  • 如果 amount 为非零值,则 bytecode 必须具有 payable 构造函数。

computeAddress(bytes32 salt, bytes32 bytecodeHash) → address 内部函数

返回如果通过 deploy 部署合约,该合约将存储的地址。bytecodeHashsalt 的任何更改都将导致新的目标地址。

computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) → address 内部函数

返回如果从位于 deployer 的合约通过 deploy 部署合约,该合约将存储的地址。如果 deployer 是此合约的地址,则返回与 computeAddress 相同的值。

EnumerableMap

用于管理 Solidity 的可枚举变体的库 mapping 类型。

映射具有以下属性:

  • 条目的添加、删除和存在检查以恒定时间 (O(1)) 完成。

  • 条目的枚举以 O(n) 完成。不保证排序。

contract Example {
    // 添加库方法
    using EnumerableMap for EnumerableMap.UintToAddressMap;

    // 声明一个集合状态变量
    EnumerableMap.UintToAddressMap private myMap;
}

从 v3.0.0 开始,仅支持 uint256 → address ( UintToAddressMap) 类型的映射。

函数

set(struct EnumerableMap.UintToAddressMap map, uint256 key, address value) → bool 内部函数

向映射添加键值对,或更新现有键的值。O(1)。

如果键已添加到映射,即它尚未存在,则返回 true。

remove(struct EnumerableMap.UintToAddressMap map, uint256 key) → bool 内部函数

从集合中删除一个值。O(1)。

如果键已从映射中删除,即它存在,则返回 true。

contains(struct EnumerableMap.UintToAddressMap map, uint256 key) → bool 内部函数

如果键在映射中,则返回 true。O(1)。

length(struct EnumerableMap.UintToAddressMap map) → uint256 内部函数

返回映射中的元素数。O(1)。

at(struct EnumerableMap.UintToAddressMap map, uint256 index) → uint256, address 内部函数

返回存储在集合中位置 index 处的元素。O(1)。 请注意,不保证数组内值的排序,并且当添加或删除更多值时,它可能会更改。

要求:

  • index 必须严格小于 length
tryGet(struct EnumerableMap.UintToAddressMap map, uint256 key) → bool, address 内部函数

尝试返回与 key 关联的值。O(1)。 如果 key 不在映射中,则不会恢复。

自 v3.4 起可用。

get(struct EnumerableMap.UintToAddressMap map, uint256 key) → address 内部函数

返回与 key 关联的值。O(1)。

要求:

  • key 必须在映射中。
get(struct EnumerableMap.UintToAddressMap map, uint256 key, string errorMessage) → address 内部函数

get 相同,当 key 不在映射中时,使用自定义错误消息。

此函数已弃用,因为它需要不必要地为错误消息分配内存。对于自定义恢复原因,请使用 tryGet

EnumerableSet

用于管理原始类型的集合的库。

集合具有以下属性:

  • 元素的添加、删除和存在检查以恒定时间 (O(1)) 完成。

  • 元素的枚举以 O(n) 完成。不保证排序。

contract Example {
    // 添加库方法
    using EnumerableSet for EnumerableSet.AddressSet;

    // 声明一个集合状态变量
    EnumerableSet.AddressSet private mySet;
}

截至 v3.3.0,支持 bytes32 ( Bytes32Set)、address ( AddressSet) 和 uint256 ( UintSet) 类型的集合。

函数

add(struct EnumerableSet.Bytes32Set set, bytes32 value) → bool 内部函数

将一个值添加到一个集合中。O(1)。

如果该值已添加到集合中,即它尚未存在,则返回 true。

remove(struct EnumerableSet.Bytes32Set set, bytes32 value) → bool 内部函数

从集合中删除一个值。O(1)。

如果该值已从集合中删除,即它存在,则返回 true。

contains(struct EnumerableSet.Bytes32Set set, bytes32 value) → bool 内部函数

如果该值在集合中,则返回 true。O(1)。

length(struct EnumerableSet.Bytes32Set set) → uint256 内部函数

返回集合中的值的数量。O(1)。

at(struct EnumerableSet.Bytes32Set set, uint256 index) → bytes32 内部函数

返回存储在集合中位置 index 处的值。O(1)。

请注意,不保证数组内值的排序,并且当添加或删除更多值时,它可能会更改。

要求:

  • index 必须严格小于 length
add(struct EnumerableSet.AddressSet set, address value) → bool 内部函数

将一个值添加到一个集合中。O(1)。

如果该值已添加到集合中,即它尚未存在,则返回 true。

remove(struct EnumerableSet.AddressSet set, address value) → bool 内部函数

从集合中删除一个值。O(1)。

如果该值已从集合中删除,即它存在,则返回 true。

contains(struct EnumerableSet.AddressSet set, address value) → bool 内部函数

如果该值在集合中,则返回 true。O(1)。

length(struct EnumerableSet.AddressSet set) → uint256 内部函数

返回集合中的值的数量。O(1)。

at(struct EnumerableSet.AddressSet set, uint256 index) → address 内部函数

返回存储在集合中位置 index 处的值。O(1)。

请注意,不保证数组内值的排序,并且当添加或删除更多值时,它可能会更改。

要求:

  • index 必须严格小于 length
add(struct EnumerableSet.UintSet set, uint256 value) → bool 内部函数

将一个值添加到一个集合中。O(1)。

如果该值已添加到集合中,即它尚未存在,则返回 true。

remove(struct EnumerableSet.UintSet set, uint256 value) → bool 内部函数

从集合中删除一个值。O(1)。

如果该值已从集合中删除,即它存在,则返回 true。

contains(struct EnumerableSet.UintSet set, uint256 value) → bool 内部函数

如果该值在集合中,则返回 true。O(1)。

length(struct EnumerableSet.UintSet set) → uint256 内部函数

返回集合上的值的数量。O(1)。

at(struct EnumerableSet.UintSet set, uint256 index) → uint256 内部函数

返回存储在集合中位置 index 处的值。O(1)。

请注意,不保证数组内值的排序,并且当添加或删除更多值时,它可能会更改。

要求:

  • index 必须严格小于 length

SafeCast

带有添加的溢出检查的 Solidity 的 uintXX/intXX 强制转换运算符的包装器。

在 Solidity 中,从 uint256/int256 向下转换不会在溢出时恢复。这很容易导致不需要的利用或错误,因为开发人员通常假设溢出会引发错误。SafeCast 通过在此类操作溢出时恢复事务来恢复这种直觉。

使用此库而不是未检查的操作可以消除一整类错误,因此建议始终使用它。

可以与 SafeMathSignedSafeMath 组合以将其扩展到更小的类型,方法是在 uint256int256 上执行所有数学运算,然后向下转换。

函数

toUint128(uint256 value) → uint128 内部函数

从 uint256 返回向下转换的 uint128,在溢出时- 输入必须符合 32 位

toUint16(uint256 value) → uint16 internal

从 uint256 返回降转型后的 uint16,在溢出时恢复(当输入大于最大的 uint16 时)。

对应于 Solidity 的 uint16 运算符。

要求:

  • 输入必须符合 16 位
toUint8(uint256 value) → uint8 internal

从 uint256 返回降转型后的 uint8,在溢出时恢复(当输入大于最大的 uint8 时)。

对应于 Solidity 的 uint8 运算符。

要求:

  • 输入必须符合 8 位。
toUint256(int256 value) → uint256 internal

将有符号 int256 转换为无符号 uint256。

要求:

  • 输入必须大于等于 0。
toInt128(int256 value) → int128 internal

从 int256 返回降转型后的 int128,在溢出时恢复(当输入小于最小的 int128 或大于最大的 int128 时)。

对应于 Solidity 的 int128 运算符。

要求:

  • 输入必须符合 128 位

可用版本:v3.1

toInt64(int256 value) → int64 internal

从 int256 返回降转型后的 int64,在溢出时恢复(当输入小于最小的 int64 或大于最大的 int64 时)。

对应于 Solidity 的 int64 运算符。

要求:

  • 输入必须符合 64 位

可用版本:v3.1

toInt32(int256 value) → int32 internal

从 int256 返回降转型后的 int32,在溢出时恢复(当输入小于最小的 int32 或大于最大的 int32 时)。

对应于 Solidity 的 int32 运算符。

要求:

  • 输入必须符合 32 位

可用版本:v3.1

toInt16(int256 value) → int16 internal

从 int256 返回降转型后的 int16,在溢出时恢复(当输入小于最小的 int16 或大于最大的 int16 时)。

对应于 Solidity 的 int16 运算符。

要求:

  • 输入必须符合 16 位

可用版本:v3.1

toInt8(int256 value) → int8 internal

从 int256 返回降转型后的 int8,在溢出时恢复(当输入小于最小的 int8 或大于最大的 int8 时)。

对应于 Solidity 的 int8 运算符。

要求:

  • 输入必须符合 8 位。

可用版本:v3.1

toInt256(uint256 value) → int256 internal

将无符号 uint256 转换为有符号 int256。

要求:

  • 输入必须小于等于 maxInt256。

Strings

字符串操作。

函数

toString(uint256 value) → string internal

uint256 转换为其 ASCII string 表示形式。

← Proxy

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

0 条评论

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