本文档是 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 证明的函数。
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
: 一种数据结构,用于存储映射到严格递增键的值。 可用于随时间存储和访问值。
MerkleTree
: 包含 Merkle Tree 数据结构和辅助函数的库。
Create2
: CREATE2
EVM 操作码 的包装器,用于安全使用,无需处理底层汇编。
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
库一起使用的库。
因为 Solidity 不支持泛型类型,所以 EnumerableMap 和 EnumerableSet 专门用于有限数量的键值类型。 |
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
通过
当这样的操作溢出时回退事务来恢复这种直觉。
使用此库而不是未检查的操作可以消除整个 类别的错误,因此建议始终使用它。
函数
[toUint144(- [
toUint(b)`](https://docs.openzeppelin.com/contracts/5.x/api/utils#SafeCast-toUint-bool-)
错误
toUint248(uint256 value) → uint248
internal从 uint256 返回向下转换的 uint248,在溢出时回退(当输入大于最大 uint248 时)。
与 Solidity 的 uint248
运算符对应。
要求:
toUint240(uint256 value) → uint240
internal从 uint256 返回向下转换的 uint240,在溢出时回退(当输入大于最大 uint240 时)。
与 Solidity 的 uint240
运算符对应。
要求:
toUint232(uint256 value) → uint232
internal从 uint256 返回向下转换的 uint232,在溢出时回退(当输入大于最大 uint232 时)。
与 Solidity 的 uint232
运算符对应。
要求:
toUint224(uint256 value) → uint224
internal从 uint256 返回向下转换的 uint224,在溢出时回退(当输入大于最大 uint224 时)。
与 Solidity 的 uint224
运算符对应。
要求:
toUint216(uint256 value) → uint216
internal从 uint256 返回向下转换的 uint216,在溢出时回退(当输入大于最大 uint216 时)。
与 Solidity 的 uint216
运算符对应。
要求:
toUint208(uint256 value) → uint208
internal从 uint256 返回向下转换的 uint208,在溢出时回退(当输入大于最大 uint208 时)。
与 Solidity 的 uint208
运算符对应。
要求:
toUint200(uint256 value) → uint200
internal从 uint256 返回向下转换的 uint200,在溢出时回退(当输入大于最大 uint200 时)。
与 Solidity 的 uint200
运算符对应。
要求:
toUint192(uint256 value) → uint192
internal从 uint256 返回向下转换的 uint192,在溢出时回退(当输入大于最大 uint192 时)。
与 Solidity 的 uint192
运算符对应。
要求:
toUint184(uint256 value) → uint184
internal从 uint256 返回向下转换的 uint184,在溢出时回退(当输入大于最大 uint184 时)。
与 Solidity 的 uint184
运算符对应。
要求:
toUint176(uint256 value) → uint176
internal从 uint256 返回向下转换的 uint176,在溢出时回退(当输入大于最大 uint176 时)。
与 Solidity 的 uint176
运算符对应。
要求:
toUint168(uint256 value) → uint168
internal从 uint256 返回向下转换的 uint168,在溢出时回退(当输入大于最大 uint168 时)。
与 Solidity 的 uint168
运算符对应。
要求:
toUint160(uint256 value) → uint160
internal从 uint256 返回向下转换的 uint160,在溢出时回退(当输入大于最大 uint160 时)。
与 Solidity 的 uint160
运算符对应。
要求:
toUint152(uint256 value) → uint152
internal从 uint256 返回向下转换的 uint152,在溢出时回退(当输入大于最大 uint152 时)。
与 Solidity 的 uint152
运算符对应。
要求:
toUint144(uint256 value) → uint144
internal从 uint256 返回向下转换的 uint144,在溢出时回退(当输入大于最大 uint144 时)。
与 Solidity 的 uint144
运算符对应。
要求:
toUint136(uint256 value) → uint136
internal从 uint256 返回向下转换的 uint136,在溢出时回退(当输入大于最大 uint136 时)。
与 Solidity 的 uint136
运算符对应。
要求:
toUint128(uint256 value) → uint128
internal从 uint256 返回向下转换的 uint128,在溢出时回退(当输入大于最大 uint128 时)。
与 Solidity 的 uint128
运算符对应。
要求:
toUint120(uint256 value) → uint120
internal从 uint256 返回向下转换的 uint120,在溢出时回退(当输入大于最大 uint120 时)。
与 Solidity 的 uint120
运算符对应。
要求:
toUint112(uint256 value) → uint112
internal从 uint256 返回向下转换的 uint112,在溢出时回退(当输入大于最大 uint112 时)。
与 Solidity 的 uint112
运算符对应。
要求:
toUint104(uint256 value) → uint104
internal从 uint256 返回向下转换的 uint104,在溢出时回退(当输入大于最大 uint104 时)。
与 Solidity 的 uint104
运算符对应。
要求:
toUint96(uint256 value) → uint96
internal从 uint256 返回向下转换的 uint96,在溢出时回退(当输入大于最大 uint96 时)。
与 Solidity 的 uint96
运算符对应。
要求:
toUint88(uint256 value) → uint88
internal从 uint256 返回向下转换的 uint88,在溢出时回退(当输入大于最大 uint88 时)。
与 Solidity 的 uint88
运算符对应。
要求:
toUint80(uint256 value) → uint80
internal从 uint256 返回向下转换的 uint80,在溢出时回退(当输入大于最大 uint80 时)。
与 Solidity 的 uint80
运算符对应。
要求:
toUint72(uint256 value) → uint72
internal从 uint256 返回向下转换的 uint72,在溢出时回退(当输入大于最大 uint72 时)。
与 Solidity 的 uint72
运算符对应。
要求:
toUint64(uint256 value) → uint64
internal从 uint256 返回向下转换的 uint64,在溢出时回退(当输入大于最大 uint64 时)。
与 Solidity 的 uint64
运算符对应。
要求:
toUint56(uint256 value) → uint56
internal从 uint256 返回向下转换的 uint56,在溢出时回退(当输入大于最大 uint56 时)。
与 Solidity 的 uint56
运算符对应。
要求:
toUint48(uint256 value) → uint48
internal从 uint256 返回向下转换的 uint48,在溢出时回退(当输入大于最大 uint48 时)。
与 Solidity 的 uint48
运算符对应。
要求:
toUint40(uint256 value) → uint40
internal从 uint256 返回向下转换的 uint40,在溢出时回退(当输入大于最大 uint40 时)。
与 Solidity 的 uint40
运算符对应。
要求:
toUint32(uint256 value) → uint32
internal从 uint256 返回向下转换的 uint32,在溢出时回退(当输入大于最大 uint32 时)。
与 Solidity 的 uint32
运算符对应。
要求:
toUint24(uint256 value) → uint24
internal从 uint256 返回向下转换的 uint24,在溢出时回退(当输入大于最大 uint24 时)。
与 Solidity 的 uint24
运算符对应。
要求:
toUint16(uint256 value) → uint16
internal从 uint256 返回向下转换的 uint16,在溢出时回退(当输入大于最大 uint16 时)。
与 Solidity 的 uint16
运算符对应。
要求:
toUint8(uint256 value) → uint8
internal从 uint256 返回向下转换的 uint8,在溢出时回退(当输入大于最大 uint8 时)。
与 Solidity 的 uint8
运算符对应。
要求:
toUint256(int256 value) → uint256
internal将有符号 int256 转换为无符号 uint256。
要求:
toInt248(int256 value) → int248 downcasted
internal从 int256 返回向下转换的 int248,在溢出时回退(当输入小于最小 int248 或大于最大 int248 时)。
与 Solidity 的 int248
运算符对应。
要求:
toInt240(int256 value) → int240 downcasted
internal从 int256 返回向下转换的 int240,在溢出时回退(当输入小于最小 int240 或大于最大 int240 时)。
与 Solidity 的 int240
运算符对应。
要求:
toInt232(int256 value) → int232 downcasted
internal从 int256 返回向下转换的 int232,在溢出时回退(当输入小于最小 int232 或大于最大 int232 时)。
与 Solidity 的 int232
运算符对应。
要求:
toInt224(int256 value) → int224 downcasted
internal从 int256 返回向下转换的 int224,在溢出时回退(当输入小于最小 int224 或大于最大 int224 时)。
与 Solidity 的 int224
运算符对应。
要求:
toInt216(int256 value) → int216 downcasted
internal从 int256 返回向下转换的 int216,在溢出时回退(当输入小于最小 int216 或大于最大 int216 时)。
与 Solidity 的 int216
运算符对应。
要求:
toInt208(int256 value) → int208 downcasted
internal从 int256 返回向下转换的 int208,在溢出时回退(当输入小于最小 int208 或大于最大 int208 时)。
与 Solidity 的 int208
运算符对应。
要求:
toInt200(int256 value) → int200 downcasted
internal从 int256 返回向下转换的 int200,在溢出时回退(当输入小于最小 int200 或大于最大 int200 时)。
与 Solidity 的 int200
运算符对应。
要求:
toInt192(int256 value) → int192 downcasted
internal从 int256 返回向下转换的 int192,在溢出时回退(当输入小于最小 int192 或大于最大 int192 时)。
与 Solidity 的 int192
运算符对应。
要求:
toInt184(int256 value) → int184 downcasted
internal从 int256 返回向下转换的 int184,在溢出时回退(当输入小于最小 int184 或大于最大 int184 时)。
与 Solidity 的 int184
运算符对应。
要求:
toInt176(int256 value) → int176 downcasted
internal从 int256 返回向下转换的 int176,在溢出时回退(当输入小于最小 int176 或大于最大 int176 时)。
与 Solidity 的 int176
运算符对应。
要求:
toInt168(int256 value) → int168 downcasted
internal从 int256 返回向下转换的 int168,在溢出时回退(当输入小于最小 int168 或大于最大 int168 时)。
与 Solidity 的 int168
运算符对应。
要求:
toInt160(int256 value) → int160 downcasted
internal从 int256 返回向下转换的 int160,在溢出时回退(当输入小于最小 int160 或大于最大 int160 时)。
与 Solidity 的 int160
运算符对应。
要求:
toInt152(int256 value) → int152 downcasted
internal从 int256 返回向下转换的 int152,在溢出时回退(当输入小于最小 int152 或大于最大 int152 时)。
与 Solidity 的 int152
运算符对应。
要求:
toInt144(int256 value) → int144 downcasted
internal从 int256 返回向下转换的 int144,在溢出时回退(当输入小于最小 int144 或大于最大 int144 时)。
与 Solidity 的 int144
运算符对应。
要求:
toInt136(int256 value) → int136 downcasted
internal从 int256 返回向下转换的 int136,在溢出时回退(当输入小于最小 int136 或大于最大 int136 时)。
与 Solidity 的 int136
运算符对应。
要求:
toInt128(int256 value) → int128 downcasted
internal从 int256 返回向下转换的 int128,在溢出时回退(当输入小于最小 int128 或大于最大 int128 时)。
与 Solidity 的 int128
运算符对应。
要求:
toInt120(int256 value) → int120 downcasted
internal从 int256 返回向下转换的 int120,在溢出时回退(当输入小于最小 int120 或大于最大 int120 时)。
与 Solidity 的 int120
运算符对应。
要求:
toInt112(int256 value) → int112 downcasted
internal从 int256 返回向下转换的 int112,在溢出时回退(当输入小于最小 int112 或大于最大 int112 时)。
与 Solidity 的 int112
运算符对应。
要求:
toInt104(int256 value) → int104 downcasted
internal从 int256 返回向下转换的 int104,在溢出时回退(当输入小于最小 int104 或大于最大 int104 时)。
与 Solidity 的 int104
运算符对应。
要求:
toInt96(int256 value) → int96 downcasted
internal从 int256 返回向下转换的 int96,在溢出时回退(当输入小于最小 int96 或大于最大 int96 时)。
与 Solidity 的 int96
运算符对应。
要求:
toInt88(int256 value) → int88 downcasted
internal从 int256 返回向下转换的 int88,在溢出时回退(当输入小于最小 int88 或大于最大 int88 时)。
与 Solidity 的 int88
运算符对应。
要求:
toInt80(int256 value) → int80 downcasted
internal从 int256 返回向下转换的 int80,在溢出时回退(当输入小于最小 int80 或大于最大 int80 时)。
与 Solidity 的 int80
运算符对应。
要求:
toInt72(int256 value) → int72 downcasted
internal从 int256 返回向下转换的 int72,在溢出时回退(当输入小于最小 int72 或大于最大 int72 时)。
与 Solidity 的 int72
运算符对应。
要求:
toInt64(int256 value) → int64 downcasted
internal从 int256 返回向下转换的 int64,在溢出时回退(当输入小于最小 int64 或大于最大 int64 时)。
与 Solidity 的 int64
运算符对应。
要求:
toInt56(int256 value) → int56 downcasted
internal从 int256 返回向下转换的 int56,在溢出时回退(当输入小于最小 int56 或大于最大 int56 时)。
与 Solidity 的 int56
运算符对应。
要求:
toInt48(int256 value) → int48 downcasted
internal从 int256 返回向下转换的 int48,在溢出时回退(当输入小于最小 int48 或大于最大 int48 时)。
与 Solidity 的 int48
运算符对应。
要求:
toInt40(int256 value) → int40 downcasted
internal从 int256 返回向下转换的 int40,在溢出时回退(当输入小于最小 int40 或大于最大 int40 时)。
与 Solidity 的 int40
运算符对应。
要求:
toInt32(int256 value) → int32 downcasted
internal从 int256 返回向下转换的 int32,在溢出时回退(当输入小于最小 int32 或大于最大 int32 时)。
与 Solidity 的 int32
运算符对应。
要求:
toInt24(int256 value) → int24 downcasted
internal从 int256 返回向下转换的 int24,在溢出时回退(当输入小于最小 int24 或大于最大 int24 时)。
与 Solidity 的 int24
运算符对应。
要求:
toInt16(int256 value) → int16 downcasted
internal从 int256 返回向下转换的 int16,在溢出时回退(当输入小于最小 int16 或大于最大 int16 时)。
与 Solidity 的 int16
运算符对应。
要求:
toInt8(int256 value) → int8 downcasted
internal从 int256 返回向下转换的 int8,在溢出时回退(当输入小于最小 int8 或大于最大 int8 时)。
与 Solidity 的 int8
运算符对应。
要求:
toInt256(uint256 value) → int256
internal将无符号 uint256 转换为有符号 int256。
要求:
toUint(bool b) → uint256 u
internal将布尔值(false 或 true)转换为 uint256(0 或 1),无需跳转。
SafeCastOverflowedUintDowncast(uint8 bits, uint256 value)
error值不适合 bits
大小的 uint。
SafeCastOverflowedIntToUint(int256 value)
errorint 值不适合 bits
大小的 uint。
SafeCastOverflowedIntDowncast(uint8 bits, int256 value)
error值不适合 bits
大小的 int。
SafeCastOverflowedUintToInt(uint256 value)
erroruint 值不适合 bits
大小的 int。
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
internalECDSA.tryRecover
的重载,用于分别接收 r
和 vs
短签名字段。
请参阅 ERC-2098 短签名
recover(bytes32 hash, bytes32 r, bytes32 vs) → address
internalECDSA.recover
的重载,用于分别接收 r 和 vs
短签名字段。
tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) → address recovered, enum ECDSA.RecoverError err, bytes32 errArg
internalECDSA.tryRecover
的重载,用于分别接收 v
、r
和 s
签名字段。
recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) → address
internalECDSA.recover
的重载,用于分别接收 v
、r
和 s
签名字段。
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)。 很大程度上受到 maxrobot 和 tdrerup 实现的启发。
自 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.encode
和 keccak256
的组合来生成其类型化数据的哈希值。
此合约实现了 EIP-712 域分隔符(_domainSeparatorV4
),它用作编码的一部分,以及编码的最后一步,以获得通过 ECDSA 签名的消息摘要 ( _hashTypedDataV4
)。
域分隔符的实现旨在尽可能高效,同时仍能正确更新 链 ID,以防止在链的最终分叉上发生重放攻击。
此合约实现了称为“v4”的编码版本,如 JSON RPC 方法中实现的那样 eth_signTypedDataV4 in MetaMask。 |
在此合约的可升级版本中,缓存值将对应于地址和实现合约的域分隔符。这将导致 _domainSeparatorV4 函数始终从不可变值重建分隔符,这比访问冷存储中的缓存版本更便宜。 |
函数
事件
IERC5267
constructor(string name, string version)
内部函数初始化域分隔符和参数缓存。
name
和 version
的含义在
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-191 和 EIP 712 规范的消息哈希的方法。
函数
toEthSignedMessageHash(bytes32 messageHash) → bytes32 digest
内部函数返回带有版本 0x45
(personal_sign
消息)的 ERC-191 签名数据的 keccak256 摘要。
通过将 bytes32 messageHash
前缀为 "\x19Ethereum Signed Message:\n32"
并对结果进行哈希来计算摘要。它对应于使用 eth_sign
JSON-RPC 方法签名时的哈希。
messageHash 参数旨在成为使用 keccak256 对原始消息进行哈希处理的结果,尽管可以安全地使用任何 bytes32 值,因为最终的摘要将被重新哈希处理。 |
请参阅 ECDSA.recover
.
toEthSignedMessageHash(bytes message) → bytes32
内部函数返回带有版本 0x45
(personal_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 摘要。
摘要由 domainSeparator
和 structHash
计算得出,方法是用 \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) )构建的默克尔树的证明验证。证明在使用不可交换哈希函数构建的树中包含叶子需要此库不支持的其他逻辑。 |
函数
multiProofVerifyCalldata(proof, proofFlags, root, leaves, hasher)
processMultiProofCalldata(proof, proofFlags, leaves, hasher)
错误
verify(bytes32[] proof, bytes32 root, bytes32 leaf) → bool
内部函数如果可以证明 leaf
是由 root
定义的默克尔树的一部分,则返回 true。为此,必须提供一个 proof
,其中包含从树的叶子到根的分支上的同级哈希。假定每对叶子和每对预映像都已排序。
此版本使用默认哈希函数处理内存中的证明。
processProof(bytes32[] proof, bytes32 leaf) → bytes32
内部函数返回通过使用 proof
从 leaf
向上遍历默克尔树获得的重建哈希。当且仅当重建的哈希与树的根匹配时,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
内部函数返回通过使用 proof
从 leaf
向上遍历默克尔树获得的重建哈希。当且仅当重建的哈希与树的根匹配时,proof
才有效。在处理证明时,假定叶子和预映像对已排序。
此版本使用自定义哈希函数处理内存中的证明。
verifyCalldata(bytes32[] proof, bytes32 root, bytes32 leaf) → bool
内部函数如果可以证明 leaf
是由 root
定义的默克尔树的一部分,则返回 true。为此,必须提供一个 proof
,其中包含从树的叶子到根的分支上的同级哈希。假定每对叶子和每对预映像都已排序。
此版本使用默认哈希函数处理 calldata 中的证明。
processProofCalldata(bytes32[] proof, bytes32 leaf) → bytes32
内部函数返回通过使用 proof
从 leaf
向上遍历默克尔树获得的重建哈希。当且仅当重建的哈希与树的根匹配时,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
内部函数返回通过使用 proof
从 leaf
向上遍历默克尔树获得的重建哈希。当且仅当重建的哈希与树的根匹配时,proof
才有效。在处理证明时,假定叶子和预映像对已排序。
此版本使用自定义哈希函数处理 calldata 中的证明。
multiProofVerify(bytes32[] proof, bool[] proofFlags, bytes32 root, bytes32[] leaves) → bool
内部函数如果可以根据 processMultiProof
中描述的 proof
和 proofFlags
同时证明 leaves
是由 root
定义的默克尔树的一部分,则返回 true。
此版本使用默认哈希函数处理内存中的多重证明。
并非所有默克尔树都允许使用多重证明。有关详细信息,请参阅 processMultiProof 。 |
考虑 root == proof[0] && leaves.length == 0 的情况,因为它将返回 true 。leaves 必须独立验证。有关详细信息,请参阅 processMultiProof 。 |
processMultiProof(bytes32[] proof, bool[] proofFlags, bytes32[] leaves) → bytes32 merkleRoot
内部函数返回从 leaves
和 proof
中的同级节点重建的树的根。重建过程通过将叶子/内部节点与另一个叶子/内部节点或证明同级节点相结合来增量重建所有内部节点,具体取决于每个 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
中描述的 proof
和 proofFlags
同时证明 leaves
是由 root
定义的默克尔树的一部分,则返回 true。
此版本使用自定义哈希函数处理内存中的多重证明。
并非所有默克尔树都允许使用多重证明。有关详细信息,请参阅 processMultiProof 。 |
考虑 root == proof[0] && leaves.length == 0 的情况,因为它将返回 true 。leaves 必须独立验证。有关详细信息,请参阅 processMultiProof 。 |
processMultiProof(bytes32[] proof, bool[] proofFlags, bytes32[] leaves, function (bytes32,bytes32) view returns (bytes32) hasher) → bytes32 merkleRoot
内部函数返回从 leaves
和 proof
中的同级节点重建的树的根。重建过程通过将叶子/内部节点与另一个叶子/内部节点或证明同级节点相结合来增量重建所有内部节点,具体取决于每个 proofFlags
项是 true 还是 false。
此版本使用自定义哈希函数处理内存中的多重证明。
并非所有默克尔树都允许使用多重证明。要使用多重证明,足以确保:1) 树是完整的(但不一定是完美的),2) 要证明的叶子的顺序与它们在树中的顺序相反(即,从右向左看,从最深的一层开始,并在下一层继续)。 |
空集(即 proof.length == 1 && leaves.length == 0 的情况)被视为无操作,因此是有效的多重证明(即它返回 proof[0] )。如果你没有在其他地方验证叶子,请考虑禁止这种情况。 |
multiProofVerifyCalldata(bytes32[] proof, bool[] proofFlags, bytes32 root, bytes32[] leaves) → bool
内部函数如果可以根据 processMultiProof
中描述的 proof
和 proofFlags
同时证明 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返回由 leaves
和 proof
中的兄弟节点重建的树的根。 重建过程通过递增地重建所有内部节点,将叶节点/内部节点与另一个叶节点/内部节点或证明兄弟节点组合,具体取决于每个 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";
允许子合约实现紧急停止机制的合约模块,该机制可以由授权帐户触发。
此模块通过继承使用。 它将提供修饰符 whenNotPaused
和 whenPaused
,这些修饰符可以应用于合约的函数。 请注意,仅在修饰符到位后,它们才可以通过简单地包含此模块来暂停。
修饰符
函数
事件
错误
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";
为地址提供跟踪 nonce。 Nonce 只会增加。
函数
错误
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用于 account
的 nonce 不是预期的当前 nonce。
NoncesKeyed
import "@openzeppelin/contracts/utils/NoncesKeyed.sol";
nonces
的替代方案,支持键控 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
publicERC165Checker
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
本身的支持。
getSupportedInterfaces(address account, bytes4[] interfaceIds) → bool[]
internal返回一个布尔数组,其中每个值对应于传入的接口以及它们是否受支持。 这使你可以批量检查合约的接口,其中你的期望是某些接口可能不受支持。
supportsAllInterfaces(address account, bytes4[] interfaceIds) → bool
internal如果 account
支持 interfaceIds
中定义的所有接口,则返回 true。 将自动查询对 IERC165
本身的支持。
批量查询可以通过跳过对
IERC165
支持的重复检查来节省 gas。
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 数组创建一个新实例。 |
函数
[length(map)
](https://docs.openzeppelin.com/contracts/5.x/api/utils#EnumerableMap-length-struct- set(map, key, value)
错误
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
必须是正在更新的叶子的最新包含证明。这意味着此函数
容易受到抢先交易攻击。任何 push
或 update
操作(更改树的根)将使
所有“正在进行中”的更新无效。
此变体使用 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
必须是正在更新的叶子的最新包含证明。这意味着此函数
容易受到抢先交易攻击。任何 push
或 update
操作(更改树的根)将使
所有“正在进行中”的更新无效。
此变体使用自定义哈希函数来哈希内部节点。它应该只使用与 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
部署的话。bytecodeHash
或 salt
的任何更改都会导致新的目标地址。
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)
internalSolidity 的 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)
errortarget
处没有代码(它不是合约)。
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[]
internalsort
的变体,用于按递增顺序对 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[]
internalsort
的变体,用于按递增顺序对 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[]
internalsort
的变体,用于按递增顺序对 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
internalemptyString() → string result
internalStrings
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
internalparseUint
的变体,它解析位于位置 begin
(包含)和 end
(排除)之间的 input
的子字符串。
要求:
- 子字符串必须格式化为 [0-9]*
- 结果必须适合 uint256
类型
tryParseUint(string input) → bool success, uint256 value
internalparseUint
的变体,如果由于无效字符导致解析失败,则返回 false。
如果结果不适合 uint256 ,此函数将还原。 |
tryParseUint(string input, uint256 begin, uint256 end) → bool success, uint256 value
internalparseUint
的变体,如果由于无效字符导致解析失败,则返回 false。
如果结果不适合 uint256 ,此函数将还原。 |
parseInt(string input) → int256
internal解析十进制字符串并将该值作为 int256
返回。
要求:
- 字符串必须格式化为 [-+]?[0-9]*
- 结果必须适合 int256
类型。
parseInt(string input, uint256 begin, uint256 end) → int256
internalparseInt
的变体,它解析位于位置 begin
(包含)和end
(排除)之间的 input
的子字符串。
要求:
- 子字符串必须格式化为 [-+]?[0-9]*
- 结果必须适合 int256
类型。
tryParseInt(string input) → bool success, int256 value
internalparseInt
的变体,如果由于无效字符或结果不适合 int256
而导致解析失败,则返回 false。
如果结果的绝对值不适合 uint256 ,此函数将还原。 |
tryParseInt(string input, uint256 begin, uint256 end) → bool success, int256 value
internalparseInt
的变体,如果由于无效字符或结果不适合 int256
而导致解析失败,则返回 false。
如果结果的绝对值不适合 uint256 ,此函数将还原。 |
parseHexUint(string input) → uint256
internal解析十六进制字符串 (带有或不带有 "0x" 前缀),并将该值作为 uint256
返回。
要求:
- 字符串必须格式化为 (0x)?[0-9a-fA-F]*
- 结果必须适合 uint256
类型。
parseHexUint(string input, uint256 begin, uint256 end) → uint256
internalparseHexUint
的变体,它解析位于位置 begin
(包含)和 end
(排除)之间的 input
的子字符串。
要求:
- 子字符串必须格式化为 (0x)?[0-9a-fA-F]*
- 结果必须适合 uint256
类型。
tryParseHexUint(string input) → bool success, uint256 value
internalparseHexUint
的变体,如果由于无效字符导致解析失败,则返回 false。
如果结果不适合 uint256 ,此函数将还原。 |
tryParseHexUint(string input, uint256 begin, uint256 end) → bool success, uint256 value
internalparseHexUint
的变体,如果由于无效字符导致解析失败,则返回 false。
如果结果不适合 uint256 ,此函数将还原。 |
parseAddress(string input) → address
internal解析十六进制字符串 (带有或不带有 "0x" 前缀),并将该值作为 address
返回。
要求:
- 字符串必须格式化为 (0x)?[0-9a-fA-F]{40}
parseAddress(string input, uint256 begin, uint256 end) → address
internalparseAddress
的变体,它解析位于位置 begin
(包含) 和 end
(排除) 之间的 input
的子字符串。
要求:
- 子字符串必须格式化为 (0x)?[0-9a-fA-F]{40}
tryParseAddress(string input) → bool success, address value
internalparseAddress
的变体,如果由于输入格式不正确的地址而导致解析失败,则返回 false。 请参阅 parseAddress
要求。
tryParseAddress(string input, uint256 begin, uint256 end) → bool success, address value
internalparseAddress
的变体,如果由于输入格式不正确的地址而导致解析失败,则返回 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)
errorvalue
字符串不适合指定的 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)
errorInvalidShortString()
errorSlotDerivation
import "@openzeppelin/contracts/utils/SlotDerivation.sol";
用于从命名空间计算存储(和瞬态存储)位置并派生与标准模式对应的槽的库。 用于数组和映射的推导方法与 solidity 语言/编译器使用的存储布局匹配。
用法示例:
contract Example {
// 添加库方法
using StorageSlot for bytes32;
using SlotDerivation for bytes32;
// 声明一个命名空间
string private constant _NAMESPACE = "<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返回字符串存储指针 store
的 StringSlot
表示形式。
getBytesSlot(bytes32 slot) → struct StorageSlot.BytesSlot r
internal返回一个 BytesSlot
,其成员 value
位于 slot
。
getBytesSlot(bytes store) → struct StorageSlot.BytesSlot r
internal返回字节存储指针 store
的 BytesSlot
表示形式。
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
internalPacking
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 起可用。
函数
[extract_24_8(self, offset)
](https://docs.openzeppelin.com/contracts/5.x/api/utils#Packing-extract_24_8-bytes2- replace_28_22(self, value, offset)
错误
pack_1_1(bytes1 left, bytes1 right) → bytes2 result
internalpack_2_2(bytes2 left, bytes2 right) → bytes4 result
internalpack_2_4(bytes2 left, bytes4 right) → bytes6 result
internalpack_2_6(bytes2 left, bytes6 right) → bytes8 result
internalpack_2_8(bytes2 left, bytes8 right) → bytes10 result
internalpack_2_10(bytes2 left, bytes10 right) → bytes12 result
internalpack_2_20(bytes2 left, bytes20 right) → bytes22 result
internalpack_2_22(bytes2 left, bytes22 right) → bytes24 result
internalpack_4_2(bytes4 left, bytes2 right) → bytes6 result
internalpack_4_4(bytes4 left, bytes4 right) → bytes8 result
internalpack_4_6(bytes4 left, bytes6 right) → bytes10 result
internalpack_4_8(bytes4 left, bytes8 right) → bytes12 result
internalpack_4_12(bytes4 left, bytes12 right) → bytes16 result
internalpack_4_16(bytes4 left, bytes16 right) → bytes20 result
internalpack_4_20(bytes4 left, bytes20 right) → bytes24 result
internalpack_4_24(bytes4 left, bytes24 right) → bytes28 result
internalpack_4_28(bytes4 left, bytes28 right) → bytes32 result
internalpack_6_2(bytes6 left, bytes2 right) → bytes8 result
internalpack_6_4(bytes6 left, bytes4 right) → bytes10 result
internalpack_6_6(bytes6 left, bytes6 right) → bytes12 result
internalpack_6_10(bytes6 left, bytes10 right) → bytes16 result
internalpack_6_16(bytes6 left, bytes16 right) → bytes22 result
internalpack_6_22(bytes6 left, bytes22 right) → bytes28 result
internalpack_8_2(bytes8 left, bytes2 right) → bytes10 result
internalpack_8_4(bytes8 left, bytes4 right) → bytes12 result
internalpack_8_8(bytes8 left, bytes8 right) → bytes16 result
internalpack_8_12(bytes8 left, bytes12 right) → bytes20 result
internalpack_8_16(bytes8 left, bytes16 right) → bytes24 result
internalpack_8_20(bytes8 left, bytes20 right) → bytes28 result
internalpack_8_24(bytes8 left, bytes24 right) → bytes32 result
internalpack_10_2(bytes10 left, bytes2 right) → bytes12 result
internalpack_10_6(bytes10 left, bytes6 right) → bytes16 result
internalpack_10_10(bytes10 left, bytes10 right) → bytes20 result
internalpack_10_12(bytes10 left, bytes12 right) → bytes22 result
internalpack_10_22(bytes10 left, bytes22 right) → bytes32 result
internalpack_12_4(bytes12 left, bytes4 right) → bytes16 result
internalpack_12_8(bytes12 left, bytes8 right) → bytes20 result
internalpack_12_10(bytes12 left, bytes10 right) → bytes22 result
internalpack_12_12(bytes12 left, bytes12 right) → bytes24 result
internalpack_12_16(bytes12 left, bytes16 right) → bytes28 result
internalpack_12_20(bytes12 left, bytes20 right) → bytes32 result
internalpack_16_4(bytes16 left, bytes4 right) → bytes20 result
internalpack_16_6(bytes16 left, bytes6 right) → bytes22 result
internalpack_16_8(bytes16 left, bytes8 right) → bytes24 result
internalpack_16_12(bytes16 left, bytes12 right) → bytes28 result
internalpack_16_16(bytes16 left, bytes16 right) → bytes32 result
internalpack_20_2(bytes20 left, bytes2 right) → bytes22 result
internalpack_20_4(bytes20 left, bytes4 right) → bytes24 result
internalpack_20_8(bytes20 left, bytes8 right) → bytes28 result
internalpack_20_12(bytes20 left, bytes12 right) → bytes32 result
internalpack_22_2(bytes22 left, bytes2 right) → bytes24 result
internalpack_22_6(bytes22 left, bytes6 right) → bytes28 result
internalpack_22_10(bytes22 left, bytes10 right) → bytes32 result
internalpack_24_4(bytes24 left, bytes4 right) → bytes28 result
internalpack_24_8(bytes24 left, bytes8 right) → bytes32 result
internalpack_28_4(bytes28 left, bytes4 right) → bytes32 result
internalextract_2_1(bytes2 self, uint8 offset) → bytes1 result
internalreplace_2_1(bytes2 self, bytes1 value, uint8 offset) → bytes2 result
internalextract_4_1(bytes4 self, uint8 offset) → bytes1 result
internalreplace_4_1(bytes4 self, bytes1 value, uint8 offset) → bytes4 result
internalextract_4_2(bytes4 self, uint8 offset) → bytes2 result
internalreplace_4_2(bytes4 self, bytes2 value, uint8 offset) → bytes4 result
internalextract_6_1(bytes6 self, uint8 offset) → bytes1 result
internalreplace_6_1(bytes6 self, bytes1 value, uint8 offset) → bytes6 result
internalextract_6_2(bytes6 self, uint8 offset) → bytes2 result
internalreplace_6_2(bytes6 self, bytes2 value, uint8 offset) → bytes6 result
internalextract_6_4(bytes6 self, uint8 offset) → bytes4 result
internalreplace_6_4(bytes6 self, bytes4 value, uint8 offset) → bytes6 result
internalextract_8_1(bytes8 self, uint8 offset) → bytes1 result
internalreplace_8_1(bytes8 self, bytes1 value, uint8 offset) → bytes8 result
internalextract_8_2(bytes8 self, uint8 offset) → bytes2 result
internalreplace_8_2(bytes8 self, bytes2 value, uint8 offset) → bytes8 result
internalextract_8_4(bytes8 self, uint8 offset) → bytes4 result
internalreplace_8_4(bytes8 self, bytes4 value, uint8 offset) → bytes8 result
internalextract_8_6(bytes8 self, uint8 offset) → bytes6 result
internalreplace_8_6(bytes8 self, bytes6 value, uint8 offset) → bytes8 result
internalextract_10_1(bytes10 self, uint8 offset) → bytes1 result
internalreplace_10_1(bytes10 self, bytes1 value, uint8 offset) → bytes10 result
internalextract_10_2(bytes10 self, uint8 offset) → bytes2 result
internalreplace_10_2(bytes10 self, bytes2 value, uint8 offset) → bytes10 result
internalextract_10_4(bytes10 self, uint8 offset) → bytes4 result
internalreplace_10_4(bytes10 self, bytes4 value, uint8 offset) → bytes10 result
internalextract_10_6(bytes10 self, uint8 offset) → bytes6 result
internalreplace_10_6(bytes10 self, bytes6 value, uint8 offset) → bytes10 result
internalextract_10_8(bytes10 self, uint8 offset) → bytes8 result
internalreplace_10_8(bytes10 self, bytes8 value, uint8 offset) → bytes10 result
internalextract_12_1(bytes12 self, uint8 offset) → bytes1 result
internalreplace_12_1(bytes12 self, bytes1 value, uint8 offset) → bytes12 result
internalextract_12_2(bytes12 self, uint8 offset) → bytes2 result
internalreplace_12_2(bytes12 self, bytes2 value, uint8 offset) → bytes12 result
internalextract_12_4(bytes12 self, uint8 offset) → bytes4 result
internalreplace_12_4(bytes12 self, bytes4 value, uint8 offset) → bytes12 result
internalextract_12_6(bytes12 self, uint8 offset) → bytes6 result
internalreplace_12_6(bytes12 self, bytes6 value, uint8 offset) → bytes12 result
internalextract_12_8(bytes12 self, uint8 offset) → bytes8 result
internalreplace_12_8(bytes12 self, bytes8 value, uint8 offset) → bytes12 result
internalextract_12_10(bytes12 self, uint8 offset) → bytes10 result
internalreplace_12_10(bytes12 self, bytes10 value, uint8 offset) → bytes12 result
internalextract_16_1(bytes16 self, uint8 offset) → bytes1 result
internalreplace_16_1(bytes16 self, bytes1 value, uint8 offset) → bytes16 result
internalextract_16_2(bytes16 self, uint8 offset) → bytes2 result
internalreplace_16_2(bytes16 self, bytes2 value, uint8 offset) → bytes16 result
internalextract_16_4(bytes16 self, uint8 offset) → bytes4 result
internalreplace_16_4(bytes16 self, bytes4 value, uint8 offset) → bytes16 result
internalextract_16_6(bytes16 self, uint8 offset) → bytes6 result
internalreplace_16_6(bytes16 self, bytes6 value, uint8 offset) → bytes16 result
internalextract_16_8(bytes16 self, uint8 offset) → bytes8 result
internalreplace_16_8(bytes16 self, bytes8 value, uint8 offset) → bytes16 result
internalextract_16_10(bytes16 self, uint8 offset) → bytes10 result
internalreplace_16_10(bytes16 self, bytes10 value, uint8 offset) → bytes16 result
internalextract_16_12(bytes16 self, uint8 offset) → bytes12 result
internalreplace_16_12(bytes16 self, bytes12 value, uint8 offset) → bytes16 result
internalextract_20_1(bytes20 self, uint8 offset) → bytes1 result
internalreplace_20_1(bytes20 self, bytes1 value, uint8 offset) → bytes20 result
internalextract_20_2(bytes20 self, uint8 offset) → bytes2 result
internalreplace_20_2(bytes20 self, bytes2 value, uint8 offset) → bytes20 result
internalextract_20_4(bytes20 self, uint8 offset) → bytes4 result
internalreplace_20_4(bytes20 self, bytes4 value, uint8 offset) → bytes20 result
internalextract_20_6(bytes20 self, uint8 offset) → bytes6 result
internalreplace_20_6(bytes20 self, bytes6 value, uint8 offset) → bytes20 result
internalextract_20_8(bytes20 self, uint8 offset) → bytes8 result
internalreplace_20_8(bytes20 self, bytes8 value, uint8 offset) → bytes20 result
internalextract_20_10(bytes20 self, uint8 offset) → bytes10 result
internalreplace_20_10(bytes20 self, bytes10 value, uint8 offset) → bytes20 result
internalextract_20_12(bytes20 self, uint8 offset) → bytes12 result
internalreplace_20_12(bytes20 self, bytes12 value, uint8 offset) → bytes20 result
internalextract_20_16(bytes20 self, uint8 offset) → bytes16 result
internalreplace_20_16(bytes20 self, bytes16 value, uint8 offset) → bytes20 result
internalextract_22_1(bytes22 self, uint8 offset) → bytes1 result
internalreplace_22_1(bytes22 self, bytes1 value, uint8 offset) → bytes22 result
internalextract_22_2(bytes22 self, uint8 offset) → bytes2 result
internalreplace_22_2(bytes22 self, bytes2 value, uint8 offset) → bytes22 result
internalextract_22_4(bytes22 self, uint8 offset) → bytes4 result
internalreplace_22_4(bytes22 self, bytes4 value, uint8 offset) → bytes22 result
internalextract_22_6(bytes22 self, uint8 offset) → bytes6 result
internalreplace_22_6(bytes22 self, bytes6 value, uint8 offset) → bytes22 result
internalextract_22_8(bytes22 self, uint8 offset) → bytes8 result
internalreplace_22_8(bytes22 self, bytes8 value, uint8 offset) → bytes22 result
internalextract_22_10(bytes22 self, uint8 offset) → bytes10 result
internalreplace_22_10(bytes22 self, bytes10 value, uint8 offset) → bytes22 result
internalextract_22_12(bytes22 self, uint8 offset) → bytes12 result
internalreplace_22_12(bytes22 self, bytes12 value, uint8 offset) → bytes22 result
internalextract_22_16(bytes22 self, uint8 offset) → bytes16 result
internalreplace_22_16(bytes22 self, bytes16 value, uint8 offset) → bytes22 result
internalextract_22_20(bytes22 self, uint8 offset) → bytes20 result
internalreplace_22_20(bytes22 self, bytes20 value, uint8 offset) → bytes22 result
internalextract_24_1(bytes24 self, uint8 offset) → bytes1 result
internalreplace_24_1(bytes24 self, bytes1 value, uint8 offset) → bytes24 result
internalextract_24_2(bytes24 self, uint8 offset) → bytes2 result
internalreplace_24_2(bytes24 self, bytes2 value, uint8 offset) → bytes24 result
internalextract_24_4(bytes24 self, uint8 offset) → bytes4 result
internalreplace_24_4(bytes24 self, bytes4 value, uint8 offset) → bytes24 result
internalextract_24_6(bytes24 self, uint8 offset) → bytes6 result
internalreplace_24_6(bytes24 self, bytes6 value, uint8 offset) → bytes24 result
internalextract_24_8(bytes24 self, uint8 offset) → bytes8 result
internalreplace_24_8(bytes24 self, bytes8 value, uint8 offset) → bytes24 result
internalextract_24_10(bytes24 self, uint8 offset) → bytes10 result
internalreplace_24_10(bytes24 self, bytes10 value, uint8 offset) → bytes24 result
internalextract_24_12(bytes24 self, uint8 offset) → bytes12 result
internalreplace_24_12(bytes24 self, bytes12 value, uint8 offset) → bytes24 result
internalextract_24_16(bytes24 self, uint8 offset) → bytes16 result
internalreplace_24_16(bytes24 self, bytes16 value, uint8 offset) → bytes24 result
internalextract_24_20(bytes24 self, uint8 offset) → bytes20 result
internalreplace_24_20(bytes24 self, bytes20 value, uint8 offset) → bytes24 result
internalextract_24_22(bytes24 self, uint8 offset) → bytes22 result
internalreplace_24_22(bytes24 self, bytes22 value, uint8 offset) → bytes24 result
internalextract_28_1(bytes28 self, uint8 offset) → bytes1 result
internalreplace_28_1(bytes28 self, bytes1 value, uint8 offset) → bytes28 result
internalextract_28_2(bytes28 self, uint8 offset) → bytes2 result
internalreplace_28_2(bytes28 self, bytes2 value, uint8 offset) → bytes28 result
internalextract_28_4(bytes28 self, uint8 offset) → bytes4 result
internalreplace_28_4(bytes28 self, bytes4 value, uint8 offset) → bytes28 result
internalextract_28_6(bytes28 self, uint8 offset) → bytes6 result
internalreplace_28_6(bytes28 self, bytes6 value, uint8 offset) → bytes28 result
internalextract_28_8(bytes28 self, uint8 offset) → bytes8 result
internalreplace_28_8(bytes28 self, bytes8 value, uint8 offset) → bytes28 result
internalextract_28_10(bytes28 self, uint8 offset) → bytes10 result
internalreplace_28_10(bytes28 self, bytes10 value, uint8 offset) → bytes28 result
internalextract_28_12(bytes28 self, uint8 offset) → bytes12 result
internalreplace_28_12(bytes28 self, bytes12 value, uint8 offset) → bytes28 result
internalextract_28_16(bytes28 self, uint8 offset) → bytes16 result
internalreplace_28_16(bytes28 self, bytes16 value, uint8 offset) → bytes28 result
internalextract_28_20(bytes28 self, uint8 offset) → bytes20 result
internalreplace_28_20(bytes28 self, bytes20 value, uint8 offset) → bytes28 result
internalextract_28_22(bytes28 self, uint8 offset) → bytes22 result
internalreplace_28_22(bytes28 self, bytes22 value, uint8 offset) → bytes28 result
internalextract_28_24(bytes28 self, uint8 offset) → bytes24 result
internalreplace_28_24(bytes28 self, bytes24 value, uint8 offset) → bytes28 result
internalextract_32_1(bytes32 self, uint8 offset) → bytes1 result
internalreplace_32_1(bytes32 self, bytes1 value, uint8 offset) → bytes32 result
internalextract_32_2(bytes32 self, uint8 offset) → bytes2 result
internalreplace_32_2(bytes32 self, bytes2 value, uint8 offset) → bytes32 result
internalextract_32_4(bytes32 self, uint8 offset) → bytes4 result
internalreplace_32_4(bytes32 self, bytes4 value, uint8 offset) → bytes32 result
internalextract_32_6(bytes32 self, uint8 offset) → bytes6 result
internalreplace_32_6(bytes32 self, bytes6 value, uint8 offset) → bytes32 result
internalextract_32_8(bytes32 self, uint8 offset) → bytes8 result
internalreplace_32_8(bytes32 self, bytes8 value, uint8 offset) → bytes32 result
internalextract_32_10(bytes32 self, uint8 offset) → bytes10 result
internalreplace_32_10(bytes32 self, bytes10 value, uint8 offset) → bytes32 result
internalextract_32_12(bytes32 self, uint8 offset) → bytes12 result
internalreplace_32_12(bytes32 self, bytes12 value, uint8 offset) → bytes32 result
internalextract_32_16(bytes32 self, uint8 offset) → bytes16 result
internalreplace_32_16(bytes32 self, bytes16 value, uint8 offset) → bytes32 result
internalextract_32_20(bytes32 self, uint8 offset) → bytes20 result
internalreplace_32_20(bytes32 self, bytes20 value, uint8 offset) → bytes32 result
internalextract_32_22(bytes32 self, uint8 offset) → bytes22 result
internalreplace_32_22(bytes32 self, bytes22 value, uint8 offset) → bytes32 result
internalextract_32_24(bytes32 self, uint8 offset) → bytes24 result
internalreplace_32_24(bytes32 self, bytes24 value, uint8 offset) → bytes32 result
internalextract_32_28(bytes32 self, uint8 offset) → bytes28 result
internalreplace_32_28(bytes32 self, bytes28 value, uint8 offset) → bytes32 result
internalOutOfRangeAccess()
错误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 库进行解析。 |
- 原文链接: docs.openzeppelin.com/co...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!