-
bitcoin $87959.907984 USD
1.34% -
ethereum $2920.497338 USD
3.04% -
tether $0.999775 USD
0.00% -
xrp $2.237324 USD
8.12% -
bnb $860.243768 USD
0.90% -
solana $138.089498 USD
5.43% -
usd-coin $0.999807 USD
0.01% -
tron $0.272801 USD
-1.53% -
dogecoin $0.150904 USD
2.96% -
cardano $0.421635 USD
1.97% -
hyperliquid $32.152445 USD
2.23% -
bitcoin-cash $533.301069 USD
-1.94% -
chainlink $12.953417 USD
2.68% -
unus-sed-leo $9.535951 USD
0.73% -
zcash $521.483386 USD
-2.87%
阵列存储在 Solidity 中如何工作以及其成本是多少?
Dynamic arrays in Solidity store length in a slot, with elements placed at `keccak256(slot) + index`, ensuring deterministic, collision-free storage.
2025/11/23 11:59
了解 Solidity 中的数组存储
1. Solidity 中的数组存储在合约存储中,该存储在函数调用和交易之间是持久的。当声明动态数组时,例如uint[] public value ,分配给数组的槽仅保存数组的长度。实际数据元素存储在阵列槽号的 keccak256 散列中,从而实现安全且确定的位置映射。
2. 数组中的每个元素都放置在由公式keccak256(slot) + index导出的存储槽中。这种机制保证了即使合约中存在多个数组,它们的数据也不会发生冲突。由于以太坊存储是 256 位对齐的,因此每个槽可以容纳一个完整的 uint256 或同等大小的值。较大的类型可能跨越多个插槽。
3. 对于固定大小的数组,编译器从声明的变量位置开始保留连续的存储槽。像uint[3] ids这样的固定数组恰好使用三个相邻的槽。由于大小在编译时已知,因此不会存储长度等元数据,这使得访问更直接,并且在燃料方面稍微便宜一些。
4. 嵌套数组显着增加了复杂性。二维动态数组使用相同的哈希方法计算基位置,然后根据内部数组索引应用偏移量。由于读取或写入期间的多级散列和增加的 SLOAD 操作,访问模式变得更加昂贵。
5. 如果可能,将值打包到结构中或使用较小的整数类型(例如,uint128 而不是 uint256),以允许多个变量适合单个存储槽。这减少了使用的时隙总数,并降低了涉及这些变量的部署和状态修改的 Gas 成本。
与阵列操作相关的 Gas 成本
1. 通过push()追加到动态数组会产生一定的成本,具体取决于添加的元素是零还是非零。如果存储的值非零,则在设置先前的空槽时,会导致 SSTORE 操作的 Gas 成本为 20,000。根据 EIP-1283 规则,假设槽已包含数据,后续非零值的覆盖将花费 5,000 个 Gas。
2. 从数组中读取元素会触发 SLOAD 操作,每次访问消耗 2,100 Gas。在链上逻辑中应避免对大型数组进行频繁迭代,因为每次读取都会增加此基本成本。链下索引服务更适合检索完整数据集。
3. 动态数组本质上不支持删除元素,除非实现手动移位。调用pop()会删除最后一项,并在清理存储槽时退还 15,000 个 Gas,从而激励清理未使用的状态。然而,从中间删除项目需要移动所有后续元素,导致 O(n) 计算和高 Gas 使用量。
4. 在合同创建期间初始化大型阵列会大大增加部署成本。每个预设值都会消耗存储初始化气体。将数组初始化为空并通过用户交互逐渐填充它们通常会更有效,从而将成本分散到多个事务中。
5. 函数内临时使用的内存阵列不会写入持久存储,从而完全避免 SSTORE 成本。这些非常适合中间计算,但无法保留事务范围之外的数据。在将选择性结果写入存储之前使用内存阵列进行批处理可以优化整体效率。
高效阵列使用的优化技术
1. 当需要通过密钥进行随机访问时,优先选择映射而不是数组。像映射(uint =>地址)这样的映射提供恒定时间的查找,而无需迭代或管理长度的开销。映射还消除了对索引范围和调整大小的担忧。
2. 谨慎地对单个数组元素使用delete。手动将元素设置为零可能比依赖删除更便宜,尤其是在不适用退款的情况下。为了完全清理,重复调用 pop() 直到数组为空可以最大限度地从已清理的存储槽中退款。
3. 限制数组内容的链上暴露。使用数组数据发出事件允许外部系统重建状态,而无需直接从存储中读取。事件的成本低于永久存储写入,并支持通过索引参数进行过滤。
4. 针对追加繁重的工作负载实施检查点或链表模式。通过仅存储条目之间的增量或引用,合约减少了冗余数据存储并最大限度地减少了昂贵的重组。这种方法非常适合跟踪历史状态或用户活动日志。
5. 谨慎利用汇编级优化。内联 Yul 代码可以比高级 Solidity 构造更快地计算存储位置,但会带来寻址不正确的风险。只有高级开发人员才应该尝试低级存储操作,以确保跨不同编译器版本进行彻底测试。
常见问题解答
当访问越界数组索引时会发生什么?访问当前数组长度之外的索引会触发无效的操作码,消耗所有剩余的气体并恢复交易。在访问之前,必须在代码中显式处理边界检查。
数组可以作为参数在合约之间传递吗?是的,数组可以在内部和外部函数调用中传递。 Calldata 数组对于大型输入非常有效,因为它们避免了复制到内存中。外部接口需要ABI编码,支持静态和动态类型。
动态数组的增长大小是否有限制?理论限制受到可用气体和区块大小限制的约束。实际的限制包括追加和迭代的成本不断上升。在链上处理过大的数组时,合约有达到交易 Gas 限制的风险。
空数组声明会消耗存储空间吗?声明一个数组而不初始化它会将其长度设置为零并占用一个存储槽。在添加元素之前不会分配额外的槽。这种最小的占用空间使得未初始化的阵列对于延迟填充来说具有成本效益。
免责声明:info@kdj.com
所提供的信息并非交易建议。根据本文提供的信息进行的任何投资,kdj.com不承担任何责任。加密货币具有高波动性,强烈建议您深入研究后,谨慎投资!
如您认为本网站上使用的内容侵犯了您的版权,请立即联系我们(info@kdj.com),我们将及时删除。
- 比特币、eCash 分叉和空投动态:深入探讨加密货币的最新争议
- 2026-05-03 12:55:01
- 2026 年迈阿密共识:Web3、区块链、加密货币、NFT、Metaverse,会议,5 月 5 日 — 华尔街与数字前沿相遇的地方
- 2026-05-02 12:45:01
- 美联储维持利率稳定,地缘政治紧张局势引发比特币价格下跌
- 2026-05-01 06:45:01
- 比特币矿工为电网供电:收购俄亥俄州天然气厂开启数字黄金新时代
- 2026-05-01 00:45:01
- MegaETH的MEGA代币登陆纽约:为实时区块链设定新的性能基准
- 2026-05-01 00:55:01
- Solana 的滑坡:价格预测表明阻力损失和潜在的进一步下跌
- 2026-05-01 06:45:01
相关百科
AVAX 期货保证金要求是如何计算的?
2026-07-23 15:40:03
AVAX 期货保证金结构1. AVAX期货保证金由两个不同的部分组成:初始保证金和维持保证金。这些是根据当前市场价格、波动性、未平仓合约和合约规模实时计算的。 2. 初始保证金作为履约保证金,以弥补短期(通常是一个交易时段)内潜在的不利价格变动。它以头寸名义价值的百分比表示。 3. 维持保证金设置为...
ADA合约保证金率为何会触发警告?
2026-07-22 09:00:26
ADA 合约保证金比率机制1. 各大交易所的ADA永续合约采用根据持仓规模、杠杆水平和当前标记价格实时计算的动态保证金比例。 2. 保证金比率等于(钱包余额+未实现盈亏)除以维持保证金要求,以百分比表示。 3. 当该比率低于交易所定义的维持阈值(通常为 5% 至 10%,具体取决于杠杆率)时,系统将...
ADAUSDT永续合约资金费率是多少?
2026-07-24 20:19:46
ADAUSDT永续合约资金费率定义及目的1. ADAUSDT永续合约资金费率是卡尔达诺(ADA)与主要加密货币交易所Tether(USDT)衍生品头寸之间采用的定期费用兑换机制。 2. 作为价格锚定工具,确保ADAUSDT永续合约价格与基础ADA/USDT现货指数价格保持紧密一致。 3、与传统期货不...
TON 期货强平价格公式是什么?
2026-07-23 09:19:45
TON 期货强平机制1. 当交易者的保证金余额低于交易所设定的维持保证金要求时,TON 期货就会被清算。 2、保证金比例低于或等于100%时,系统自动触发强制平仓,计算公式为(可用保证金/所需保证金)×100%。 3. 强平价格不是固定的,它会随着市场走势、头寸规模、杠杆水平和资金费率的调整而动态变...
SUI期货杠杆如何影响强平?
2026-07-22 09:59:59
SUI 期货保证金机制1、主要衍生品交易所的SUI期货合约根据持仓规模和市场波动情况实行分级初始保证金要求。对于名义价值低于 50,000 美元的头寸,标准初始保证金设置为 8%,而较大头寸则可逐步调整至 15%。 2. 所有合约规模的维持保证金固定为初始保证金水平的 65%,这意味着当净值相对于当...
SUI永续合约的安全保证金比例是多少?
2026-07-24 14:00:09
市场波动模式1. 自2023年1月以来,Bitcoin超过68%的交易日在24小时窗口内价格波动超过15%。 2. 当以分钟级回报的标准差来衡量时,以太坊始终表现出比 Solana 或 Cardano 等主要山寨币更高的日内波动性。 3.衍生品市场表现出放大的敏感性——在清算级联期间,币安和Bybi...
AVAX 期货保证金要求是如何计算的?
2026-07-23 15:40:03
AVAX 期货保证金结构1. AVAX期货保证金由两个不同的部分组成:初始保证金和维持保证金。这些是根据当前市场价格、波动性、未平仓合约和合约规模实时计算的。 2. 初始保证金作为履约保证金,以弥补短期(通常是一个交易时段)内潜在的不利价格变动。它以头寸名义价值的百分比表示。 3. 维持保证金设置为...
ADA合约保证金率为何会触发警告?
2026-07-22 09:00:26
ADA 合约保证金比率机制1. 各大交易所的ADA永续合约采用根据持仓规模、杠杆水平和当前标记价格实时计算的动态保证金比例。 2. 保证金比率等于(钱包余额+未实现盈亏)除以维持保证金要求,以百分比表示。 3. 当该比率低于交易所定义的维持阈值(通常为 5% 至 10%,具体取决于杠杆率)时,系统将...
ADAUSDT永续合约资金费率是多少?
2026-07-24 20:19:46
ADAUSDT永续合约资金费率定义及目的1. ADAUSDT永续合约资金费率是卡尔达诺(ADA)与主要加密货币交易所Tether(USDT)衍生品头寸之间采用的定期费用兑换机制。 2. 作为价格锚定工具,确保ADAUSDT永续合约价格与基础ADA/USDT现货指数价格保持紧密一致。 3、与传统期货不...
TON 期货强平价格公式是什么?
2026-07-23 09:19:45
TON 期货强平机制1. 当交易者的保证金余额低于交易所设定的维持保证金要求时,TON 期货就会被清算。 2、保证金比例低于或等于100%时,系统自动触发强制平仓,计算公式为(可用保证金/所需保证金)×100%。 3. 强平价格不是固定的,它会随着市场走势、头寸规模、杠杆水平和资金费率的调整而动态变...
SUI期货杠杆如何影响强平?
2026-07-22 09:59:59
SUI 期货保证金机制1、主要衍生品交易所的SUI期货合约根据持仓规模和市场波动情况实行分级初始保证金要求。对于名义价值低于 50,000 美元的头寸,标准初始保证金设置为 8%,而较大头寸则可逐步调整至 15%。 2. 所有合约规模的维持保证金固定为初始保证金水平的 65%,这意味着当净值相对于当...
SUI永续合约的安全保证金比例是多少?
2026-07-24 14:00:09
市场波动模式1. 自2023年1月以来,Bitcoin超过68%的交易日在24小时窗口内价格波动超过15%。 2. 当以分钟级回报的标准差来衡量时,以太坊始终表现出比 Solana 或 Cardano 等主要山寨币更高的日内波动性。 3.衍生品市场表现出放大的敏感性——在清算级联期间,币安和Bybi...
查看所有文章














