实用工具 - OpenZeppelin 文档

本文档是 OpenZeppelin 合约库中 Utilities 模块的 API 文档,介绍了各种实用合约和库,包括数学运算、安全类型转换、ECDSA 签名、哈希函数、Merkle 证明、EIP712 签名、可重入保护、可暂停功能、计数器、ERC165 接口检测、位图、可枚举的 Map 和 Set、双端队列、环形缓冲区、检查点、堆、Merkle 树、CREATE2 部署、以及 address、arrays、bytes、strings 相关的实用函数。

实用工具

更好的查看此文档的方式:https://docs.openzeppelin.com/contracts/api/utils

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

  • Math, SignedMath: 各种算术函数的实现。

  • SafeCast: 检查过的向下转型函数,以避免静默截断。

  • ECDSA, MessageHashUtils: 用于与 ECDSA 签名交互的库。

  • P256: 用于验证和从 secp256r1 签名恢复公钥的库。

  • RSA: 具有 RSA PKCS#1 v1.5 签名验证实用程序的库。

  • SignatureChecker: 一个库助手,用于支持来自 EOA 的常规 ECDSA 以及智能合约的 ERC-1271 签名。

  • Hashes: 常用哈希函数。

  • MerkleProof: 用于验证 Merkle Tree 证明的函数。

  • EIP712: 合约包含的函数允许根据 EIP-712 处理签名类型结构数据。

  • ReentrancyGuard: 一个修饰器,可以防止某些函数在执行期间的重入。

  • ReentrancyGuardTransient: ReentrancyGuard 的变体,它使用瞬态存储(EIP-1153)。

  • Pausable: 一种常见的紧急响应机制,可以在补救措施待定时暂停功能。

  • Nonces: 用于跟踪和验证仅递增的地址 Nonce 的实用程序。

  • NoncesKeyed: Nonces 的替代方案,支持遵循 ERC-4337 规范 的键控 Nonce。

  • ERC165, ERC165Checker: 用于检查合约支持的接口的实用程序。

  • BitMaps: 一个简单的库,用于以有效的方式管理映射到数字索引的布尔值。

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

  • EnumerableSet: 就像 EnumerableMap 一样,但是用于集合。 可以用于存储特权帐户、已颁发的 ID 等。

  • DoubleEndedQueue: 双端队列的实现,其值可以从两侧添加或删除。 对 FIFO 和 LIFO 结构有用。

  • CircularBuffer: 一种数据结构,用于存储最后 N 个推送到它的值。

  • Checkpoints: 一种数据结构,用于存储映射到严格递增键的值。 可用于随时间存储和访问值。

  • Heap: 一个在存储中实现二叉堆的库。

  • MerkleTree: 包含 Merkle Tree 数据结构和辅助函数的库。

  • Create2: CREATE2 EVM 操作码 的包装器,用于安全使用,无需处理底层汇编。

  • Address: 用于重载 Solidity 的 address 类型的函数集合。

  • Arrays: 对 arrays 进行操作的函数集合。

  • Base64: 根据 RFC-4648 的链上 base64 和 base64URL 编码。

  • Bytes: 字节对象的常用操作。

  • Calldata: 用于操作 Calldata 的助手。

  • Strings: 用于字符串格式化的常用操作。

  • ShortStrings: 用于将短字符串编码(和解码)为单个 bytes32 插槽以优化成本的库。 短字符串限制为 31 个字符。

  • SlotDerivation: 用于从 ERC-7201 命名空间以及从映射和数组等构造中派生存储插槽的方法。

  • StorageSlot: 用于访问格式化为常见原始类型的特定存储插槽的方法。

  • TransientSlot: 用于从瞬态存储读取和写入的原语(目前仅支持 Value type)。

  • Multicall: 抽象合约,带有一个实用程序,允许将多个调用批量处理到单个事务中。 对于允许 EOA 一次执行多个操作很有用。

  • Context: 一个用于抽象当前执行上下文中的发送者和 Calldata 的实用程序。

  • Packing: 一个用于将多个值打包和解压缩到 bytes32 中的库

  • Panic: 一个使用 Solidity panic codes 进行回退的库。

  • Comparators: 一个包含比较器函数以与 Heap 库一起使用的库。

  • CAIP2, CAIP10: 用于格式化和解析 CAIP-2 和 CAIP-10 标识符的库。

因为 Solidity 不支持泛型类型,所以 EnumerableMapEnumerableSet 专门用于有限数量的键值类型。

Math

Math

import "@openzeppelin/contracts/utils/math/Math.sol";

Solidity 语言中缺少的标准数学实用程序。

函数

##### `add512(uint256 a, uint256 b) → uint256 high, uint256 low` internal

返回两个 uint256 的 512 位加法。

结果存储在两个 256 变量中,使得 sum = high * 2²⁵⁶ + low。

##### `mul512(uint256 a, uint256 b) → uint256 high, uint256 low` internal

返回两个 uint256 的 512 位乘法。

结果存储在两个 256 变量中,使得 product = high * 2²⁵⁶ + low。

##### `tryAdd(uint256 a, uint256 b) → bool success, uint256 result` internal

返回两个无符号整数的加法,带有一个 Success 标志(无溢出)。

##### `trySub(uint256 a, uint256 b) → bool success, uint256 result` internal

返回两个无符号整数的减法,带有一个 Success 标志(无溢出)。

##### `tryMul(uint256 a, uint256 b) → bool success, uint256 result` internal

返回两个无符号整数的乘法,带有一个 Success 标志(无溢出)。

##### `tryDiv(uint256 a, uint256 b) → bool success, uint256 result` internal

返回两个无符号整数的除法,带有一个 Success 标志(无被零除)。

##### `tryMod(uint256 a, uint256 b) → bool success, uint256 result` internal

返回两个无符号整数相除的余数,带有一个 Success 标志(无被零除)。

##### `saturatingAdd(uint256 a, uint256 b) → uint256` internal

无符号饱和加法,绑定到 2²⁵⁶ - 1 而不是溢出。

##### `saturatingSub(uint256 a, uint256 b) → uint256` internal

无符号饱和减法,绑定到零而不是溢出。

##### `saturatingMul(uint256 a, uint256 b) → uint256` internal

无符号饱和乘法,绑定到 2²⁵⁶ - 1 而不是溢出。

##### `ternary(bool condition, uint256 a, uint256 b) → uint256` internal

a ? b : c 的无分支三元评估。 Gas 成本是恒定的。

此函数可以减少字节码大小,并在单独使用时消耗更少的 gas。<br>但是,编译器可以优化 Solidity 三元运算(即 a ? b : c)以仅计算<br>在需要时使用一个分支,从而使此函数更昂贵。
##### `max(uint256 a, uint256 b) → uint256` internal

返回两个数字中最大的一个。

##### `min(uint256 a, uint256 b) → uint256` internal

返回两个数字中最小的一个。

##### `average(uint256 a, uint256 b) → uint256` internal

返回两个数字的平均值。 结果向零舍入。

##### `ceilDiv(uint256 a, uint256 b) → uint256` internal

返回两个数字相除的上限。

这与标准除法 / 的不同之处在于它向无穷大舍入而不是向零舍入。

##### `mulDiv(uint256 x, uint256 y, uint256 denominator) → uint256 result` internal

计算 floor(x * y / denominator) 的完整精度。 如果结果溢出 uint256 或 denominator == 0,则抛出异常。

最初的功劳归于 MIT 许可下的 Remco Bloemen ( https://xn—​2-umb.com/21/muldiv),Uniswap Labs 在 MIT 许可下进行了进一步编辑。

##### `mulDiv(uint256 x, uint256 y, uint256 denominator, enum Math.Rounding rounding) → uint256` internal

使用完整精度计算 x * y / denominator,并遵循所选的舍入方向。

##### `mulShr(uint256 x, uint256 y, uint8 n) → uint256 result` internal

计算 floor(x * y >> n) 的完整精度。 如果结果溢出 uint256,则抛出异常。

##### `mulShr(uint256 x, uint256 y, uint8 n, enum Math.Rounding rounding) → uint256` internal

使用完整精度计算 x * y >> n,并遵循所选的舍入方向。

##### `invMod(uint256 a, uint256 n) → uint256` internal

计算 Z/nZ 中数字的模乘逆元。

如果 n 是素数,则 Z/nZ 是一个域。 在这种情况下,所有元素都是可逆的,除了 0。 如果 n 不是素数,则 Z/nZ 不是一个域,并且某些元素可能不可逆。

如果输入值不可逆,则返回 0。

如果你确定 n 是(大)素数,则使用费马小定理并使用<br>Math.modExp(a, n - 2, n) 获取逆可能更便宜。 请参阅 invModPrime
##### `invModPrime(uint256 a, uint256 p) → uint256` internal

invMod 的变体。 效率更高,但仅在已知 p 是大于 2 的素数时才有效。

费马小定理,我们知道如果 p 是素数,则 a(p-1) ≡ 1 mod p *。 因此,我们有 `a a**(p-2) ≡ 1 mod p,这意味着a**(p-2)` 是 a 在 Fp 中的模乘逆元。

此函数不检查 p 是否是大于 2 的素数。
##### `modExp(uint256 b, uint256 e, uint256 m) → uint256` internal

返回指定底数、指数和模数的模幂运算 (b ** e % m)

要求: - 模数不能为零 - 对预编译合约的底层 staticcall 必须成功

只有在基础调用成功时,结果才有效。 使用此函数时,请确保你使用的链支持<br>EIP-198 中指定的地址 0x05 处的模幂预编译合约。 否则,<br>由于缺少回退,底层函数将成功,但结果可能被错误地解释为 0。
##### `tryModExp(uint256 b, uint256 e, uint256 m) → bool success, uint256 result` internal

返回指定底数、指数和模数的模幂运算 (b ** e % m)。 它包括Success标志,指示操作是否成功。 如果尝试以 0 为模运算或底层预编译合约回退,则操作将被标记为失败。

只有当 Success 标志为 true 时,结果才有效。 使用此函数时,请确保你使用的链支持<br>EIP-198 中指定的地址 0x05 处的模幂预编译合约。 否则,由于缺少回退,底层函数将成功,但结果可能被错误地解释为 0。
##### `modExp(bytes b, bytes e, bytes m) → bytes` internal

modExp 的变体,支持任意长度的输入。

##### `tryModExp(bytes b, bytes e, bytes m) → bool success, bytes result` internal

tryModExp 的变体,支持任意长度的输入。

##### `sqrt(uint256 a) → uint256` internal

返回数字的平方根。 如果该数字不是完全平方数,则该值将向零舍入。

此方法基于牛顿法计算平方根; 该算法仅限于仅使用整数运算。

##### `sqrt(uint256 a, enum Math.Rounding rounding) → uint256` internal

计算 sqrt(a),并遵循所选的舍入方向。

##### `log2(uint256 x) → uint256 r` internal

返回以 2 为底的正值的对数,并向零舍入。 如果给定 0,则返回 0。

##### `log2(uint256 value, enum Math.Rounding rounding) → uint256` internal

返回以 2 为底的正值的对数,并遵循所选的舍入方向。 如果给定 0,则返回 0。

##### `log10(uint256 value) → uint256` internal

返回以 10 为底的正值的对数,并向零舍入。 如果给定 0,则返回 0。

##### `log10(uint256 value, enum Math.Rounding rounding) → uint256` internal

返回以 10 为底的正值的对数,并遵循所选的舍入方向。 如果给定 0,则返回 0。

##### `log256(uint256 x) → uint256 r` internal

返回以 256 为底的正值的对数,并向零舍入。 如果给定 0,则返回 0。

将结果加一可得到将 Value 表示为十六进制字符串所需的十六进制符号对数。

##### `log256(uint256 value, enum Math.Rounding rounding) → uint256` internal

返回以 256 为底的正值的对数,并遵循所选的舍入方向。 如果给定 0,则返回 0。

##### `unsignedRoundsUp(enum Math.Rounding rounding) → bool` internal

返回提供的舍入模式是否被认为是无符号整数的向上舍入。

SignedMath

import "@openzeppelin/contracts/utils/math/SignedMath.sol";

Solidity 语言中缺少的标准有符号数学实用程序。

函数

##### `ternary(bool condition, int256 a, int256 b) → int256` internal

a ? b : c 的无分支三元评估。 Gas 成本是恒定的。

此函数可以减少字节码大小,并在单独使用时消耗更少的 gas。<br>但是,编译器可以优化 Solidity 三元运算(即 a ? b : c)以仅计算<br>在需要时使用一个分支,从而使此函数更昂贵。
##### `max(int256 a, int256 b) → int256` internal

返回两个有符号数字中最大的一个。

##### `min(int256 a, int256 b) → int256` internal

返回两个有符号数字中最小的一个。

##### `average(int256 a, int256 b) → int256` internal

返回两个有符号数字的平均值,没有溢出。 结果向零舍入。

##### `abs(int256 n) → uint256` internal

返回有符号值的绝对无符号值。

SafeCast

import "@openzeppelin/contracts/utils/math/SafeCast.sol";

Solidity 的 uintXX/intXX/bool 强制转换运算符的包装器,增加了溢出 检查。

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

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

函数

错误

toUint248(uint256 value) → uint248 internal

从 uint256 返回向下转换的 uint248,在溢出时回退(当输入大于最大 uint248 时)。

与 Solidity 的 uint248 运算符对应。

要求:

  • 输入必须适合 248 位
toUint240(uint256 value) → uint240 internal

从 uint256 返回向下转换的 uint240,在溢出时回退(当输入大于最大 uint240 时)。

与 Solidity 的 uint240 运算符对应。

要求:

  • 输入必须适合 240 位
toUint232(uint256 value) → uint232 internal

从 uint256 返回向下转换的 uint232,在溢出时回退(当输入大于最大 uint232 时)。

与 Solidity 的 uint232 运算符对应。

要求:

  • 输入必须适合 232 位
toUint224(uint256 value) → uint224 internal

从 uint256 返回向下转换的 uint224,在溢出时回退(当输入大于最大 uint224 时)。

与 Solidity 的 uint224 运算符对应。

要求:

  • 输入必须适合 224 位
toUint216(uint256 value) → uint216 internal

从 uint256 返回向下转换的 uint216,在溢出时回退(当输入大于最大 uint216 时)。

与 Solidity 的 uint216 运算符对应。

要求:

  • 输入必须适合 216 位
toUint208(uint256 value) → uint208 internal

从 uint256 返回向下转换的 uint208,在溢出时回退(当输入大于最大 uint208 时)。

与 Solidity 的 uint208 运算符对应。

要求:

  • 输入必须适合 208 位
toUint200(uint256 value) → uint200 internal

从 uint256 返回向下转换的 uint200,在溢出时回退(当输入大于最大 uint200 时)。

与 Solidity 的 uint200 运算符对应。

要求:

  • 输入必须适合 200 位
toUint192(uint256 value) → uint192 internal

从 uint256 返回向下转换的 uint192,在溢出时回退(当输入大于最大 uint192 时)。

与 Solidity 的 uint192 运算符对应。

要求:

  • 输入必须适合 192 位
toUint184(uint256 value) → uint184 internal

从 uint256 返回向下转换的 uint184,在溢出时回退(当输入大于最大 uint184 时)。

与 Solidity 的 uint184 运算符对应。

要求:

  • 输入必须适合 184 位
toUint176(uint256 value) → uint176 internal

从 uint256 返回向下转换的 uint176,在溢出时回退(当输入大于最大 uint176 时)。

与 Solidity 的 uint176 运算符对应。

要求:

  • 输入必须适合 176 位
toUint168(uint256 value) → uint168 internal

从 uint256 返回向下转换的 uint168,在溢出时回退(当输入大于最大 uint168 时)。

与 Solidity 的 uint168 运算符对应。

要求:

  • 输入必须适合 168 位
toUint160(uint256 value) → uint160 internal

从 uint256 返回向下转换的 uint160,在溢出时回退(当输入大于最大 uint160 时)。

与 Solidity 的 uint160 运算符对应。

要求:

  • 输入必须适合 160 位
toUint152(uint256 value) → uint152 internal

从 uint256 返回向下转换的 uint152,在溢出时回退(当输入大于最大 uint152 时)。

与 Solidity 的 uint152 运算符对应。

要求:

  • 输入必须适合 152 位
toUint144(uint256 value) → uint144 internal

从 uint256 返回向下转换的 uint144,在溢出时回退(当输入大于最大 uint144 时)。

与 Solidity 的 uint144 运算符对应。

要求:

  • 输入必须适合 144 位
toUint136(uint256 value) → uint136 internal

从 uint256 返回向下转换的 uint136,在溢出时回退(当输入大于最大 uint136 时)。

与 Solidity 的 uint136 运算符对应。

要求:

  • 输入必须适合 136 位
toUint128(uint256 value) → uint128 internal

从 uint256 返回向下转换的 uint128,在溢出时回退(当输入大于最大 uint128 时)。

与 Solidity 的 uint128 运算符对应。

要求:

  • 输入必须适合 128 位
toUint120(uint256 value) → uint120 internal

从 uint256 返回向下转换的 uint120,在溢出时回退(当输入大于最大 uint120 时)。

与 Solidity 的 uint120 运算符对应。

要求:

  • 输入必须适合 120 位
toUint112(uint256 value) → uint112 internal

从 uint256 返回向下转换的 uint112,在溢出时回退(当输入大于最大 uint112 时)。

与 Solidity 的 uint112 运算符对应。

要求:

  • 输入必须适合 112 位
toUint104(uint256 value) → uint104 internal

从 uint256 返回向下转换的 uint104,在溢出时回退(当输入大于最大 uint104 时)。

与 Solidity 的 uint104 运算符对应。

要求:

  • 输入必须适合 104 位
toUint96(uint256 value) → uint96 internal

从 uint256 返回向下转换的 uint96,在溢出时回退(当输入大于最大 uint96 时)。

与 Solidity 的 uint96 运算符对应。

要求:

  • 输入必须适合 96 位
toUint88(uint256 value) → uint88 internal

从 uint256 返回向下转换的 uint88,在溢出时回退(当输入大于最大 uint88 时)。

与 Solidity 的 uint88 运算符对应。

要求:

  • 输入必须适合 88 位
toUint80(uint256 value) → uint80 internal

从 uint256 返回向下转换的 uint80,在溢出时回退(当输入大于最大 uint80 时)。

与 Solidity 的 uint80 运算符对应。

要求:

  • 输入必须适合 80 位
toUint72(uint256 value) → uint72 internal

从 uint256 返回向下转换的 uint72,在溢出时回退(当输入大于最大 uint72 时)。

与 Solidity 的 uint72 运算符对应。

要求:

  • 输入必须适合 72 位
toUint64(uint256 value) → uint64 internal

从 uint256 返回向下转换的 uint64,在溢出时回退(当输入大于最大 uint64 时)。

与 Solidity 的 uint64 运算符对应。

要求:

  • 输入必须适合 64 位
toUint56(uint256 value) → uint56 internal

从 uint256 返回向下转换的 uint56,在溢出时回退(当输入大于最大 uint56 时)。

与 Solidity 的 uint56 运算符对应。

要求:

  • 输入必须适合 56 位
toUint48(uint256 value) → uint48 internal

从 uint256 返回向下转换的 uint48,在溢出时回退(当输入大于最大 uint48 时)。

与 Solidity 的 uint48 运算符对应。

要求:

  • 输入必须适合 48 位
toUint40(uint256 value) → uint40 internal

从 uint256 返回向下转换的 uint40,在溢出时回退(当输入大于最大 uint40 时)。

与 Solidity 的 uint40 运算符对应。

要求:

  • 输入必须适合 40 位
toUint32(uint256 value) → uint32 internal

从 uint256 返回向下转换的 uint32,在溢出时回退(当输入大于最大 uint32 时)。

与 Solidity 的 uint32 运算符对应。

要求:

  • 输入必须适合 32 位
toUint24(uint256 value) → uint24 internal

从 uint256 返回向下转换的 uint24,在溢出时回退(当输入大于最大 uint24 时)。

与 Solidity 的 uint24 运算符对应。

要求:

  • 输入必须适合 24 位
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。
toInt248(int256 value) → int248 downcasted internal

从 int256 返回向下转换的 int248,在溢出时回退(当输入小于最小 int248 或大于最大 int248 时)。

与 Solidity 的 int248 运算符对应。

要求:

  • 输入必须适合 248 位
toInt240(int256 value) → int240 downcasted internal

从 int256 返回向下转换的 int240,在溢出时回退(当输入小于最小 int240 或大于最大 int240 时)。

与 Solidity 的 int240 运算符对应。

要求:

  • 输入必须适合 240 位
toInt232(int256 value) → int232 downcasted internal

从 int256 返回向下转换的 int232,在溢出时回退(当输入小于最小 int232 或大于最大 int232 时)。

与 Solidity 的 int232 运算符对应。

要求:

  • 输入必须适合 232 位
toInt224(int256 value) → int224 downcasted internal

从 int256 返回向下转换的 int224,在溢出时回退(当输入小于最小 int224 或大于最大 int224 时)。

与 Solidity 的 int224 运算符对应。

要求:

  • 输入必须适合 224 位
toInt216(int256 value) → int216 downcasted internal

从 int256 返回向下转换的 int216,在溢出时回退(当输入小于最小 int216 或大于最大 int216 时)。

与 Solidity 的 int216 运算符对应。

要求:

  • 输入必须适合 216 位
toInt208(int256 value) → int208 downcasted internal

从 int256 返回向下转换的 int208,在溢出时回退(当输入小于最小 int208 或大于最大 int208 时)。

与 Solidity 的 int208 运算符对应。

要求:

  • 输入必须适合 208 位
toInt200(int256 value) → int200 downcasted internal

从 int256 返回向下转换的 int200,在溢出时回退(当输入小于最小 int200 或大于最大 int200 时)。

与 Solidity 的 int200 运算符对应。

要求:

  • 输入必须适合 200 位
toInt192(int256 value) → int192 downcasted internal

从 int256 返回向下转换的 int192,在溢出时回退(当输入小于最小 int192 或大于最大 int192 时)。

与 Solidity 的 int192 运算符对应。

要求:

  • 输入必须适合 192 位
toInt184(int256 value) → int184 downcasted internal

从 int256 返回向下转换的 int184,在溢出时回退(当输入小于最小 int184 或大于最大 int184 时)。

与 Solidity 的 int184 运算符对应。

要求:

  • 输入必须适合 184 位
toInt176(int256 value) → int176 downcasted internal

从 int256 返回向下转换的 int176,在溢出时回退(当输入小于最小 int176 或大于最大 int176 时)。

与 Solidity 的 int176 运算符对应。

要求:

  • 输入必须适合 176 位
toInt168(int256 value) → int168 downcasted internal

从 int256 返回向下转换的 int168,在溢出时回退(当输入小于最小 int168 或大于最大 int168 时)。

与 Solidity 的 int168 运算符对应。

要求:

  • 输入必须适合 168 位
toInt160(int256 value) → int160 downcasted internal

从 int256 返回向下转换的 int160,在溢出时回退(当输入小于最小 int160 或大于最大 int160 时)。

与 Solidity 的 int160 运算符对应。

要求:

  • 输入必须适合 160 位
toInt152(int256 value) → int152 downcasted internal

从 int256 返回向下转换的 int152,在溢出时回退(当输入小于最小 int152 或大于最大 int152 时)。

与 Solidity 的 int152 运算符对应。

要求:

  • 输入必须适合 152 位
toInt144(int256 value) → int144 downcasted internal

从 int256 返回向下转换的 int144,在溢出时回退(当输入小于最小 int144 或大于最大 int144 时)。

与 Solidity 的 int144 运算符对应。

要求:

  • 输入必须适合 144 位
toInt136(int256 value) → int136 downcasted internal

从 int256 返回向下转换的 int136,在溢出时回退(当输入小于最小 int136 或大于最大 int136 时)。

与 Solidity 的 int136 运算符对应。

要求:

  • 输入必须适合 136 位
toInt128(int256 value) → int128 downcasted internal

从 int256 返回向下转换的 int128,在溢出时回退(当输入小于最小 int128 或大于最大 int128 时)。

与 Solidity 的 int128 运算符对应。

要求:

  • 输入必须适合 128 位
toInt120(int256 value) → int120 downcasted internal

从 int256 返回向下转换的 int120,在溢出时回退(当输入小于最小 int120 或大于最大 int120 时)。

与 Solidity 的 int120 运算符对应。

要求:

  • 输入必须适合 120 位
toInt112(int256 value) → int112 downcasted internal

从 int256 返回向下转换的 int112,在溢出时回退(当输入小于最小 int112 或大于最大 int112 时)。

与 Solidity 的 int112 运算符对应。

要求:

  • 输入必须适合 112 位
toInt104(int256 value) → int104 downcasted internal

从 int256 返回向下转换的 int104,在溢出时回退(当输入小于最小 int104 或大于最大 int104 时)。

与 Solidity 的 int104 运算符对应。

要求:

  • 输入必须适合 104 位
toInt96(int256 value) → int96 downcasted internal

从 int256 返回向下转换的 int96,在溢出时回退(当输入小于最小 int96 或大于最大 int96 时)。

与 Solidity 的 int96 运算符对应。

要求:

  • 输入必须适合 96 位
toInt88(int256 value) → int88 downcasted internal

从 int256 返回向下转换的 int88,在溢出时回退(当输入小于最小 int88 或大于最大 int88 时)。

与 Solidity 的 int88 运算符对应。

要求:

  • 输入必须适合 88 位
toInt80(int256 value) → int80 downcasted internal

从 int256 返回向下转换的 int80,在溢出时回退(当输入小于最小 int80 或大于最大 int80 时)。

与 Solidity 的 int80 运算符对应。

要求:

  • 输入必须适合 80 位
toInt72(int256 value) → int72 downcasted internal

从 int256 返回向下转换的 int72,在溢出时回退(当输入小于最小 int72 或大于最大 int72 时)。

与 Solidity 的 int72 运算符对应。

要求:

  • 输入必须适合 72 位
toInt64(int256 value) → int64 downcasted internal

从 int256 返回向下转换的 int64,在溢出时回退(当输入小于最小 int64 或大于最大 int64 时)。

与 Solidity 的 int64 运算符对应。

要求:

  • 输入必须适合 64 位
toInt56(int256 value) → int56 downcasted internal

从 int256 返回向下转换的 int56,在溢出时回退(当输入小于最小 int56 或大于最大 int56 时)。

与 Solidity 的 int56 运算符对应。

要求:

  • 输入必须适合 56 位
toInt48(int256 value) → int48 downcasted internal

从 int256 返回向下转换的 int48,在溢出时回退(当输入小于最小 int48 或大于最大 int48 时)。

与 Solidity 的 int48 运算符对应。

要求:

  • 输入必须适合 48 位
toInt40(int256 value) → int40 downcasted internal

从 int256 返回向下转换的 int40,在溢出时回退(当输入小于最小 int40 或大于最大 int40 时)。

与 Solidity 的 int40 运算符对应。

要求:

  • 输入必须适合 40 位
toInt32(int256 value) → int32 downcasted internal

从 int256 返回向下转换的 int32,在溢出时回退(当输入小于最小 int32 或大于最大 int32 时)。

与 Solidity 的 int32 运算符对应。

要求:

  • 输入必须适合 32 位
toInt24(int256 value) → int24 downcasted internal

从 int256 返回向下转换的 int24,在溢出时回退(当输入小于最小 int24 或大于最大 int24 时)。

与 Solidity 的 int24 运算符对应。

要求:

  • 输入必须适合 24 位
toInt16(int256 value) → int16 downcasted internal

从 int256 返回向下转换的 int16,在溢出时回退(当输入小于最小 int16 或大于最大 int16 时)。

与 Solidity 的 int16 运算符对应。

要求:

  • 输入必须适合 16 位
toInt8(int256 value) → int8 downcasted internal

从 int256 返回向下转换的 int8,在溢出时回退(当输入小于最小 int8 或大于最大 int8 时)。

与 Solidity 的 int8 运算符对应。

要求:

  • 输入必须适合 8 位
toInt256(uint256 value) → int256 internal

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

要求:

  • 输入必须小于或等于 maxInt256。
toUint(bool b) → uint256 u internal

将布尔值(false 或 true)转换为 uint256(0 或 1),无需跳转。

SafeCastOverflowedUintDowncast(uint8 bits, uint256 value) error

值不适合 bits 大小的 uint。

SafeCastOverflowedIntToUint(int256 value) error

int 值不适合 bits 大小的 uint。

SafeCastOverflowedIntDowncast(uint8 bits, int256 value) error

值不适合 bits 大小的 int。

SafeCastOverflowedUintToInt(uint256 value) error

uint 值不适合 bits 大小的 int。

Cryptography

加密技术

ECDSA

import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

椭圆曲线数字签名算法 (ECDSA) 操作。

这些函数可以用于验证消息是否由给定地址的私钥持有者签名。

函数

错误

tryRecover(bytes32 hash, bytes signature) → address recovered, enum ECDSA.RecoverError err, bytes32 errArg internal

返回使用 signature 签署哈希消息(hash)的地址或错误。这不会在不返回错误描述的情况下返回 address(0)。使用枚举(错误类型)和提供有关错误的附加信息的 bytes32 记录错误。

如果未返回错误,则该地址可用于验证目的。

ecrecover EVM 预编译允许可塑的(非唯一的)签名:此函数要求 s 值位于较低的半阶中,并且 v 值必须为 27 或 28,从而拒绝它们。

要使验证安全,hash 必须是哈希运算的结果:可以制作签名,从而为非哈希数据恢复为任意地址。确保安全的方法是接收原始消息的哈希(否则可能太长),然后对其调用 MessageHashUtils.toEthSignedMessageHash

签名生成的文档: - 使用 Web3.js - 使用 ethers

recover(bytes32 hash, bytes signature) → address internal

返回使用 signature 签署哈希消息(hash)的地址。然后,该地址可用于验证目的。

ecrecover EVM 预编译允许可塑的(非唯一的)签名:此函数要求 s 值位于较低的半阶中,并且 v 值必须为 27 或 28,从而拒绝它们。

要使验证安全,hash 必须是哈希运算的结果:可以制作签名,从而为非哈希数据恢复为任意地址。确保安全的方法是接收原始消息的哈希(否则可能太长),然后对其调用 MessageHashUtils.toEthSignedMessageHash
tryRecover(bytes32 hash, bytes32 r, bytes32 vs) → address recovered, enum ECDSA.RecoverError err, bytes32 errArg internal

ECDSA.tryRecover 的重载,用于分别接收 rvs 短签名字段。

请参阅 ERC-2098 短签名

recover(bytes32 hash, bytes32 r, bytes32 vs) → address internal

ECDSA.recover 的重载,用于分别接收 r 和 vs 短签名字段。

tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) → address recovered, enum ECDSA.RecoverError err, bytes32 errArg internal

ECDSA.tryRecover 的重载,用于分别接收 vrs 签名字段。

recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) → address internal

ECDSA.recover 的重载,用于分别接收 vrs 签名字段。

ECDSAInvalidSignature() error

签名派生出 address(0)

ECDSAInvalidSignatureLength(uint256 length) error

签名具有无效长度。

ECDSAInvalidSignatureS(bytes32 s) error

签名具有位于上半阶中的 S 值。

P256

import "@openzeppelin/contracts/utils/cryptography/P256.sol";

secp256r1 验证和恢复函数的实现。

secp256r1 曲线(也称为 P256)是 NIST 标准曲线,在现代设备和密码学标准中得到广泛支持。一些值得注意的例子包括 Apple 的安全 Enclave 和 Android 的密钥库,以及 FIDO2 等身份验证协议。

基于 itsobvioustech 的原始实现(GNU 通用公共许可证 v3.0)。 很大程度上受到 maxrobottdrerup 实现的启发。

自 v5.1 起可用。

函数

内部变量

verify(bytes32 h, bytes32 r, bytes32 s, bytes32 qx, bytes32 qy) → bool internal

使用 RIP-7212 预编译验证 secp256r1 签名,如果预编译不可用,则回退到 Solidity 实现。此版本应适用于所有链,但需要部署更多字节码。

verifyNative(bytes32 h, bytes32 r, bytes32 s, bytes32 qx, bytes32 qy) → bool internal
与 [verify](https://docs.openzeppelin.com/contracts/5.x/api/utils#P256-verify-bytes3
这个验证算法不能阻止可重放性。如果使用相同的摘要、公钥和(有效签名)多次调用它,它每次都会返回 true。考虑在消息中包含一个链上 nonce 或唯一标识符,以防止重放攻击。
此验证算法支持任何指数。NIST 建议使用 65537(或更高)。这是许多库使用的默认值,例如 OpenSSL。出于安全考虑,开发人员可能会选择拒绝使用低指数的公钥。

EIP712

import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";

EIP-712 是用于哈希和签名类型化结构化数据的标准。

EIP 中指定的编码方案需要一个域分隔符和类型化结构化数据的哈希值,该数据的 编码非常通用,因此在 Solidity 中实现是不可行的,因此这个合约 不实现编码本身。协议需要实现它们所需的类型特定的编码,以便 使用 abi.encodekeccak256 的组合来生成其类型化数据的哈希值。

此合约实现了 EIP-712 域分隔符(_domainSeparatorV4),它用作编码的一部分,以及编码的最后一步,以获得通过 ECDSA 签名的消息摘要 ( _hashTypedDataV4)。

域分隔符的实现旨在尽可能高效,同时仍能正确更新 链 ID,以防止在链的最终分叉上发生重放攻击。

此合约实现了称为“v4”的编码版本,如 JSON RPC 方法中实现的那样 eth_signTypedDataV4 in MetaMask
在此合约的可升级版本中,缓存值将对应于地址和实现合约的域分隔符。这将导致 _domainSeparatorV4 函数始终从不可变值重建分隔符,这比访问冷存储中的缓存版本更便宜。

函数

事件

IERC5267

constructor(string name, string version) 内部函数

初始化域分隔符和参数缓存。

nameversion 的含义在 EIP-712 中指定:

  • name:签名域的用户可读名称,即 DApp 或协议的名称。

  • version:签名域的当前主要版本。

这些参数只能通过 智能合约升级 来更改。
_domainSeparatorV4() → bytes32 内部函数

返回当前链的域分隔符。

_hashTypedDataV4(bytes32 structHash) → bytes32 内部函数

给定一个已经 哈希的结构体,这个 函数返回此域的完全编码的 EIP712 消息的哈希值。

此哈希可以与 ECDSA.recover 一起使用,以获得消息的签名者。例如:

bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
    keccak256("Mail(address to,string contents)"),
    mailTo,
    keccak256(bytes(mailContents))
)));
address signer = ECDSA.recover(digest, signature);
eip712Domain() → bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions public

返回描述此合约用于 EIP-712 签名的域分隔符的字段和值。

_EIP712Name() → string 内部函数

EIP712 域的名称参数。

默认情况下,此函数读取 _name,这是一个不可变的值。仅在必要时才从存储中读取(以防该值太大而无法放入 ShortString 中)。
_EIP712Version() → string 内部函数

EIP712 域的版本参数。

默认情况下,此函数读取 _version,这是一个不可变的值。仅在必要时才从存储中读取(以防该值太大而无法放入 ShortString 中)。

MessageHashUtils

import "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";

签名消息哈希实用程序,用于生成供 ECDSA 恢复或签名使用的摘要。

该库提供了用于生成符合 ERC-191EIP 712 规范的消息哈希的方法。

函数

toEthSignedMessageHash(bytes32 messageHash) → bytes32 digest 内部函数

返回带有版本 0x45personal_sign 消息)的 ERC-191 签名数据的 keccak256 摘要。

通过将 bytes32 messageHash 前缀为 "\x19Ethereum Signed Message:\n32" 并对结果进行哈希来计算摘要。它对应于使用 eth_sign JSON-RPC 方法签名时的哈希。

messageHash 参数旨在成为使用 keccak256 对原始消息进行哈希处理的结果,尽管可以安全地使用任何 bytes32 值,因为最终的摘要将被重新哈希处理。

请参阅 ECDSA.recover.

toEthSignedMessageHash(bytes message) → bytes32 内部函数

返回带有版本 0x45personal_sign 消息)的 ERC-191 签名数据的 keccak256 摘要。

通过将任意 message 前缀为 "\x19Ethereum Signed Message:\n" + len(message) 并对结果进行哈希来计算摘要。它对应于使用 eth_sign JSON-RPC 方法签名时的哈希。

请参阅 ECDSA.recover.

toDataWithIntendedValidatorHash(address validator, bytes data) → bytes32 内部函数

返回带有版本 0x00(带有预期验证器的数据)的 ERC-191 签名数据的 keccak256 摘要。

通过将任意 data 前缀为 "\x19\x00" 和预期的 validator 地址来计算摘要。然后对结果进行哈希。

请参阅 ECDSA.recover.

toDataWithIntendedValidatorHash(address validator, bytes32 messageHash) → bytes32 digest 内部函数

toDataWithIntendedValidatorHash 的变体,针对 data 是 bytes32 的情况进行了优化。

toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) → bytes32 digest 内部函数

返回 EIP-712 类型化数据(ERC-191 版本 0x01)的 keccak256 摘要。

摘要由 domainSeparatorstructHash 计算得出,方法是用 \x19\x01 对它们进行前缀并对结果进行哈希处理。它对应于作为 EIP-712 的一部分的 eth_signTypedData JSON-RPC 方法签名的哈希。

请参阅 ECDSA.recover.

SignatureChecker

import "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";

签名验证助手,可以用来代替 ECDSA.recover,以无缝支持来自外部拥有的帐户 (EOA) 的 ECDSA 签名以及来自智能合约钱包(如 Argent 和 Safe Wallet(以前称为 Gnosis Safe))的 ERC-1271 签名。

函数

isValidSignatureNow(address signer, bytes32 hash, bytes signature) → bool 内部函数

检查签名对于给定的签名者和数据哈希是否有效。如果签名者是智能合约,则 使用 ERC-1271 对该智能合约验证签名,否则使用 ECDSA.recover 进行验证。

与 ECDSA 签名不同,合约签名是可以撤销的,因此此函数的结果可能会随着时间推移而改变。它可能在区块 N 返回 true,而在区块 N+1 返回 false(或相反)。
isValidERC1271SignatureNow(address signer, bytes32 hash, bytes signature) → bool 内部函数

检查签名对于给定的签名者和数据哈希是否有效。使用 ERC-1271 针对签名者智能合约验证签名。

与 ECDSA 签名不同,合约签名是可以撤销的,因此此函数的结果可能会随着时间推移而改变。它可能在区块 N 返回 true,而在区块 N+1 返回 false(或相反)。

Hashes

import "@openzeppelin/contracts/utils/cryptography/Hashes.sol";

标准哈希函数库。

自 v5.1 起可用。

函数

commutativeKeccak256(bytes32 a, bytes32 b) → bytes32 内部函数

已排序的 bytes32 对的可交换 Keccak256 哈希。在处理默克尔证明时经常使用。

等效于我们的 JavaScript 库 中的 standardNodeHash
efficientKeccak256(bytes32 a, bytes32 b) → bytes32 value 内部函数

keccak256(abi.encode(a, b)) 的实现,不分配或扩展内存。

MerkleProof

import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

这些函数处理默克尔树证明的验证。

树和证明可以使用我们的 JavaScript 库 生成。 你将在自述文件中找到快速入门指南。

在哈希之前,你应避免使用长度为 64 字节的叶子值,或者使用 keccak256 以外的哈希函数来哈希叶子。这是因为默克尔树中排序的一对内部节点的串联可以重新解释为叶子值。OpenZeppelin 的 JavaScript 库生成的默克尔树在开箱即用时可以防止这种攻击。
使用以不安全的方式访问内存的自定义哈希函数时,请考虑内存副作用。
此库支持使用自定义可交换哈希函数(即 H(a, b) == H(b, a))构建的默克尔树的证明验证。证明在使用不可交换哈希函数构建的树中包含叶子需要此库不支持的其他逻辑。

函数

错误

verify(bytes32[] proof, bytes32 root, bytes32 leaf) → bool 内部函数

如果可以证明 leaf 是由 root 定义的默克尔树的一部分,则返回 true。为此,必须提供一个 proof,其中包含从树的叶子到根的分支上的同级哈希。假定每对叶子和每对预映像都已排序。

此版本使用默认哈希函数处理内存中的证明。

processProof(bytes32[] proof, bytes32 leaf) → bytes32 内部函数

返回通过使用 proofleaf 向上遍历默克尔树获得的重建哈希。当且仅当重建的哈希与树的根匹配时,proof 才有效。在处理证明时,假定叶子和预映像对已排序。

此版本使用默认哈希函数处理内存中的证明。

verify(bytes32[] proof, bytes32 root, bytes32 leaf, function (bytes32,bytes32) view returns (bytes32) hasher) → bool 内部函数

如果可以证明 leaf 是由 root 定义的默克尔树的一部分,则返回 true。为此,必须提供一个 proof,其中包含从树的叶子到根的分支上的同级哈希。假定每对叶子和每对预映像都已排序。

此版本使用自定义哈希函数处理内存中的证明。

processProof(bytes32[] proof, bytes32 leaf, function (bytes32,bytes32) view returns (bytes32) hasher) → bytes32 内部函数

返回通过使用 proofleaf 向上遍历默克尔树获得的重建哈希。当且仅当重建的哈希与树的根匹配时,proof 才有效。在处理证明时,假定叶子和预映像对已排序。

此版本使用自定义哈希函数处理内存中的证明。

verifyCalldata(bytes32[] proof, bytes32 root, bytes32 leaf) → bool 内部函数

如果可以证明 leaf 是由 root 定义的默克尔树的一部分,则返回 true。为此,必须提供一个 proof,其中包含从树的叶子到根的分支上的同级哈希。假定每对叶子和每对预映像都已排序。

此版本使用默认哈希函数处理 calldata 中的证明。

processProofCalldata(bytes32[] proof, bytes32 leaf) → bytes32 内部函数

返回通过使用 proofleaf 向上遍历默克尔树获得的重建哈希。当且仅当重建的哈希与树的根匹配时,proof 才有效。在处理证明时,假定叶子和预映像对已排序。

此版本使用默认哈希函数处理 calldata 中的证明。

verifyCalldata(bytes32[] proof, bytes32 root, bytes32 leaf, function (bytes32,bytes32) view returns (bytes32) hasher) → bool 内部函数

如果可以证明 leaf 是由 root 定义的默克尔树的一部分,则返回 true。为此,必须提供一个 proof,其中包含从树的叶子到根的分支上的同级哈希。假定每对叶子和每对预映像都已排序。

此版本使用自定义哈希函数处理 calldata 中的证明。

processProofCalldata(bytes32[] proof, bytes32 leaf, function (bytes32,bytes32) view returns (bytes32) hasher) → bytes32 内部函数

返回通过使用 proofleaf 向上遍历默克尔树获得的重建哈希。当且仅当重建的哈希与树的根匹配时,proof 才有效。在处理证明时,假定叶子和预映像对已排序。

此版本使用自定义哈希函数处理 calldata 中的证明。

multiProofVerify(bytes32[] proof, bool[] proofFlags, bytes32 root, bytes32[] leaves) → bool 内部函数

如果可以根据 processMultiProof 中描述的 proofproofFlags 同时证明 leaves 是由 root 定义的默克尔树的一部分,则返回 true。

此版本使用默认哈希函数处理内存中的多重证明。

并非所有默克尔树都允许使用多重证明。有关详细信息,请参阅 processMultiProof
考虑 root == proof[0] && leaves.length == 0 的情况,因为它将返回 trueleaves 必须独立验证。有关详细信息,请参阅 processMultiProof
processMultiProof(bytes32[] proof, bool[] proofFlags, bytes32[] leaves) → bytes32 merkleRoot 内部函数

返回从 leavesproof 中的同级节点重建的树的根。重建过程通过将叶子/内部节点与另一个叶子/内部节点或证明同级节点相结合来增量重建所有内部节点,具体取决于每个 proofFlags 项是 true 还是 false。

此版本使用默认哈希函数处理内存中的多重证明。

并非所有默克尔树都允许使用多重证明。要使用多重证明,足以确保:1) 树是完整的(但不一定是完美的),2) 要证明的叶子的顺序与它们在树中的顺序相反(即,从右向左看,从最深的一层开始,并在下一层继续)。
空集(即 proof.length == 1 && leaves.length == 0 的情况)被视为无操作,因此是有效的多重证明(即它返回 proof[0])。如果你没有在其他地方验证叶子,请考虑禁止这种情况。
multiProofVerify(bytes32[] proof, bool[] proofFlags, bytes32 root, bytes32[] leaves, function (bytes32,bytes32) view returns (bytes32) hasher) → bool 内部函数

如果可以根据 processMultiProof 中描述的 proofproofFlags 同时证明 leaves 是由 root 定义的默克尔树的一部分,则返回 true。

此版本使用自定义哈希函数处理内存中的多重证明。

并非所有默克尔树都允许使用多重证明。有关详细信息,请参阅 processMultiProof
考虑 root == proof[0] && leaves.length == 0 的情况,因为它将返回 trueleaves 必须独立验证。有关详细信息,请参阅 processMultiProof
processMultiProof(bytes32[] proof, bool[] proofFlags, bytes32[] leaves, function (bytes32,bytes32) view returns (bytes32) hasher) → bytes32 merkleRoot 内部函数

返回从 leavesproof 中的同级节点重建的树的根。重建过程通过将叶子/内部节点与另一个叶子/内部节点或证明同级节点相结合来增量重建所有内部节点,具体取决于每个 proofFlags 项是 true 还是 false。

此版本使用自定义哈希函数处理内存中的多重证明。

并非所有默克尔树都允许使用多重证明。要使用多重证明,足以确保:1) 树是完整的(但不一定是完美的),2) 要证明的叶子的顺序与它们在树中的顺序相反(即,从右向左看,从最深的一层开始,并在下一层继续)。
空集(即 proof.length == 1 && leaves.length == 0 的情况)被视为无操作,因此是有效的多重证明(即它返回 proof[0])。如果你没有在其他地方验证叶子,请考虑禁止这种情况。
multiProofVerifyCalldata(bytes32[] proof, bool[] proofFlags, bytes32 root, bytes32[] leaves) → bool 内部函数

如果可以根据 processMultiProof 中描述的 proofproofFlags 同时证明 leaves 是由 root 定义的默克尔树的一部分,则返回 true。

此版本使用默认哈希函数处理 calldata 中的多重证明。

并非所有默克尔树都允许使用多重证明。有关详细信息,请参阅 processMultiProof
考虑 root == proof[0] && leaves.length == 0 的情况,因为它会返回 true。<br>leaves 必须被独立验证。 请参见 processMultiProofCalldata
processMultiProofCalldata(bytes32[] proof, bool[] proofFlags, bytes32[] leaves, function (bytes32,bytes32) view returns (bytes32) hasher) → bytes32 merkleRoot internal

返回由 leavesproof 中的兄弟节点重建的树的根。 重建过程通过递增地重建所有内部节点,将叶节点/内部节点与另一个叶节点/内部节点或证明兄弟节点组合,具体取决于每个 proofFlags 项是 true 还是 false。

此版本使用自定义哈希函数处理 calldata 中的 multiproofs。

并非所有的 Merkle 树都允许 multiproofs。 要使用 multiproofs,足以确保: 1) 树是完整的(但不一定是完美的),2) 要证明的叶子的顺序与它们在树中的顺序相反(即,从最深层开始从右到左看,然后在下一层继续)。
空集(即 proof.length == 1 && leaves.length == 0 的情况)被认为是无操作,因此是一个有效的 multiproof(即,它返回 proof[0])。 如果你未在其他地方验证叶子,请考虑禁止这种情况。
MerkleProofInvalidMultiproof() error

提供的 multiproof 无效。

安全

ReentrancyGuard

import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

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

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

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

如果你部署的链上可以使用 EIP-1153(瞬态存储),请考虑使用 ReentrancyGuardTransient 代替。
如果你想了解更多关于重入以及保护它其他方式,请查看我们的博客文章<br>伊斯坦布尔之后的重入

修饰符

函数

错误

nonReentrant() modifier

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

constructor() internal
_reentrancyGuardEntered() → bool internal

如果重入保护当前设置为“已进入”,则返回 true,这表明调用堆栈中存在一个 nonReentrant 函数。

ReentrancyGuardReentrantCall() error

未经授权的重入调用。

ReentrancyGuardTransient

import "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";

ReentrancyGuard 的变体,它使用瞬态存储。

此变体仅适用于 EIP-1153 可用的网络。

自 v5.1 起可用。

修饰符

函数

错误

nonReentrant() modifier

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

_reentrancyGuardEntered() → bool internal

如果重入保护当前设置为“已进入”,则返回 true,这表明调用堆栈中存在一个 nonReentrant 函数。

ReentrancyGuardReentrantCall() error

未经授权的重入调用。

Pausable

import "@openzeppelin/contracts/utils/Pausable.sol";

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

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

修饰符

函数

事件

错误

whenNotPaused() modifier

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

要求:

  • 合约不得暂停。
whenPaused() modifier

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

要求:

  • 合约必须暂停。
paused() → bool public

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

_requireNotPaused() internal

如果合约已暂停,则抛出错误。

_requirePaused() internal

如果合约未暂停,则抛出错误。

_pause() internal

触发停止状态。

要求:

  • 合约不得暂停。
_unpause() internal

返回正常状态。

要求:

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

当暂停由 account 触发时发出。

Unpaused(address account) event

当暂停由 account 解除时发出。

EnforcedPause() error

操作失败,因为合约已暂停。

ExpectedPause() error

操作失败,因为合约未暂停。

Nonces

import "@openzeppelin/contracts/utils/Nonces.sol";

为地址提供跟踪 nonceNonce 只会增加。

函数

错误

nonces(address owner) → uint256 public

返回地址的下一个未使用 nonce

_useNonce(address owner) → uint256 internal

消耗一个 nonce

返回当前值并递增 nonce

_useCheckedNonce(address owner, uint256 nonce) internal

_useNonce 相同,但检查 nonce 是否是 owner 的下一个有效 nonce

InvalidAccountNonce(address account, uint256 currentNonce) error

用于 accountnonce 不是预期的当前 nonce

NoncesKeyed

import "@openzeppelin/contracts/utils/NoncesKeyed.sol";

nonces 的替代方案,支持键控 nonce

遵循 ERC-4337 的半抽象 nonce 系统

此合约继承自 nonces 并重用其存储用于第一个 nonce 键(即 0)。 这使得从 nonces 升级到 NoncesKeyed 在使用其可升级版本(例如 NoncesKeyedUpgradeable)时是安全的。<br> 这样做不会重置 nonce 的当前状态,从而避免了在升级后重用 nonce 的重放攻击。

函数

Nonces

错误

Nonces

nonces(address owner, uint192 key) → uint256 public

返回地址和键的下一个未使用的 nonce。 结果包含键前缀。

_useNonce(address owner, uint192 key) → uint256 internal

消耗地址和键的下一个未使用的 nonce

返回不带键前缀的当前值。 消耗的 nonce 会增加,因此使用相同参数两次调用此函数将返回不同的(连续的)结果。

_useCheckedNonce(address owner, uint256 keyNonce) internal

_useNonce 相同,但检查 nonce 是否是 owner 的下一个有效 nonce

此版本在单个 uint256 参数中获取键和 nonce: - 使用前 24 个字节作为键 - 使用后 8 个字节作为 nonce

_useCheckedNonce(address owner, uint192 key, uint64 nonce) internal

_useNonce 相同,但检查 nonce 是否是 owner 的下一个有效 nonce

此版本将键和 nonce 作为两个不同的参数。

内省

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

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

IERC165

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

ERC-165 标准的接口,如 ERC 中定义的那样。

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

有关实现,请参见 ERC165

函数

supportsInterface(bytes4 interfaceId) → bool external

如果此合约实现了由 interfaceId 定义的接口,则返回 true。 请参阅相应的 ERC 部分 以了解有关如何创建这些 ID 的更多信息。

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

ERC165

import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

IERC165 接口的实现。

想要实现 ERC-165 的合约应从此合约继承并覆盖 supportsInterface 以检查将支持的其他接口 ID。 例如:

function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
    return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
}

函数

supportsInterface(bytes4 interfaceId) → bool public

参见 IERC165.supportsInterface

ERC165Checker

import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";

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

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

函数

supportsERC165(address account) → bool internal

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

supportsInterface(address account, bytes4 interfaceId) → bool internal

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

参见 IERC165.supportsInterface

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

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

参见 IERC165.supportsInterface

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

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

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

参见 IERC165.supportsInterface

supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) → bool internal

假设帐户包含支持 ERC-165 的合约,否则此方法的行为未定义。 可以使用 supportsERC165 检查此前提条件。

某些预编译合约会错误地指示支持给定的接口,因此在使用此函数时应谨慎。

接口识别在 ERC-165 中指定。

数据结构

BitMaps

import "@openzeppelin/contracts/utils/structs/BitMaps.sol";

用于以紧凑和高效的方式管理 uint256 到 bool 的映射的库,前提是键是顺序的。 主要受到 Uniswap 的 merkle-distributor 的启发。

BitMaps 在 uint256 类型的单个 256 位槽的每个位上打包 256 个布尔值。 因此,对应于 256 个顺序索引的布尔值只会消耗一个槽,这与常规 bool 不同,后者将为单个值消耗整个槽。

这通过两种方式节省了 gas:

  • 仅每 256 次将零值设置为非零值一次

  • 访问每 256 个顺序索引的同一热槽

函数

get(struct BitMaps.BitMap bitmap, uint256 index) → bool internal

返回是否设置了 index 处的位。

setTo(struct BitMaps.BitMap bitmap, uint256 index, bool value) internal

index 处的位设置为布尔值 value

set(struct BitMaps.BitMap bitmap, uint256 index) internal

设置 index 处的位。

unset(struct BitMaps.BitMap bitmap, uint256 index) internal

取消设置 index 处的位。

EnumerableMap

import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";

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

映射具有以下属性:

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

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

  • 映射可以在 O(n) 中清除(删除所有条目)。

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

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

支持以下映射类型:

  • uint256 → address ( UintToAddressMap) 自 v3.0.0 起

  • address → uint256 ( AddressToUintMap) 自 v4.6.0 起

  • bytes32 → bytes32 ( Bytes32ToBytes32Map) 自 v4.6.0 起

  • uint256 → uint256 ( UintToUintMap) 自 v4.7.0 起

  • bytes32 → uint256 ( Bytes32ToUintMap) 自 v4.7.0 起

  • uint256 → bytes32 ( UintToBytes32Map) 自 v5.1.0 起

  • address → address ( AddressToAddressMap) 自 v5.1.0 起

  • address → bytes32 ( AddressToBytes32Map) 自 v5.1.0 起

  • bytes32 → address ( Bytes32ToAddressMap) 自 v5.1.0 起

尝试从存储中删除此类结构可能会导致数据损坏,从而使该结构无法使用。<br> 有关详细信息,请参见 ethereum/solidity#11843。<br> 为了清理 EnumerableMap,你可以逐个删除所有元素,也可以使用 EnumerableMap 数组创建一个新实例。

函数

错误

set(struct EnumerableMap.Bytes32ToBytes32Map map, bytes32 key, bytes32 value) → bool internal

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

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

remove(struct EnumerableMap.Bytes32ToBytes32Map map, bytes32 key) → bool internal

从 map 中删除键值对。O(1)。

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

clear(struct EnumerableMap.Bytes32ToBytes32Map map) internal

从 map 中删除所有条目。O(n)。

开发人员应记住,此函数具有无界成本,如果 map 增长到清除 map 消耗太多 gas 以至于无法放入区块中,则使用它可能会导致该函数无法调用。
contains(struct EnumerableMap.Bytes32ToBytes32Map map, bytes32 key) → bool internal

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

length(struct EnumerableMap.Bytes32ToBytes32Map map) → uint256 internal

返回 map 中键值对的数量。O(1)。

at(struct EnumerableMap.Bytes32ToBytes32Map map, uint256 index) → bytes32 key, bytes32 value internal

返回存储在 map 中位置 index 处的键值对。O(1)。

请注意,不能保证数组中条目的顺序,当添加或删除更多条目时,条目的顺序可能会发生变化。

要求:

  • index 必须严格小于 length
tryGet(struct EnumerableMap.Bytes32ToBytes32Map map, bytes32 key) → bool exists, bytes32 value internal

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

get(struct EnumerableMap.Bytes32ToBytes32Map map, bytes32 key) → bytes32 internal

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

要求:

  • key 必须在 map 中。
keys(struct EnumerableMap.Bytes32ToBytes32Map map) → bytes32[] internal

返回包含所有键的数组

此操作会将整个存储复制到内存中,这可能会非常昂贵。这主要供在没有任何 gas 费用的情况下查询的视图访问器使用。开发人员应记住,此函数具有无界成本,如果 map 增长到复制到内存消耗太多 gas 以至于无法放入区块中,则将其用作状态更改函数的一部分可能会导致该函数无法调用。
set(struct EnumerableMap.UintToUintMap map, uint256 key, uint256 value) → bool internal

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

如果键已添加到 map 中,即如果它不是已经存在,则返回 true。

remove(struct EnumerableMap.UintToUintMap map, uint256 key) → bool internal

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

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

clear(struct EnumerableMap.UintToUintMap map) internal

从 map 中删除所有条目。O(n)。

开发人员应记住,此函数具有无界成本,如果 map 增长到清除 map 消耗太多 gas 以至于无法放入区块中,则使用它可能会导致该函数无法调用。
contains(struct EnumerableMap.UintToUintMap map, uint256 key) → bool internal

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

length(struct EnumerableMap.UintToUintMap map) → uint256 internal

返回 map 中的元素数量。O(1)。

at(struct EnumerableMap.UintToUintMap map, uint256 index) → uint256 key, uint256 value internal

返回存储在 map 中 index 位置的元素。O(1)。 请注意,不能保证数组中值的顺序,当添加或删除更多值时,值的顺序可能会发生变化。

要求:

  • index 必须严格小于length
tryGet(struct EnumerableMap.UintToUintMap map, uint256 key) → bool exists, uint256 value internal

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

get(struct EnumerableMap.UintToUintMap map, uint256 key) → uint256 internal

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

要求:

  • key 必须在 map 中。
keys(struct EnumerableMap.UintToUintMap map) → uint256[] internal

返回包含所有键的数组

此操作会将整个存储复制到内存中,这可能会非常昂贵。这主要供在没有任何 gas 费用的情况下查询的视图访问器使用。开发人员应记住,此函数具有无界成本,如果 map 增长到复制到内存消耗太多 gas 以至于无法放入区块中,则将其用作状态更改函数的一部分可能会导致该函数无法调用。
set(struct EnumerableMap.UintToAddressMap map, uint256 key, address value) → bool internal

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

如果键已添加到 map 中,即如果它不是已经存在,则返回 true。

remove(struct EnumerableMap.UintToAddressMap map, uint256 key) → bool internal

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

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

clear(struct EnumerableMap.UintToAddressMap map) internal

从 map 中删除所有条目。O(n)。

开发人员应记住,此函数具有无界成本,如果 map 增长到清除 map 消耗太多 gas 以至于无法放入区块中,则使用它可能会导致该函数无法调用。
contains(struct EnumerableMap.UintToAddressMap map, uint256 key) → bool internal

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

length(struct EnumerableMap.UintToAddressMap map) → uint256 internal

返回 map 中的元素数量。O(1)。

at(struct EnumerableMap.UintToAddressMap map, uint256 index) → uint256 key, address value internal

返回存储在 map 中 index 位置的元素。O(1)。 请注意,不能保证数组中值的顺序,当添加或删除更多值时,值的顺序可能会发生变化。

要求:

  • index 必须严格小于length
tryGet(struct EnumerableMap.UintToAddressMap map, uint256 key) → bool exists, address value internal

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

get(struct EnumerableMap.UintToAddressMap map, uint256 key) → address internal

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

要求:

  • key 必须在 map 中。
keys(struct EnumerableMap.UintToAddressMap map) → uint256[] internal

返回包含所有键的数组

此操作会将整个存储复制到内存中,这可能会非常昂贵。这主要供在没有任何 gas 费用的情况下查询的视图访问器使用。开发人员应记住,此函数具有无界成本,如果 map 增长到复制到内存消耗太多 gas 以至于无法放入区块中,则将其用作状态更改函数的一部分可能会导致该函数无法调用。
set(struct EnumerableMap.UintToBytes32Map map, uint256 key, bytes32 value) → bool internal

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

如果键已添加到 map 中,即如果它不是已经存在,则返回 true。

remove(struct EnumerableMap.UintToBytes32Map map, uint256 key) → bool internal

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

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

clear(struct EnumerableMap.UintToBytes32Map map) internal

从 map 中删除所有条目。O(n)。

开发人员应记住,此函数具有无界成本,如果 map 增长到清除 map 消耗太多 gas 以至于无法放入区块中,则使用它可能会导致该函数无法调用。
contains(struct EnumerableMap.UintToBytes32Map map, uint256 key) → bool internal

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

length(struct EnumerableMap.UintToBytes32Map map) → uint256 internal

返回 map 中的元素数量。O(1)。

at(struct EnumerableMap.UintToBytes32Map map, uint256 index) → uint256 key, bytes32 value internal

返回存储在 map 中 index 位置的元素。O(1)。 请注意,不能保证数组中值的顺序,当添加或删除更多值时,值的顺序可能会发生变化。

要求:

  • index 必须严格小于length
tryGet(struct EnumerableMap.UintToBytes32Map map, uint256 key) → bool exists, bytes32 value internal

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

get(struct EnumerableMap.UintToBytes32Map map, uint256 key) → bytes32 internal

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

要求:

  • key 必须在 map 中。
keys(struct EnumerableMap.UintToBytes32Map map) → uint256[] internal

返回包含所有键的数组

此操作会将整个存储复制到内存中,这可能会非常昂贵。这主要供在没有任何 gas 费用的情况下查询的视图访问器使用。开发人员应记住,此函数具有无界成本,如果 map 增长到复制到内存消耗太多 gas 以至于无法放入区块中,则将其用作状态更改函数的一部分可能会导致该函数无法调用。
set(struct EnumerableMap.AddressToUintMap map, address key, uint256 value) → bool internal

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

如果键已添加到 map 中,即如果它不是已经存在,则返回 true。

remove(struct EnumerableMap.AddressToUintMap map, address key) → bool internal

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

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

clear(struct EnumerableMap.AddressToUintMap map) internal

从 map 中删除所有条目。O(n)。

开发人员应记住,此函数具有无界成本,如果 map 增长到清除 map 消耗太多 gas 以至于无法放入区块中,则使用它可能会导致该函数无法调用。
contains(struct EnumerableMap.AddressToUintMap map, address key) → bool internal

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

length(struct EnumerableMap.AddressToUintMap map) → uint256 internal

返回 map 中的元素数量。O(1)。

at(struct EnumerableMap.AddressToUintMap map, uint256 index) → address key, uint256 value internal

返回存储在 map 中 index 位置的元素。O(1)。 请注意,不能保证数组中值的顺序,当添加或删除更多值时,值的顺序可能会发生变化。

要求:

  • index 必须严格小于length
tryGet(struct EnumerableMap.AddressToUintMap map, address key) → bool exists, uint256 value internal

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

get(struct EnumerableMap.AddressToUintMap map, address key) → uint256 internal

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

要求:

  • key 必须在 map 中。
keys(struct EnumerableMap.AddressToUintMap map) → address[] internal

返回包含所有键的数组

此操作会将整个存储复制到内存中,这可能会非常昂贵。这主要供在没有任何 gas 费用的情况下查询的视图访问器使用。开发人员应记住,此函数具有无界成本,如果 map 增长到复制到内存消耗太多 gas 以至于无法放入区块中,则将其用作状态更改函数的一部分可能会导致该函数无法调用。
set(struct EnumerableMap.AddressToAddressMap map, address key, address value) → bool internal

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

如果键已添加到 map 中,即如果它不是已经存在,则返回 true。

remove(struct EnumerableMap.AddressToAddressMap map, address key) → bool internal

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

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

clear(struct EnumerableMap.AddressToAddressMap map) internal

从 map 中删除所有条目。O(n)。

开发人员应记住,此函数具有无界成本,如果 map 增长到清除 map 消耗太多 gas 以至于无法放入区块中,则使用它可能会导致该函数无法调用。
contains(struct EnumerableMap.AddressToAddressMap map, address key) → bool internal

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

length(struct EnumerableMap.AddressToAddressMap map) → uint256 internal

返回 map 中的元素数量。O(1)。

at(struct EnumerableMap.AddressToAddressMap map, uint256 index) → address key, address value internal

返回存储在 map 中 index 位置的元素。O(1)。 请注意,不能保证数组中值的顺序,当添加或删除更多值时,值的顺序可能会发生变化。

要求:

  • index 必须严格小于length
tryGet(struct EnumerableMap.AddressToAddressMap map, address key) → bool exists, address value internal

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

get(struct EnumerableMap.AddressToAddressMap map, address key) → address internal

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

要求:

  • key 必须在 map 中。
keys(struct EnumerableMap.AddressToAddressMap map) → address[] internal

返回包含所有键的数组

此操作会将整个存储复制到内存中,这可能会非常昂贵。这主要供在没有任何 gas 费用的情况下查询的视图访问器使用。开发人员应记住,此函数具有无界成本,如果 map 增长到复制到内存消耗太多 gas 以至于无法放入区块中,则将其用作状态更改函数的一部分可能会导致该函数无法调用。
set(struct EnumerableMap.AddressToBytes32Map map, address key, bytes32 value) → bool internal

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

如果键已添加到 map 中,即如果它不是已经存在,则返回 true。

remove(struct EnumerableMap.AddressToBytes32Map map, address key) → bool internal

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

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

clear(struct EnumerableMap.AddressToBytes32Map map) internal

从 map 中删除所有条目。O(n)。

开发人员应记住,此函数具有无界成本,如果 map 增长到清除 map 消耗太多 gas 以至于无法放入区块中,则使用它可能会导致该函数无法调用。
contains(struct EnumerableMap.AddressToBytes32Map map, address key) → bool internal

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

length(struct EnumerableMap.AddressToBytes32Map map) → uint256 internal

返回 map 中的元素数量。O(1)。

at(struct EnumerableMap.AddressToBytes32Map map, uint256 index) → address key, bytes32 value internal

返回存储在 map 中 index 位置的元素。O(1)。 请注意,不能保证数组中值的顺序,当添加或删除更多值时,值的顺序可能会发生变化。

要求:

  • index 必须严格小于length
tryGet(struct EnumerableMap.AddressToBytes32Map map, address key) → bool exists, bytes32 value internal

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

get(struct EnumerableMap.AddressToBytes32Map map, address key) → bytes32 internal

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

要求:

  • key 必须在 map 中。
keys(struct EnumerableMap.AddressToBytes32Map map) → address[] internal

返回包含所有键的数组

此操作会将整个存储复制到内存中,这可能会非常昂贵。这主要供在没有任何 gas 费用的情况下查询的视图访问器使用。开发人员应记住,此函数具有无界成本,如果 map 增长到复制到内存消耗太多 gas 以至于无法放入区块中,则将其用作状态更改函数的一部分可能会导致该函数无法调用。
set(struct EnumerableMap.Bytes32ToUintMap map, bytes32 key, uint256 value) → bool internal

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

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

remove(struct EnumerableMap.Bytes32ToUintMap map, bytes32 key) → bool internal

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

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

clear(struct EnumerableMap.Bytes32ToUintMap map) internal

从 map 中删除所有条目。O(n)。

开发人员应记住,此函数具有无界成本,如果 map 增长到清除 map 消耗太多 gas 以至于无法放入区块中,则使用它可能会导致该函数无法调用。
contains(struct EnumerableMap.Bytes32ToUintMap map, bytes32 key) → bool internal

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

length(struct EnumerableMap.Bytes32ToUintMap map) → uint256 internal

返回 map 中的元素数量。O(1)。

at(struct EnumerableMap.Bytes32ToUintMap map, uint256 index) → bytes32 key, uint256 value internal

返回存储在 map 中位置 index 处的元素。O(1)。 请注意,不能保证数组中值的顺序,当添加或删除更多值时,值的顺序可能会发生变化。

要求:

  • index 必须严格小于 length
tryGet(struct EnumerableMap.Bytes32ToUintMap map, bytes32 key) → bool exists, uint256 value internal

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

get(struct EnumerableMap.Bytes32ToUintMap map, bytes32 key) → uint256 internal

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

要求:

  • key 必须在 map 中。
keys(struct EnumerableMap.Bytes32ToUintMap map) → bytes32[] internal

返回包含所有键的数组

此操作会将整个存储复制到内存中,这可能会非常昂贵。这主要供在没有任何 gas 费用的情况下查询的视图访问器使用。开发人员应记住,此函数具有无界成本,如果 map 增长到复制到内存消耗太多 gas 以至于无法放入区块中,则将其用作状态更改函数的一部分可能会导致该函数无法调用。
set(struct EnumerableMap.Bytes32ToAddressMap map, bytes32 key, address value) → bool internal

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

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

remove(struct EnumerableMap.Bytes32ToAddressMap map, bytes32 key) → bool internal

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

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

clear(struct EnumerableMap.Bytes32ToAddressMap map) internal

从 map 中删除所有条目。O(n)。

开发人员应记住,此函数具有无界成本,如果 map 增长到清除 map 消耗太多 gas 以至于无法放入区块中,则使用它可能会导致该函数无法调用。
contains(struct EnumerableMap.Bytes32ToAddressMap map, bytes32 key) → bool internal

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

length(struct EnumerableMap.Bytes32ToAddressMap map) → uint256 internal

返回 map 中的元素数量。O(1)。

at(struct EnumerableMap.Bytes32ToAddressMap map, uint256 index) → bytes32 key, address value internal

返回存储在 map 中位置 index 处的元素。O(1)。 请注意,不能保证数组中值的顺序,当添加或删除更多值时,值的顺序可能会发生变化。

要求:

  • index 必须严格小于 length
tryGet(struct EnumerableMap.Bytes32ToAddressMap map, bytes32 key) → bool exists, address value internal

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

get(struct EnumerableMap.Bytes32ToAddressMap map, bytes32 key) → address internal

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

要求:

  • key 必须在 map 中。
keys(struct EnumerableMap.Bytes32ToAddressMap map) → bytes32[] internal

返回包含所有键的数组

此操作会将整个存储复制到内存中,这可能会非常昂贵。这主要供在没有任何 gas 费用的情况下查询的视图访问器使用。开发人员应记住,此函数具有无界成本,如果 map 增长到复制到内存消耗太多 gas 以至于无法放入区块中,则将其用作状态更改函数的一部分可能会导致该函数无法调用。
EnumerableMapNonexistentKey(bytes32 key) error

查询不存在的 map 键。

EnumerableSet

import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

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

集合具有以下属性:

  • 在恒定时间 (O(1)) 内添加、删除元素并检查元素是否存在。

  • 在 O(n) 中枚举元素。不能保证排序。

  • 可以在 O(n) 中清除集合(删除所有元素)。

contract Example {
    // Add the library methods
    using EnumerableSet for EnumerableSet.AddressSet;

    // Declare a set state variable
    EnumerableSet.AddressSet private mySet;
}

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

尝试从存储中删除此类结构可能会导致数据损坏,从而使该结构无法使用。<br>有关更多信息,请参见 ethereum/solidity#11843。<br>为了清理 EnumerableSet,你可以逐个删除所有元素,也可以使用 EnumerableSet 数组创建一个新实例。

函数

add(struct EnumerableSet.Bytes32Set set, bytes32 value) → bool internal

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

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

remove(struct EnumerableSet.Bytes32Set set, bytes32 value) → bool internal
从集合中删除一个值。
此操作会将整个存储复制到内存中,这可能相当昂贵。这被设计成主要由没有任何 gas 费用的 view 访问器使用。开发者应该记住,此函数具有无限制的成本,如果集合增长到复制到内存消耗过多 gas 导致无法放入一个区块的地步,那么将其用作更改状态的函数的一部分可能会使该函数无法被调用。
add(struct EnumerableSet.AddressSet set, address value) → bool internal

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

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

remove(struct EnumerableSet.AddressSet set, address value) → bool internal

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

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

clear(struct EnumerableSet.AddressSet set) internal

从集合中移除所有值。O(n)。

开发者应该记住,此函数具有无限制的成本,如果集合增长到清除它消耗过多 gas 导致无法放入一个区块的地步,那么使用它可能会使该函数无法被调用。
contains(struct EnumerableSet.AddressSet set, address value) → bool internal

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

length(struct EnumerableSet.AddressSet set) → uint256 internal

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

at(struct EnumerableSet.AddressSet set, uint256 index) → address internal

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

请注意,不能保证数组中值的顺序,并且在添加或删除更多值时可能会发生变化。

要求:

  • index 必须严格小于 length
values(struct EnumerableSet.AddressSet set) → address[] internal

以数组形式返回整个集合

此操作会将整个存储复制到内存中,这可能相当昂贵。这被设计成主要由没有 gas 费用的 view 访问器使用。开发者应该记住,此函数具有无限制的成本,如果集合增长到复制到内存消耗过多 gas 导致无法放入一个区块的地步,那么将其用作更改状态的函数的一部分可能会使该函数无法被调用。
add(struct EnumerableSet.UintSet set, uint256 value) → bool internal

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

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

remove(struct EnumerableSet.UintSet set, uint256 value) → bool internal

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

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

clear(struct EnumerableSet.UintSet set) internal

从集合中移除所有值。O(n)。

开发者应该记住,此函数具有无限制的成本,如果集合增长到清除它消耗过多 gas 导致无法放入一个区块的地步,那么使用它可能会使该函数无法被调用。
contains(struct EnumerableSet.UintSet set, uint256 value) → bool internal

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

length(struct EnumerableSet.UintSet set) → uint256 internal

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

at(struct EnumerableSet.UintSet set, uint256 index) → uint256 internal

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

请注意,不能保证数组中值的顺序,并且在添加或删除更多值时可能会发生变化。

要求:

  • index 必须严格小于 length
values(struct EnumerableSet.UintSet set) → uint256[] internal

以数组形式返回整个集合

此操作会将整个存储复制到内存中,这可能相当昂贵。这被设计成主要由没有 gas 费用的 view 访问器使用。开发者应该记住,此函数具有无限制的成本,如果集合增长到复制到内存消耗过多 gas 导致无法放入一个区块的地步,那么将其用作更改状态的函数的一部分可能会使该函数无法被调用。

DoubleEndedQueue

import "@openzeppelin/contracts/utils/structs/DoubleEndedQueue.sol";

一个项目序列,能够在序列的两端(称为前端和后端)高效地推送和弹出项目(即插入和删除)。在其他访问模式中,它可以用于实现高效的 LIFO 和 FIFO 队列。存储使用进行了优化,并且所有操作都是 O(1) 常数时间。这包括 clear,因为现有的队列内容保留在存储中。

该结构体被称为 Bytes32Deque。其他类型可以转换为 bytes32 类型。此数据结构只能在存储中使用,不能在内存中使用。

DoubleEndedQueue.Bytes32Deque queue;

函数

pushBack(struct DoubleEndedQueue.Bytes32Deque deque, bytes32 value) internal

在队列末尾插入一个项目。

如果队列已满,则使用 Panic.RESOURCE_ERROR 恢复。

popBack(struct DoubleEndedQueue.Bytes32Deque deque) → bytes32 value internal

移除队列末尾的项目并返回它。

如果队列为空,则使用 Panic.EMPTY_ARRAY_POP 恢复。

pushFront(struct DoubleEndedQueue.Bytes32Deque deque, bytes32 value) internal

在队列开头插入一个项目。

如果队列已满,则使用 Panic.RESOURCE_ERROR 恢复。

popFront(struct DoubleEndedQueue.Bytes32Deque deque) → bytes32 value internal

移除队列开头的项目并返回它。

如果队列为空,则使用 Panic.EMPTY_ARRAY_POP 恢复。

front(struct DoubleEndedQueue.Bytes32Deque deque) → bytes32 value internal

返回队列开头的项目。

如果队列为空,则使用 Panic.ARRAY_OUT_OF_BOUNDS 恢复。

back(struct DoubleEndedQueue.Bytes32Deque deque) → bytes32 value internal

返回队列末尾的项目。

如果队列为空,则使用 Panic.ARRAY_OUT_OF_BOUNDS 恢复。

at(struct DoubleEndedQueue.Bytes32Deque deque, uint256 index) → bytes32 value internal

返回队列中位置为 index 的项目,第一个项目为 0,最后一个项目为 length(deque) - 1

如果索引超出范围,则使用 Panic.ARRAY_OUT_OF_BOUNDS 恢复。

clear(struct DoubleEndedQueue.Bytes32Deque deque) internal

将队列重置为空。

当前项目保留在存储中。这不会影响队列的功能,但会错过潜在的 gas 退款。
length(struct DoubleEndedQueue.Bytes32Deque deque) → uint256 internal

返回队列中的项目数。

empty(struct DoubleEndedQueue.Bytes32Deque deque) → bool internal

如果队列为空,则返回 true。

CircularBuffer

import "@openzeppelin/contracts/utils/structs/CircularBuffer.sol";

一个固定大小的缓冲区,用于在存储中保存 bytes32 项。

此数据结构允许将元素推送到其中,并且当其长度超过指定的固定大小时,新项将取代缓冲区中最旧的元素,从而在结构中最多保留 N 个元素。

元素无法删除,但可以清除数据结构。请参见 clear

复杂度: - 插入 ( push): O(1) - 查找 ( last): O(1) - 包含 ( includes): O(N)(最坏情况) - 重置 ( clear): O(1)

  • 该结构体被称为 Bytes32CircularBuffer。其他类型可以转换为 bytes32 类型。此数据结构只能在存储中使用,不能在内存中使用。

用法示例:

contract Example {
    // 添加库方法
    using CircularBuffer for CircularBuffer.Bytes32CircularBuffer;

    // 声明一个缓冲区存储变量
    CircularBuffer.Bytes32CircularBuffer private myBuffer;
}

自 v5.1 起可用。

函数

错误

setup(struct CircularBuffer.Bytes32CircularBuffer self, uint256 size) internal

初始化指定大小的新 CircularBuffer。

如果 CircularBuffer 已经设置和使用过,再次调用该函数会将其重置为空白状态。

缓冲区的大小会影响 includes 函数的执行,因为它具有 O(N) 的复杂度。<br>考虑到较大的缓冲区大小可能会使该函数无法使用。
clear(struct CircularBuffer.Bytes32CircularBuffer self) internal

清除缓冲区中的所有数据而不重置内存,保留现有大小。

push(struct CircularBuffer.Bytes32CircularBuffer self, bytes32 value) internal

将新值推送到缓冲区。如果缓冲区已满,则新值将替换缓冲区中最旧的值。

count(struct CircularBuffer.Bytes32CircularBuffer self) → uint256 internal

缓冲区中当前值的数量。对于空缓冲区,此值为 0,并且不能超过缓冲区的大小。

length(struct CircularBuffer.Bytes32CircularBuffer self) → uint256 internal

缓冲区的长度。这是缓冲区中保留的最大元素数。

last(struct CircularBuffer.Bytes32CircularBuffer self, uint256 i) → bytes32 internal

从末尾开始,获取缓冲区中第 i 个值。

如果尝试访问尚未推送或已删除以为较新元素腾出空间的元素,则使用 Panic.ARRAY_OUT_OF_BOUNDS 恢复。

includes(struct CircularBuffer.Bytes32CircularBuffer self, bytes32 value) → bool internal

检查给定的值是否在缓冲区中。

InvalidBufferSize() error

尝试设置大小为 0 的缓冲区时发出的错误。

Checkpoints

import "@openzeppelin/contracts/utils/structs/Checkpoints.sol";

此库定义了 Trace* 结构体,用于检查不同时间点值的变化,并在以后按区块号查找过去的值。请参见 Votes 作为示例。

要创建检查点历史记录,请在你的合约中定义一个 Checkpoints.Trace* 类型的变量,并使用 push 函数为当前交易区块存储一个新的检查点。

函数

错误

push(struct Checkpoints.Trace224 self, uint32 key, uint224 value) → uint224 oldValue, uint224 newValue internal

将 ( key, value) 对推送到 Trace224 中,以便将其存储为检查点。

返回先前值和新值。

永远不要接受 key 作为用户输入,因为任意的 type(uint32).max 键设置将禁用该库。
lowerLookup(struct Checkpoints.Trace224 self, uint32 key) → uint224 internal

返回第一个(最旧的)检查点中键大于或等于搜索键的值,如果没有则返回零。

upperLookup(struct Checkpoints.Trace224 self, uint32 key) → uint224 internal

返回最后一个(最新的)检查点中键小于或等于搜索键的值,如果没有则返回零。

upperLookupRecent(struct Checkpoints.Trace224 self, uint32 key) → uint224 internal

返回最后一个(最新的)检查点中键小于或等于搜索键的值,如果没有则返回零。

这是 upperLookup 的一个变体,它经过优化以查找“最近”的检查点(具有高键的检查点)。
latest(struct Checkpoints.Trace224 self) → uint224 internal

返回最新检查点中的值,如果没有检查点,则返回零。

latestCheckpoint(struct Checkpoints.Trace224 self) → bool exists, uint32 _key, uint224 _value internal

返回结构中是否存在检查点(即,它是否为空),如果存在,则返回最新检查点中的键和值。

length(struct Checkpoints.Trace224 self) → uint256 internal

返回检查点的数量。

at(struct Checkpoints.Trace224 self, uint32 pos) → struct Checkpoints.Checkpoint224 internal

返回给定位置的检查点。

push(struct Checkpoints.Trace208 self, uint48 key, uint208 value) → uint208 oldValue, uint208 newValue internal

将 ( key, value) 对推送到 Trace208 中,以便将其存储为检查点。

返回先前值和新值。

永远不要接受 key 作为用户输入,因为任意的 type(uint48).max 键设置将禁用该库。
lowerLookup(struct Checkpoints.Trace208 self, uint48 key) → uint208 internal

返回第一个(最旧的)检查点中键大于或等于搜索键的值,如果没有则返回零。

upperLookup(struct Checkpoints.Trace208 self, uint48 key) → uint208 internal

返回最后一个(最新的)检查点中键小于或等于搜索键的值,如果没有则返回零。

upperLookupRecent(struct Checkpoints.Trace208 self, uint48 key) → uint208 internal

返回最后一个(最新的)检查点中键小于或等于搜索键的值,如果没有则返回零。

这是 upperLookup 的一个变体,它经过优化以查找“最近”的检查点(具有高键的检查点)。
latest(struct Checkpoints.Trace208 self) → uint208 internal

返回最新检查点中的值,如果没有检查点,则返回零。

latestCheckpoint(struct Checkpoints.Trace208 self) → bool exists, uint48 _key, uint208 _value internal

返回结构中是否存在检查点(即,它是否为空),如果存在,则返回最新检查点中的键和值。

length(struct Checkpoints.Trace208 self) → uint256 internal

返回检查点的数量。

at(struct Checkpoints.Trace208 self, uint32 pos) → struct Checkpoints.Checkpoint208 internal

返回给定位置的检查点。

push(struct Checkpoints.Trace160 self, uint96 key, uint160 value) → uint160 oldValue, uint160 newValue internal

将 ( key, value) 对推送到 Trace160 中,以便将其存储为检查点。

返回先前值和新值。

永远不要接受 key 作为用户输入,因为任意的 type(uint96).max 键设置将禁用该库。
lowerLookup(struct Checkpoints.Trace160 self, uint96 key) → uint160 internal

返回第一个(最旧的)检查点中键大于或等于搜索键的值,如果没有则返回零。

upperLookup(struct Checkpoints.Trace160 self, uint96 key) → uint160 internal

返回最后一个(最新的)检查点中键小于或等于搜索键的值,如果没有则返回零。

upperLookupRecent(struct Checkpoints.Trace160 self, uint96 key) → uint160 internal

返回最后一个(最新的)检查点中键小于或等于搜索键的值,如果没有则返回零。

这是 upperLookup 的一个变体,它经过优化以查找“最近”的检查点(具有高键的检查点)。
latest(struct Checkpoints.Trace160 self) → uint160 internal

返回最新检查点中的值,如果没有检查点,则返回零。

latestCheckpoint(struct Checkpoints.Trace160 self) → bool exists, uint96 _key, uint160 _value internal

返回结构中是否存在检查点(即,它是否为空),如果存在,则返回最新检查点中的键和值。

length(struct Checkpoints.Trace160 self) → uint256 internal

返回检查点的数量。

at(struct Checkpoints.Trace160 self, uint32 pos) → struct Checkpoints.Checkpoint160 internal

返回给定位置的检查点。

CheckpointUnorderedInsertion() error

尝试在过去的检查点上插入值。

Heap

import "@openzeppelin/contracts/utils/structs/Heap.sol";

用于管理二叉堆的库,该库可用作优先级队列

堆表示为一个值的树,其中第一个元素(索引 0)是根,索引 i 处的节点是索引 (i-1)/2 处的节点的子节点,是索引 2i+1 和 2i+2 处的节点的父节点。每个节点存储堆的一个元素。

结构按顺序排列,以便每个节点都大于其父节点。一个直接的结果是,最高优先级值是根处的值。可以在 heap.tree[0] 以恒定时间 (O(1)) 查找此值。

该结构旨在以相应的复杂度执行以下操作:

  • peek(获取最高优先级值):O(1)

  • insert(插入一个值):O(log(n))

  • pop(删除最高优先级值):O(log(n))

  • replace(将最高优先级值替换为新值):O(log(n))

  • length(获取元素数):O(1)

  • clear(删除所有元素):O(1)

该库允许使用自定义比较器函数。鉴于操纵内存可能导致意外行为,请考虑验证比较器是否直接操纵堆的状态,以及它是否遵循 Solidity 内存安全规则。

自 v5.1 起可用。

函数

peek(struct Heap.Uint256Heap self) → uint256 internal

查找堆的根元素。

pop(struct Heap.Uint256Heap self) → uint256 internal

使用默认比较器删除(并返回)堆的根元素。

对堆的所有插入和删除都应始终使用相同的比较器。在堆的生命周期内混合比较器将导致未定义的行为。
pop(struct Heap.Uint256Heap self, function (uint256,uint256) view returns (bool) comp) → uint256 internal

使用提供的比较器删除(并返回)堆的根元素。

对堆的所有插入和删除都应始终使用相同的比较器。在堆的生命周期内混合比较器将导致未定义的行为。
insert(struct Heap.Uint256Heap self, uint256 value) internal

使用默认比较器在堆中插入一个新元素。

对堆的所有插入和删除都应始终使用相同的比较器。在堆的生命周期内混合比较器将导致未定义的行为。
insert(struct Heap.Uint256Heap self, uint256 value, function (uint256,uint256) view returns (bool) comp) internal

使用提供的比较器在堆中插入一个新元素。

对堆的所有插入和删除都应始终使用相同的比较器。在堆的生命周期内混合比较器将导致未定义的行为。
replace(struct Heap.Uint256Heap self, uint256 newValue) → uint256 internal

返回堆的根元素,并使用默认比较器将其替换为新值。 这等效于使用 [pop](https://docs.openzeppelin.com/contracts/5.x/api/utils#Heap-pop-struct-Heap-Uint256Heap-function%E2%80%94%E2%80%8Buint256-uint256%E2%80%94- 深度: 树中的层数,它也定义了叶子的最大数量为 2**depth。

  • 零值: 代表空叶子的值。用于避免常规的零值成为树的一部分。

  • 哈希函数: 用于生成内部节点的密码学哈希函数。默认为 Hashes.commutativeKeccak256

支持使用非交换哈希函数 (即 H(a, b) != H(b, a)) 构建树。但是,<br>使用 MerkleProof 库无法证明<br>此类树中包含叶子,因为它仅支持加粗交换加粗哈希函数。

加粗自 v5.1 起可用。

函数

错误

setup(struct MerkleTree.Bytes32PushTree self, uint8 treeDepth, bytes32 zero) → bytes32 initialRoot internal

使用 Hashes.commutativeKeccak256 初始化一个 Bytes32PushTree 来哈希内部节点。 树的容量(即叶子的数量)设置为 2**treeDepth

在已经设置和使用过的 MerkleTree 上调用此函数将把它重置为空白状态。

一旦设置了一棵树,任何推送到它的操作都必须使用相同的哈希函数。这意味着应该使用默认的 push 函数将值推送到它。

零值应该仔细选择,因为它将被存储在代表<br>空叶子的树中。它应该是一个不希望成为树一部分的值。
setup(struct MerkleTree.Bytes32PushTree self, uint8 treeDepth, bytes32 zero, function (bytes32,bytes32) view returns (bytes32) fnHash) → bytes32 initialRoot internal

setup 相同,但允许指定自定义哈希函数。

一旦设置了一棵树,任何推送到它的操作都必须使用相同的哈希函数。这意味着应该使用自定义的 push 函数将值推送到它,该函数应该与设置期间使用的函数相同。

提供自定义哈希函数是一项对安全性敏感的操作,因为它可能<br>会损害树的可靠性。
考虑验证哈希函数是否不直接操作内存状态,并且它<br>遵循 Solidity 内存安全规则。否则,可能会导致意外行为。
push(struct MerkleTree.Bytes32PushTree self, bytes32 leaf) → uint256 index, bytes32 newRoot internal

在树中插入一个新的叶子,并计算新的根。返回插入的叶子在 树中的位置,以及结果根。

建议在调用此函数之前对叶子进行哈希,以防止 第二原像攻击。

此变体使用 Hashes.commutativeKeccak256 来哈希内部节点。它只应该在使用相同(默认)哈希函数的 Merkle 树上使用(例如, 通过调用 默认设置 函数)。

push(struct MerkleTree.Bytes32PushTree self, bytes32 leaf, function (bytes32,bytes32) view returns (bytes32) fnHash) → uint256 index, bytes32 newRoot internal

在树中插入一个新的叶子,并计算新的根。返回插入的叶子在 树中的位置,以及结果根。

建议在调用此函数之前对叶子进行哈希,以防止 第二原像攻击。

此变体使用自定义哈希函数来哈希内部节点。它应该只使用与 Merkle 树的初始设置期间使用的函数相同的 函数来调用。

update(struct MerkleTree.Bytes32PushTree self, uint256 index, bytes32 oldValue, bytes32 newValue, bytes32[] proof) → bytes32 oldRoot, bytes32 newRoot internal

将位置 index 处的叶子的值从 oldValue 更改为 newValue。返回重新计算的“旧”根 (在更新之前)和“新”根(在更新之后)。调用者必须验证重构的旧根是否为最后一个已知的根。

proof 必须是正在更新的叶子的最新包含证明。这意味着此函数 容易受到抢先交易攻击。任何 pushupdate 操作(更改树的根)将使 所有“正在进行中”的更新无效。

此变体使用 Hashes.commutativeKeccak256 来哈希内部节点。它只应该在使用相同(默认)哈希函数的 Merkle 树上使用(例如, 通过调用 默认设置 函数)。

update(struct MerkleTree.Bytes32PushTree self, uint256 index, bytes32 oldValue, bytes32 newValue, bytes32[] proof, function (bytes32,bytes32) view returns (bytes32) fnHash) → bytes32 oldRoot, bytes32 newRoot internal

将位置 index 处的叶子的值从 oldValue 更改为 newValue。返回重新计算的“旧”根 (在更新之前)和“新”根(在更新之后)。调用者必须验证重构的旧根是否为最后一个已知的根。

proof 必须是正在更新的叶子的最新包含证明。这意味着此函数 容易受到抢先交易攻击。任何 pushupdate 操作(更改树的根)将使 所有“正在进行中”的更新无效。

此变体使用自定义哈希函数来哈希内部节点。它应该只使用与 Merkle 树的初始设置期间使用的函数相同的 函数来调用。

depth(struct MerkleTree.Bytes32PushTree self) → uint256 internal

树的深度(在初始化时设置)

MerkleTreeUpdateInvalidIndex(uint256 index, uint256 length) error

尝试更新先前未推送的叶子时发出的错误。

MerkleTreeUpdateInvalidProof() error

当更新期间使用的证明无效(无法重现侧)时发出的错误。

Create2

import "@openzeppelin/contracts/utils/Create2.sol";

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

有关更多信息,请参见 EIP

函数

错误

deploy(uint256 amount, bytes32 salt, bytes bytecode) → address addr internal

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

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

要求:

  • bytecode 不得为空。

  • salt 必须尚未用于 bytecode

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

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

computeAddress(bytes32 salt, bytes32 bytecodeHash) → address internal

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

computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) → address addr internal

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

Create2EmptyBytecode() error

没有要部署的代码。

Address

import "@openzeppelin/contracts/utils/Address.sol";

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

函数

错误

sendValue(address payable recipient, uint256 amount) internal

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

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

了解更多

因为控制权转移到 recipient,必须注意<br>不要创建重入漏洞。考虑使用<br>ReentrancyGuard检查-效果-交互模式
functionCall(address target, bytes data) → bytes internal

使用低级 call 执行 Solidity 函数调用。 一个普通的 call 是一个不安全的函数调用替代品:请改用此 函数。

如果 target 以 revert 原因或自定义错误恢复,则此函数会将其弹出 (像常规的 Solidity 函数调用一样)。但是,如果 调用在没有返回原因的情况下恢复,则此函数会以 {Errors.FailedCall} 错误恢复。

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

要求:

  • target 必须是一个合约。

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

functionCallWithValue(address target, bytes data, uint256 value) → bytes internal

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

要求:

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

  • 调用的 Solidity 函数必须是 payable

functionStaticCall(address target, bytes data) → bytes internal

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

functionDelegateCall(address target, bytes data) → bytes internal

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

verifyCallResultFromTarget(address target, bool success, bytes returndata) → bytes internal

用于验证对智能合约的低级调用是否成功的工具,如果目标 不是合约,则恢复,或者弹出恢复原因(如果调用不成功,则回退到 {Errors.FailedCall})。

verifyCallResult(bool success, bytes returndata) → bytes internal

用于验证低级调用是否成功的工具,如果不是,则恢复,可以通过弹出 恢复原因或使用默认的 {Errors.FailedCall} 错误。

AddressEmptyCode(address target) error

target 处没有代码(它不是合约)。

Arrays

import "@openzeppelin/contracts/utils/Arrays.sol";

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

函数

sort(uint256[] array, function (uint256,uint256) pure returns (bool) comp) → uint256[] internal

按照提供的比较器函数对 uint256 数组(在内存中)进行排序。

此函数执行“就地”排序,这意味着它会覆盖输入。为了 方便起见,该对象被返回,但如果调用者具有指向该数组的内存指针,则可以安全地丢弃该返回值。

此函数的平均成本为 O(n · log(n)),最坏情况为 O(n²),其中 n 是数组的长度。<br>在通过 eth_call 执行的视图函数中使用它是安全的,但当作为事务的一部分执行时,应非常小心。<br>如果要排序的数组太大,则排序操作可能会消耗比一个块中可用的气体更多,从而导致潜在的 DoS。
使用以不安全方式访问内存的自定义比较器函数时,请考虑内存副作用。
sort(uint256[] array) → uint256[] internal

sort 的变体,用于按递增顺序对 uint256 数组进行排序。

sort(address[] array, function (address,address) pure returns (bool) comp) → address[] internal

按照提供的比较器函数对 address 数组(在内存中)进行排序。

此函数执行“就地”排序,这意味着它会覆盖输入。为了 方便起见,该对象被返回,但如果调用者具有指向该数组的内存指针,则可以安全地丢弃该返回值。

此函数的平均成本为 O(n · log(n)),最坏情况为 O(n²),其中 n 是数组的长度。<br>在通过 eth_call 执行的视图函数中使用它是安全的,但当作为事务的一部分执行时,应非常小心。<br>如果要排序的数组太大,则排序操作可能会消耗比一个块中可用的气体更多,从而导致潜在的 DoS。
使用以不安全方式访问内存的自定义比较器函数时,请考虑内存副作用。
sort(address[] array) → address[] internal

sort 的变体,用于按递增顺序对 address 数组进行排序。

sort(bytes32[] array, function (bytes32,bytes32) pure returns (bool) comp) → bytes32[] internal

按照提供的比较器函数对 bytes32 数组(在内存中)进行排序。

此函数执行“就地”排序,这意味着它会覆盖输入。为了 方便起见,该对象被返回,但如果调用者具有指向该数组的内存指针,则可以安全地丢弃该返回值。

此函数的平均成本为 O(n · log(n)),最坏情况为 O(n²),其中 n 是数组的长度。<br>在通过 eth_call 执行的视图函数中使用它是安全的,但当作为事务的一部分执行时,应非常小心。<br>如果要排序的数组太大,则排序操作可能会消耗比一个块中可用的气体更多,从而导致潜在的 DoS。
使用以不安全方式访问内存的自定义比较器函数时,请考虑内存副作用。
sort(bytes32[] array) → bytes32[] internal

sort 的变体,用于按递增顺序对 bytes32 数组进行排序。

findUpperBound(uint256[] array, uint256 element) → uint256 internal

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

预期 array 按升序排序,并且<br>不包含重复元素。
已弃用。此实现的行为与 lowerBound 相同,但缺少<br>对数组中重复元素的支持。应使用 lowerBound 函数。
lowerBound(uint256[] array, uint256 element) → uint256 internal

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

请参阅 C++ 的 lower_bound

upperBound(uint256[] array, uint256 element) → uint256 internal

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

请参阅 C++ 的 upper_bound

lowerBoundMemory(uint256[] array, uint256 element) → uint256 internal

lowerBound 相同,但数组在内存中。

upperBoundMemory(uint256[] array, uint256 element) → uint256 internal

upperBound 相同,但数组在内存中。

unsafeAccess(address[] arr, uint256 pos) → struct StorageSlot.AddressSlot internal

以“不安全”的方式访问数组。跳过 solidity“索引超出范围”检查。

仅当你确定 pos 低于数组长度时才使用。
unsafeAccess(bytes32[] arr, uint256 pos) → struct StorageSlot.Bytes32Slot internal

以“不安全”的方式访问数组。跳过 solidity“索引超出范围”检查。

仅当你确定 pos 低于数组长度时才使用。
unsafeAccess(uint256[] arr, uint256 pos) → struct StorageSlot.Uint256Slot internal

以“不安全”的方式访问数组。跳过 solidity“索引超出范围”检查。

仅当你确定 pos 低于数组长度时才使用。
unsafeMemoryAccess(address[] arr, uint256 pos) → address res internal

以“不安全”的方式访问数组。跳过 solidity“索引超出范围”检查。

仅当你确定 pos 低于数组长度时才使用。
unsafeMemoryAccess(bytes32[] arr, uint256 pos) → bytes32 res internal

以“不安全”的方式访问数组。跳过 solidity“索引超出范围”检查。

仅当你确定 pos 低于数组长度时才使用。
unsafeMemoryAccess(uint256[] arr, uint256 pos) → uint256 res internal

以“不安全”的方式访问数组。跳过 solidity“索引超出范围”检查。

仅当你确定 pos 低于数组长度时才使用。
unsafeSetLength(address[] array, uint256 len) internal

用于设置动态数组长度的帮助程序。禁止直接写入 .length

如果长度减小,则不会清除元素;如果长度增加,则不会初始化元素。
unsafeSetLength(bytes32[] array, uint256 len) internal

用于设置动态数组长度的帮助程序。禁止直接写入 .length

如果长度减小,则不会清除元素;如果长度增加,则不会初始化元素。
unsafeSetLength(uint256[] array, uint256 len) internal

用于设置动态数组长度的帮助程序。禁止直接写入 .length

如果长度减小,则不会清除元素;如果长度增加,则不会初始化元素
--- ---
复制了 Javascript 的 Array.indexOf 的行为
lastIndexOf(bytes buffer, bytes1 s) → uint256 internal

buffer 中向后搜索 s \ 如果 s 存在于 buffer 中,则返回最后一个实例的索引 \ 如果 s 不存在于 buffer 中,则返回 type(uint256).max

复制了 Javascript 的 Array.lastIndexOf 的行为
lastIndexOf(bytes buffer, bytes1 s, uint256 pos) → uint256 internal

从位置 pos 开始在 buffer 中向后搜索 s \ 如果 s 存在于 buffer 中(在 pos 处或之前),则返回上一个实例的索引 \ 如果 s 不存在于 buffer 中(在 pos 处或之前),则返回 type(uint256).max

复制了 Javascript 的 Array.lastIndexOf 的行为
slice(bytes buffer, uint256 start) → bytes internal

buffer 的内容从 start (包含) 到 buffer 的末尾复制到内存中的新 bytes 对象中。

复制了 Javascript 的 Array.slice 的行为
slice(bytes buffer, uint256 start, uint256 end) → bytes internal

buffer 的内容从 start (包含) 到 end (排除) 复制到内存中的新 bytes 对象中。

复制了 Javascript 的 Array.slice 的行为

Calldata

import "@openzeppelin/contracts/utils/Calldata.sol";

用于操作 calldata 中的对象的辅助库。

函数

emptyBytes() → bytes result internal
emptyString() → string result internal

Strings

import "@openzeppelin/contracts/utils/Strings.sol";

字符串操作。

函数

错误

toString(uint256 value) → string internal

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

toStringSigned(int256 value) → string internal

int256 转换为其 ASCII string 十进制表示形式。

toHexString(uint256 value) → string internal

uint256 转换为其 ASCII string 十六进制表示形式。

toHexString(uint256 value, uint256 length) → string internal

将具有固定长度的 uint256 转换为其 ASCII string 十六进制表示形式。

toHexString(address addr) → string internal

将具有 20 字节固定长度的 address 转换为未校验和的ASCII string 十六进制表示形式。

toChecksumHexString(address addr) → string internal

根据 EIP-55,将具有 20 字节固定长度的 address 转换为经过校验和的 ASCII string 十六进制表示形式。

equal(string a, string b) → bool internal

如果两个字符串相等,则返回 true。

parseUint(string input) → uint256 internal

解析十进制字符串并将该值作为 uint256 返回。

要求: - 字符串必须格式化为 [0-9]* - 结果必须适合 uint256 类型

parseUint(string input, uint256 begin, uint256 end) → uint256 internal

parseUint 的变体,它解析位于位置 begin (包含)和 end (排除)之间的 input 的子字符串。

要求: - 子字符串必须格式化为 [0-9]* - 结果必须适合 uint256 类型

tryParseUint(string input) → bool success, uint256 value internal

parseUint 的变体,如果由于无效字符导致解析失败,则返回 false。

如果结果不适合 uint256,此函数将还原。
tryParseUint(string input, uint256 begin, uint256 end) → bool success, uint256 value internal

parseUint 的变体,如果由于无效字符导致解析失败,则返回 false。

如果结果不适合 uint256,此函数将还原。
parseInt(string input) → int256 internal

解析十进制字符串并将该值作为 int256 返回。

要求: - 字符串必须格式化为 [-+]?[0-9]* - 结果必须适合 int256 类型。

parseInt(string input, uint256 begin, uint256 end) → int256 internal

parseInt 的变体,它解析位于位置 begin (包含)和end (排除)之间的 input 的子字符串。

要求: - 子字符串必须格式化为 [-+]?[0-9]* - 结果必须适合 int256 类型。

tryParseInt(string input) → bool success, int256 value internal

parseInt 的变体,如果由于无效字符或结果不适合 int256 而导致解析失败,则返回 false。

如果结果的绝对值不适合 uint256,此函数将还原。
tryParseInt(string input, uint256 begin, uint256 end) → bool success, int256 value internal

parseInt 的变体,如果由于无效字符或结果不适合 int256 而导致解析失败,则返回 false。

如果结果的绝对值不适合 uint256,此函数将还原。
parseHexUint(string input) → uint256 internal

解析十六进制字符串 (带有或不带有 "0x" 前缀),并将该值作为 uint256 返回。

要求: - 字符串必须格式化为 (0x)?[0-9a-fA-F]* - 结果必须适合 uint256 类型。

parseHexUint(string input, uint256 begin, uint256 end) → uint256 internal

parseHexUint 的变体,它解析位于位置 begin(包含)和 end(排除)之间的 input 的子字符串。

要求: - 子字符串必须格式化为 (0x)?[0-9a-fA-F]* - 结果必须适合 uint256 类型。

tryParseHexUint(string input) → bool success, uint256 value internal

parseHexUint 的变体,如果由于无效字符导致解析失败,则返回 false。

如果结果不适合 uint256,此函数将还原。
tryParseHexUint(string input, uint256 begin, uint256 end) → bool success, uint256 value internal

parseHexUint 的变体,如果由于无效字符导致解析失败,则返回 false。

如果结果不适合 uint256,此函数将还原。
parseAddress(string input) → address internal

解析十六进制字符串 (带有或不带有 "0x" 前缀),并将该值作为 address 返回。

要求: - 字符串必须格式化为 (0x)?[0-9a-fA-F]{40}

parseAddress(string input, uint256 begin, uint256 end) → address internal

parseAddress 的变体,它解析位于位置 begin (包含) 和 end (排除) 之间的 input 的子字符串。

要求: - 子字符串必须格式化为 (0x)?[0-9a-fA-F]{40}

tryParseAddress(string input) → bool success, address value internal

parseAddress 的变体,如果由于输入格式不正确的地址而导致解析失败,则返回 false。 请参阅 parseAddress 要求。

tryParseAddress(string input, uint256 begin, uint256 end) → bool success, address value internal

parseAddress 的变体,如果由于输入格式不正确的地址而导致解析失败,则返回 false。 请参阅 parseAddress 要求。

escapeJSON(string input) → string internal

转义 JSON 字符串中的特殊字符。 这对于防止 NFT 元数据中的 JSON 注入很有用。

此函数应仅在双引号 JSON 字符串中使用。 单引号不会被转义。
此函数会转义所有 unicode 字符,而不仅仅是 RFC-4627(U+0000 到 U+001F、U+0022 和 U+005C)的第 2.5 节中定义的范围内的字符。<br>ECMAScript 的 JSON.parse 确实会恢复此范围内不存在的转义 unicode 字符,但其他工具可能会提供不同的结果。
StringsInsufficientHexLength(uint256 value, uint256 length) error

value 字符串不适合指定的 length

StringsInvalidChar() error

正在解析的字符串包含给定 base 范围之外的字符。

StringsInvalidAddressFormat() error

正在解析的字符串不是格式正确的地址。

ShortStrings

import "@openzeppelin/contracts/utils/ShortStrings.sol";

该库提供了将短内存字符串转换为 ShortString 类型的函数,该类型可以用作不可变变量。

如果任意长度的字符串足够短(最多 31 字节),则可以通过将其长度(1 字节)打包到单个 EVM 字(32 字节)中,使用此库对其进行优化。 此外,对于每个其他情况,都可以使用回退机制。

使用示例:

contract Named {
    using ShortStrings for *;

    ShortString private immutable _name;
    string private _nameFallback;

    constructor(string memory contractName) {
        _name = contractName.toShortStringWithFallback(_nameFallback);
    }

    function name() external view returns (string memory) {
        return _name.toStringWithFallback(_nameFallback);
    }
}

函数

错误

toShortString(string str) → ShortString internal

将最多 31 个字符的字符串编码为 ShortString

如果输入字符串太长,这将触发 StringTooLong 错误。

toString(ShortString sstr) → string internal

ShortString 解码回“normal”字符串。

byteLength(ShortString sstr) → uint256 internal

返回 ShortString 的长度。

toShortStringWithFallback(string value, string store) → ShortString internal

将字符串编码为 ShortString,或者如果字符串太长,则将其写入存储。

toStringWithFallback(ShortString value, string store) → string internal

解码使用 toShortStringWithFallback 编码为 ShortString 或写入存储的字符串。

byteLengthWithFallback(ShortString value, string store) → uint256 internal

返回使用 toShortStringWithFallback 编码为 ShortString 或写入存储的字符串的长度。

这将返回字符串的“字节长度”。 这可能无法反映实际字符方面的实际长度,因为单个字符的 UTF-8 编码可能会跨越多个字节。
StringTooLong(string str) error
InvalidShortString() error

SlotDerivation

import "@openzeppelin/contracts/utils/SlotDerivation.sol";

用于从命名空间计算存储(和瞬态存储)位置并派生与标准模式对应的槽的库。 用于数组和映射的推导方法与 solidity 语言/编译器使用的存储布局匹配。

请参阅Solidity 文档,了解映射和动态数组

用法示例:

contract Example {
    // 添加库方法
    using StorageSlot for bytes32;
    using SlotDerivation for bytes32;

    // 声明一个命名空间
    string private constant _NAMESPACE = "&lt;namespace>"; // eg. OpenZeppelin.Slot

    function setValueInNamespace(uint256 key, address newValue) internal {
        _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;
    }

    function getValueInNamespace(uint256 key) internal view returns (address) {
        return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;
    }
}
考虑将此库与 StorageSlot 一起使用。
此库提供了一种以非标准方式操作存储位置的方法。 用于检查升级安全性的工具将忽略通过此库访问的槽。

自 v5.1 起可用。

函数

erc7201Slot(string namespace) → bytes32 slot internal

从字符串 (命名空间) 中派生 ERC-7201 槽。

offset(bytes32 slot, uint256 pos) → bytes32 result internal

向槽添加偏移量以获取结构或数组的第 n 个元素。

deriveArray(bytes32 slot) → bytes32 result internal

从存储长度的槽中派生数组中第一个元素的位置。

deriveMapping(bytes32 slot, address key) → bytes32 result internal

从键派生映射元素的位置。

deriveMapping(bytes32 slot, bool key) → bytes32 result internal

从键派生映射元素的位置。

deriveMapping(bytes32 slot, bytes32 key) → bytes32 result internal

从键派生映射元素的位置。

deriveMapping(bytes32 slot, uint256 key) → bytes32 result internal

从键派生映射元素的位置。

deriveMapping(bytes32 slot, int256 key) → bytes32 result internal

从键派生映射元素的位置。

deriveMapping(bytes32 slot, string key) → bytes32 result internal

从键派生映射元素的位置。

deriveMapping(bytes32 slot, bytes key) → bytes32 result internal

从键派生映射元素的位置。

StorageSlot

import "@openzeppelin/contracts/utils/StorageSlot.sol";

用于将基本类型读取和写入到特定存储槽的库。

存储槽通常用于避免在处理可升级合约时发生存储冲突。 此库有助于读取和写入此类槽,而无需内联汇编。

此库中的函数返回包含可用于读取或写入的 value 成员的 Slot 结构。

使用示例来设置 ERC-1967 实现槽:

contract ERC1967 {
    // 定义槽。 或者,使用 SlotDerivation 库来派生槽。
    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    function _getImplementation() internal view returns (address) {
        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
    }

    function _setImplementation(address newImplementation) internal {
        require(newImplementation.code.length > 0);
        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
    }
}
考虑将此库与 SlotDerivation 一起使用。

函数

getAddressSlot(bytes32 slot) → struct StorageSlot.AddressSlot r internal

返回一个 AddressSlot,其成员 value 位于 slot

getBooleanSlot(bytes32 slot) → struct StorageSlot.BooleanSlot r internal

返回一个 BooleanSlot,其成员 value 位于 slot

getBytes32Slot(bytes32 slot) → struct StorageSlot.Bytes32Slot r internal

返回一个 Bytes32Slot,其成员 value 位于 slot

getUint256Slot(bytes32 slot) → struct StorageSlot.Uint256Slot r internal

返回一个 Uint256Slot,其成员 value 位于 slot

getInt256Slot(bytes32 slot) → struct StorageSlot.Int256Slot r internal

返回一个 Int256Slot,其成员 value 位于 slot

getStringSlot(bytes32 slot) → struct StorageSlot.StringSlot r internal

返回一个 StringSlot,其成员 value 位于 slot

getStringSlot(string store) → struct StorageSlot.StringSlot r internal

返回字符串存储指针 storeStringSlot 表示形式。

getBytesSlot(bytes32 slot) → struct StorageSlot.BytesSlot r internal

返回一个 BytesSlot,其成员 value 位于 slot

getBytesSlot(bytes store) → struct StorageSlot.BytesSlot r internal

返回字节存储指针 storeBytesSlot 表示形式。

TransientSlot

import "@openzeppelin/contracts/utils/TransientSlot.sol";

用于将值类型读取和写入到特定瞬态存储槽的库。

瞬态槽通常用于存储在当前交易后删除的临时值。 此库有助于读取和写入此类槽,而无需内联汇编。

  • 使用瞬态存储读取和写入值的示例:
contract Lock {
    using TransientSlot for *;

    // 定义槽。 或者,使用 SlotDerivation 库来派生槽。
    bytes32 internal constant _LOCK_SLOT = 0xf4678858b2b588224636b8522b729e7722d32fc491da849ed75b3fdf3c84f542;

    modifier locked() {
        require(!_LOCK_SLOT.asBoolean().tload());

        _LOCK_SLOT.asBoolean().tstore(true);
        _;
        _LOCK_SLOT.asBoolean().tstore(false);
    }
}
考虑将此库与 SlotDerivation 一起使用。

函数

asAddress(bytes32 slot) → TransientSlot.AddressSlot internal

将任意槽强制转换为 AddressSlot。

asBoolean(bytes32 slot) → TransientSlot.BooleanSlot internal

将任意槽强制转换为 BooleanSlot。

- _msgData()
_msgSender() → address internal
_msgData() → bytes internal
_contextSuffixLength() → uint256 internal

Packing

import "@openzeppelin/contracts/utils/Packing.sol";

用于将多个值打包和解包到 bytesXX 的辅助库。

使用示例:

library MyPacker {
    type MyType is bytes32;

    function _pack(address account, bytes4 selector, uint64 period) external pure returns (MyType) {
        bytes12 subpack = Packing.pack_4_8(selector, bytes8(period));
        bytes32 pack = Packing.pack_20_12(bytes20(account), subpack);
        return MyType.wrap(pack);
    }

    function _unpack(MyType self) external pure returns (address, bytes4, uint64) {
        bytes32 pack = MyType.unwrap(self);
        return (
            address(Packing.extract_32_20(pack, 0)),
            Packing.extract_32_4(pack, 20),
            uint64(Packing.extract_32_8(pack, 24))
        );
    }
}

加粗自 v5.1 起可用。

函数

错误

pack_1_1(bytes1 left, bytes1 right) → bytes2 result internal
pack_2_2(bytes2 left, bytes2 right) → bytes4 result internal
pack_2_4(bytes2 left, bytes4 right) → bytes6 result internal
pack_2_6(bytes2 left, bytes6 right) → bytes8 result internal
pack_2_8(bytes2 left, bytes8 right) → bytes10 result internal
pack_2_10(bytes2 left, bytes10 right) → bytes12 result internal
pack_2_20(bytes2 left, bytes20 right) → bytes22 result internal
pack_2_22(bytes2 left, bytes22 right) → bytes24 result internal
pack_4_2(bytes4 left, bytes2 right) → bytes6 result internal
pack_4_4(bytes4 left, bytes4 right) → bytes8 result internal
pack_4_6(bytes4 left, bytes6 right) → bytes10 result internal
pack_4_8(bytes4 left, bytes8 right) → bytes12 result internal
pack_4_12(bytes4 left, bytes12 right) → bytes16 result internal
pack_4_16(bytes4 left, bytes16 right) → bytes20 result internal
pack_4_20(bytes4 left, bytes20 right) → bytes24 result internal
pack_4_24(bytes4 left, bytes24 right) → bytes28 result internal
pack_4_28(bytes4 left, bytes28 right) → bytes32 result internal
pack_6_2(bytes6 left, bytes2 right) → bytes8 result internal
pack_6_4(bytes6 left, bytes4 right) → bytes10 result internal
pack_6_6(bytes6 left, bytes6 right) → bytes12 result internal
pack_6_10(bytes6 left, bytes10 right) → bytes16 result internal
pack_6_16(bytes6 left, bytes16 right) → bytes22 result internal
pack_6_22(bytes6 left, bytes22 right) → bytes28 result internal
pack_8_2(bytes8 left, bytes2 right) → bytes10 result internal
pack_8_4(bytes8 left, bytes4 right) → bytes12 result internal
pack_8_8(bytes8 left, bytes8 right) → bytes16 result internal
pack_8_12(bytes8 left, bytes12 right) → bytes20 result internal
pack_8_16(bytes8 left, bytes16 right) → bytes24 result internal
pack_8_20(bytes8 left, bytes20 right) → bytes28 result internal
pack_8_24(bytes8 left, bytes24 right) → bytes32 result internal
pack_10_2(bytes10 left, bytes2 right) → bytes12 result internal
pack_10_6(bytes10 left, bytes6 right) → bytes16 result internal
pack_10_10(bytes10 left, bytes10 right) → bytes20 result internal
pack_10_12(bytes10 left, bytes12 right) → bytes22 result internal
pack_10_22(bytes10 left, bytes22 right) → bytes32 result internal
pack_12_4(bytes12 left, bytes4 right) → bytes16 result internal
pack_12_8(bytes12 left, bytes8 right) → bytes20 result internal
pack_12_10(bytes12 left, bytes10 right) → bytes22 result internal
pack_12_12(bytes12 left, bytes12 right) → bytes24 result internal
pack_12_16(bytes12 left, bytes16 right) → bytes28 result internal
pack_12_20(bytes12 left, bytes20 right) → bytes32 result internal
pack_16_4(bytes16 left, bytes4 right) → bytes20 result internal
pack_16_6(bytes16 left, bytes6 right) → bytes22 result internal
pack_16_8(bytes16 left, bytes8 right) → bytes24 result internal
pack_16_12(bytes16 left, bytes12 right) → bytes28 result internal
pack_16_16(bytes16 left, bytes16 right) → bytes32 result internal
pack_20_2(bytes20 left, bytes2 right) → bytes22 result internal
pack_20_4(bytes20 left, bytes4 right) → bytes24 result internal
pack_20_8(bytes20 left, bytes8 right) → bytes28 result internal
pack_20_12(bytes20 left, bytes12 right) → bytes32 result internal
pack_22_2(bytes22 left, bytes2 right) → bytes24 result internal
pack_22_6(bytes22 left, bytes6 right) → bytes28 result internal
pack_22_10(bytes22 left, bytes10 right) → bytes32 result internal
pack_24_4(bytes24 left, bytes4 right) → bytes28 result internal
pack_24_8(bytes24 left, bytes8 right) → bytes32 result internal
pack_28_4(bytes28 left, bytes4 right) → bytes32 result internal
extract_2_1(bytes2 self, uint8 offset) → bytes1 result internal
replace_2_1(bytes2 self, bytes1 value, uint8 offset) → bytes2 result internal
extract_4_1(bytes4 self, uint8 offset) → bytes1 result internal
replace_4_1(bytes4 self, bytes1 value, uint8 offset) → bytes4 result internal
extract_4_2(bytes4 self, uint8 offset) → bytes2 result internal
replace_4_2(bytes4 self, bytes2 value, uint8 offset) → bytes4 result internal
extract_6_1(bytes6 self, uint8 offset) → bytes1 result internal
replace_6_1(bytes6 self, bytes1 value, uint8 offset) → bytes6 result internal
extract_6_2(bytes6 self, uint8 offset) → bytes2 result internal
replace_6_2(bytes6 self, bytes2 value, uint8 offset) → bytes6 result internal
extract_6_4(bytes6 self, uint8 offset) → bytes4 result internal
replace_6_4(bytes6 self, bytes4 value, uint8 offset) → bytes6 result internal
extract_8_1(bytes8 self, uint8 offset) → bytes1 result internal
replace_8_1(bytes8 self, bytes1 value, uint8 offset) → bytes8 result internal
extract_8_2(bytes8 self, uint8 offset) → bytes2 result internal
replace_8_2(bytes8 self, bytes2 value, uint8 offset) → bytes8 result internal
extract_8_4(bytes8 self, uint8 offset) → bytes4 result internal
replace_8_4(bytes8 self, bytes4 value, uint8 offset) → bytes8 result internal
extract_8_6(bytes8 self, uint8 offset) → bytes6 result internal
replace_8_6(bytes8 self, bytes6 value, uint8 offset) → bytes8 result internal
extract_10_1(bytes10 self, uint8 offset) → bytes1 result internal
replace_10_1(bytes10 self, bytes1 value, uint8 offset) → bytes10 result internal
extract_10_2(bytes10 self, uint8 offset) → bytes2 result internal
replace_10_2(bytes10 self, bytes2 value, uint8 offset) → bytes10 result internal
extract_10_4(bytes10 self, uint8 offset) → bytes4 result internal
replace_10_4(bytes10 self, bytes4 value, uint8 offset) → bytes10 result internal
extract_10_6(bytes10 self, uint8 offset) → bytes6 result internal
replace_10_6(bytes10 self, bytes6 value, uint8 offset) → bytes10 result internal
extract_10_8(bytes10 self, uint8 offset) → bytes8 result internal
replace_10_8(bytes10 self, bytes8 value, uint8 offset) → bytes10 result internal
extract_12_1(bytes12 self, uint8 offset) → bytes1 result internal
replace_12_1(bytes12 self, bytes1 value, uint8 offset) → bytes12 result internal
extract_12_2(bytes12 self, uint8 offset) → bytes2 result internal
replace_12_2(bytes12 self, bytes2 value, uint8 offset) → bytes12 result internal
extract_12_4(bytes12 self, uint8 offset) → bytes4 result internal
replace_12_4(bytes12 self, bytes4 value, uint8 offset) → bytes12 result internal
extract_12_6(bytes12 self, uint8 offset) → bytes6 result internal
replace_12_6(bytes12 self, bytes6 value, uint8 offset) → bytes12 result internal
extract_12_8(bytes12 self, uint8 offset) → bytes8 result internal
replace_12_8(bytes12 self, bytes8 value, uint8 offset) → bytes12 result internal
extract_12_10(bytes12 self, uint8 offset) → bytes10 result internal
replace_12_10(bytes12 self, bytes10 value, uint8 offset) → bytes12 result internal
extract_16_1(bytes16 self, uint8 offset) → bytes1 result internal
replace_16_1(bytes16 self, bytes1 value, uint8 offset) → bytes16 result internal
extract_16_2(bytes16 self, uint8 offset) → bytes2 result internal
replace_16_2(bytes16 self, bytes2 value, uint8 offset) → bytes16 result internal
extract_16_4(bytes16 self, uint8 offset) → bytes4 result internal
replace_16_4(bytes16 self, bytes4 value, uint8 offset) → bytes16 result internal
extract_16_6(bytes16 self, uint8 offset) → bytes6 result internal
replace_16_6(bytes16 self, bytes6 value, uint8 offset) → bytes16 result internal
extract_16_8(bytes16 self, uint8 offset) → bytes8 result internal
replace_16_8(bytes16 self, bytes8 value, uint8 offset) → bytes16 result internal
extract_16_10(bytes16 self, uint8 offset) → bytes10 result internal
replace_16_10(bytes16 self, bytes10 value, uint8 offset) → bytes16 result internal
extract_16_12(bytes16 self, uint8 offset) → bytes12 result internal
replace_16_12(bytes16 self, bytes12 value, uint8 offset) → bytes16 result internal
extract_20_1(bytes20 self, uint8 offset) → bytes1 result internal
replace_20_1(bytes20 self, bytes1 value, uint8 offset) → bytes20 result internal
extract_20_2(bytes20 self, uint8 offset) → bytes2 result internal
replace_20_2(bytes20 self, bytes2 value, uint8 offset) → bytes20 result internal
extract_20_4(bytes20 self, uint8 offset) → bytes4 result internal
replace_20_4(bytes20 self, bytes4 value, uint8 offset) → bytes20 result internal
extract_20_6(bytes20 self, uint8 offset) → bytes6 result internal
replace_20_6(bytes20 self, bytes6 value, uint8 offset) → bytes20 result internal
extract_20_8(bytes20 self, uint8 offset) → bytes8 result internal
replace_20_8(bytes20 self, bytes8 value, uint8 offset) → bytes20 result internal
extract_20_10(bytes20 self, uint8 offset) → bytes10 result internal
replace_20_10(bytes20 self, bytes10 value, uint8 offset) → bytes20 result internal
extract_20_12(bytes20 self, uint8 offset) → bytes12 result internal
replace_20_12(bytes20 self, bytes12 value, uint8 offset) → bytes20 result internal
extract_20_16(bytes20 self, uint8 offset) → bytes16 result internal
replace_20_16(bytes20 self, bytes16 value, uint8 offset) → bytes20 result internal
extract_22_1(bytes22 self, uint8 offset) → bytes1 result internal
replace_22_1(bytes22 self, bytes1 value, uint8 offset) → bytes22 result internal
extract_22_2(bytes22 self, uint8 offset) → bytes2 result internal
replace_22_2(bytes22 self, bytes2 value, uint8 offset) → bytes22 result internal
extract_22_4(bytes22 self, uint8 offset) → bytes4 result internal
replace_22_4(bytes22 self, bytes4 value, uint8 offset) → bytes22 result internal
extract_22_6(bytes22 self, uint8 offset) → bytes6 result internal
replace_22_6(bytes22 self, bytes6 value, uint8 offset) → bytes22 result internal
extract_22_8(bytes22 self, uint8 offset) → bytes8 result internal
replace_22_8(bytes22 self, bytes8 value, uint8 offset) → bytes22 result internal
extract_22_10(bytes22 self, uint8 offset) → bytes10 result internal
replace_22_10(bytes22 self, bytes10 value, uint8 offset) → bytes22 result internal
extract_22_12(bytes22 self, uint8 offset) → bytes12 result internal
replace_22_12(bytes22 self, bytes12 value, uint8 offset) → bytes22 result internal
extract_22_16(bytes22 self, uint8 offset) → bytes16 result internal
replace_22_16(bytes22 self, bytes16 value, uint8 offset) → bytes22 result internal
extract_22_20(bytes22 self, uint8 offset) → bytes20 result internal
replace_22_20(bytes22 self, bytes20 value, uint8 offset) → bytes22 result internal
extract_24_1(bytes24 self, uint8 offset) → bytes1 result internal
replace_24_1(bytes24 self, bytes1 value, uint8 offset) → bytes24 result internal
extract_24_2(bytes24 self, uint8 offset) → bytes2 result internal
replace_24_2(bytes24 self, bytes2 value, uint8 offset) → bytes24 result internal
extract_24_4(bytes24 self, uint8 offset) → bytes4 result internal
replace_24_4(bytes24 self, bytes4 value, uint8 offset) → bytes24 result internal
extract_24_6(bytes24 self, uint8 offset) → bytes6 result internal
replace_24_6(bytes24 self, bytes6 value, uint8 offset) → bytes24 result internal
extract_24_8(bytes24 self, uint8 offset) → bytes8 result internal
replace_24_8(bytes24 self, bytes8 value, uint8 offset) → bytes24 result internal
extract_24_10(bytes24 self, uint8 offset) → bytes10 result internal
replace_24_10(bytes24 self, bytes10 value, uint8 offset) → bytes24 result internal
extract_24_12(bytes24 self, uint8 offset) → bytes12 result internal
replace_24_12(bytes24 self, bytes12 value, uint8 offset) → bytes24 result internal
extract_24_16(bytes24 self, uint8 offset) → bytes16 result internal
replace_24_16(bytes24 self, bytes16 value, uint8 offset) → bytes24 result internal
extract_24_20(bytes24 self, uint8 offset) → bytes20 result internal
replace_24_20(bytes24 self, bytes20 value, uint8 offset) → bytes24 result internal
extract_24_22(bytes24 self, uint8 offset) → bytes22 result internal
replace_24_22(bytes24 self, bytes22 value, uint8 offset) → bytes24 result internal
extract_28_1(bytes28 self, uint8 offset) → bytes1 result internal
replace_28_1(bytes28 self, bytes1 value, uint8 offset) → bytes28 result internal
extract_28_2(bytes28 self, uint8 offset) → bytes2 result internal
replace_28_2(bytes28 self, bytes2 value, uint8 offset) → bytes28 result internal
extract_28_4(bytes28 self, uint8 offset) → bytes4 result internal
replace_28_4(bytes28 self, bytes4 value, uint8 offset) → bytes28 result internal
extract_28_6(bytes28 self, uint8 offset) → bytes6 result internal
replace_28_6(bytes28 self, bytes6 value, uint8 offset) → bytes28 result internal
extract_28_8(bytes28 self, uint8 offset) → bytes8 result internal
replace_28_8(bytes28 self, bytes8 value, uint8 offset) → bytes28 result internal
extract_28_10(bytes28 self, uint8 offset) → bytes10 result internal
replace_28_10(bytes28 self, bytes10 value, uint8 offset) → bytes28 result internal
extract_28_12(bytes28 self, uint8 offset) → bytes12 result internal
replace_28_12(bytes28 self, bytes12 value, uint8 offset) → bytes28 result internal
extract_28_16(bytes28 self, uint8 offset) → bytes16 result internal
replace_28_16(bytes28 self, bytes16 value, uint8 offset) → bytes28 result internal
extract_28_20(bytes28 self, uint8 offset) → bytes20 result internal
replace_28_20(bytes28 self, bytes20 value, uint8 offset) → bytes28 result internal
extract_28_22(bytes28 self, uint8 offset) → bytes22 result internal
replace_28_22(bytes28 self, bytes22 value, uint8 offset) → bytes28 result internal
extract_28_24(bytes28 self, uint8 offset) → bytes24 result internal
replace_28_24(bytes28 self, bytes24 value, uint8 offset) → bytes28 result internal
extract_32_1(bytes32 self, uint8 offset) → bytes1 result internal
replace_32_1(bytes32 self, bytes1 value, uint8 offset) → bytes32 result internal
extract_32_2(bytes32 self, uint8 offset) → bytes2 result internal
replace_32_2(bytes32 self, bytes2 value, uint8 offset) → bytes32 result internal
extract_32_4(bytes32 self, uint8 offset) → bytes4 result internal
replace_32_4(bytes32 self, bytes4 value, uint8 offset) → bytes32 result internal
extract_32_6(bytes32 self, uint8 offset) → bytes6 result internal
replace_32_6(bytes32 self, bytes6 value, uint8 offset) → bytes32 result internal
extract_32_8(bytes32 self, uint8 offset) → bytes8 result internal
replace_32_8(bytes32 self, bytes8 value, uint8 offset) → bytes32 result internal
extract_32_10(bytes32 self, uint8 offset) → bytes10 result internal
replace_32_10(bytes32 self, bytes10 value, uint8 offset) → bytes32 result internal
extract_32_12(bytes32 self, uint8 offset) → bytes12 result internal
replace_32_12(bytes32 self, bytes12 value, uint8 offset) → bytes32 result internal
extract_32_16(bytes32 self, uint8 offset) → bytes16 result internal
replace_32_16(bytes32 self, bytes16 value, uint8 offset) → bytes32 result internal
extract_32_20(bytes32 self, uint8 offset) → bytes20 result internal
replace_32_20(bytes32 self, bytes20 value, uint8 offset) → bytes32 result internal
extract_32_22(bytes32 self, uint8 offset) → bytes22 result internal
replace_32_22(bytes32 self, bytes22 value, uint8 offset) → bytes32 result internal
extract_32_24(bytes32 self, uint8 offset) → bytes24 result internal
replace_32_24(bytes32 self, bytes24 value, uint8 offset) → bytes32 result internal
extract_32_28(bytes32 self, uint8 offset) → bytes28 result internal
replace_32_28(bytes32 self, bytes28 value, uint8 offset) → bytes32 result internal
OutOfRangeAccess() 错误

Panic

import "@openzeppelin/contracts/utils/Panic.sol";

用于发出标准 panic 代码的辅助库。

contract Example {
     using Panic for uint256;

     // 使用任何已声明的内部常量
     function foo() { Panic.GENERIC.panic(); }

     // 或者
     function foo() { Panic.panic(Panic.GENERIC); }
}

遵循 libsolutil 中的列表。

加粗自从 v5.1 可用。加粗

函数

内部变量

panic(uint256 code) internal

使用 panic 代码恢复。建议与具有预定义代码的内部常量一起使用。

uint256 GENERIC internal constant

通用/未指定错误

uint256 ASSERT internal constant

由 assert() 内置函数使用

uint256 UNDER_OVERFLOW internal constant

算术下溢或溢出

uint256 DIVISION_BY_ZERO internal constant

除以零或模零

uint256 ENUM_CONVERSION_ERROR internal constant

枚举转换错误

uint256 STORAGE_ENCODING_ERROR internal constant

存储中无效的编码

uint256 EMPTY_ARRAY_POP internal constant

空数组弹出

uint256 ARRAY_OUT_OF_BOUNDS internal constant

数组越界访问

uint256 RESOURCE_ERROR internal constant

资源错误(分配太大或数组太大)

uint256 INVALID_INTERNAL_FUNCTION internal constant

调用无效的内部函数

Comparators

import "@openzeppelin/contracts/utils/Comparators.sol";

提供一组用于比较函数值的函数##### parse(string caip10) → string caip2, string account internal

将 CAIP-10 标识符解析为它的组成部分。

这个函数不会验证 CAIP-10 输入的格式是否正确。 caip2 返回值可以使用 CAIP2 库进行解析。

← Proxy

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

0 条评论

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