市值: $2.8177T 0.21%
成交额(24h): $129.977B -30.15%
恐惧与贪婪指数:

28 - 恐惧

  • 市值: $2.8177T 0.21%
  • 成交额(24h): $129.977B -30.15%
  • 恐惧与贪婪指数:
  • 市值: $2.8177T 0.21%
加密货币
话题
百科
资讯
加密话题
视频
热门加密百科

选择语种

选择语种

选择货币

加密货币
话题
百科
资讯
加密话题
视频

Solidity 中的不可变变量和常量是什么?它们如何节省 Gas?

Immutable variables in Solidity are set once in the constructor and save gas by avoiding costly storage writes, while constants are compile-time literals embedded directly in bytecode for zero-cost access.

2025/11/13 04:40

了解 Solidity 中的不可变变量

1. Solidity 中的不可变变量是使用immutable关键字声明的,并且只能在合约构建期间赋值一次。一旦设置,它们的值就无法在合约的整个生命周期中更改。

2. 这些变量在部署时解析,允许编译器通过将它们放置在合约的元数据中而不是放置在用于常规状态变量的存储槽中来优化存储。

3. 由于不可变变量不占用可变存储,因此部署后无需进行 SSTORE 操作,这是以太坊中最昂贵的操作码之一。

4. 不可变变量的值通常在构造函数内分配,这使其非常适合部署时已知但同一合约的实例之间存在差异的参数。

5. 使用不可变通过表明意图来提高代码清晰度——开发人员知道某些值在部署后是固定的,从而降低了意外修改的风险。

常数在气体优化中的作用

1. 常量是使用constant关键字定义的,并且必须在声明时赋值。它们的值在编译期间被硬编码到字节码中。

2. 由于常量值直接嵌入到 EVM 指令中,因此读取它们不会产生存储访问成本,这意味着检索其值时不会执行 SLOAD 操作。

3. 任何使用常量的函数都会内联该值,从而在编译时将变量引用有效地替换为其文字值。

4. 这种内联行为减少了执行费用和合约大小,因为不需要为这些值分配或引用持久存储。

5. 常量最适合在所有部署中真正静态的值,例如计算中使用的协议参数或数学系数。

不可变和常量之间的区别

1. 虽然两者都通过避免运行时存储成本来节省gas,但常量要求在编译时知道它们的值,而不可变则允许在构造期间分配。

2. 常量不能依赖于任何输入或外部状态——它必须是编译时常量表达式,例如数字、字符串或具有常量输入的纯函数调用的结果。

3. 不可变变量提供更大的灵活性;它们可以采用构造函数参数,使不同的合约实例具有不同的值,同时仍然受益于降低的运行时成本。

4. 从gas使用的角度来看,常量通常会提供稍微更好的优化,因为它们的值在部署之前就已经完全解析,而不可变则涉及在构建期间的一次性初始化。

5. 滥用任何一种类型(例如将经常更改的值声明为不可变的值)都可能导致设计不灵活,因此正确的用例对齐至关重要。

天然气节省机制解释

1. 使用 SLOAD 从 EVM 存储中进行的每次读取至少消耗 2100 个 Gas,而访问存储在代码空间中的值(如常量)的成本接近于零。

2. 使用 SSTORE 写入存储的成本甚至更高,首次写入时花费高达 20,000 Gas,后续更新花费 5,000 Gas - 不可变在构建后完全避免了这一成本。

3. 通过将数据从存储转移到代码或构造函数初始化的内存区域,常量和不可变变量都减少了智能合约的操作足迹。

4. 严重依赖配置值(例如费用百分比、地址允许列表或代币上限)的合约在将这些值声明为常量或不可变时会显着受益。

5. 编译器优化利用这些声明来最大限度地减少冗余操作,去除不必要的检查,并生成更精简的字节码,进一步提高效率。

常见问题解答

构造函数运行后可以更改不可变变量吗?不可以。一旦在构造函数中设置了不可变变量,就无法对其进行修改。任何重新分配它的尝试都会导致编译错误。

哪些类型可以声明为常量有限制吗?是的。只有像 uint、int、bool、address 和字符串文字(有一些限制)这样的值类型可以是常量。数组和结构不能声明为常量,除非它们在内联汇编中或由较新的编译器版本处理的特殊情况。

不可变变量会增加部署 Gas 成本吗?由于构造函数逻辑,它们可能会稍微增加部署成本,但这可以通过交互过程中的长期节省来抵消。多次交易的净效应通常是总 Gas 支出的显着减少。

如果我尝试在构造函数外部分配不可变变量,会发生什么情况? Solidity 编译器会抛出错误。不可变变量的分配仅限于构造函数上下文,以确保其完整性和可预测性。

免责声明:info@kdj.com

所提供的信息并非交易建议。根据本文提供的信息进行的任何投资,kdj.com不承担任何责任。加密货币具有高波动性,强烈建议您深入研究后,谨慎投资!

如您认为本网站上使用的内容侵犯了您的版权,请立即联系我们(info@kdj.com),我们将及时删除。

相关百科

如何使用LayerZero合约执行跨链消息?

如何使用LayerZero合约执行跨链消息?

2026-01-18 13:19:39

了解 LayerZero 架构1. LayerZero 作为一种轻量级、无需许可的互操作性协议运行,无需依赖可信中介或包装资产即可实现区块链之间的通信。 2. 它利用部署在每条链上的超轻节点(ULN)来验证消息的完整性和一致性,而无需存储完整的区块链状态。 3. 核心组件包括处理消息路由的 Endp...

如何实施EIP-712进行安全签名验证?

如何实施EIP-712进行安全签名验证?

2026-01-20 22:20:26

EIP-712 概述和核心目的1. EIP-712 定义了以太坊应用程序中类型化结构化数据哈希和签名的标准。 2. 它使钱包能够在签名请求期间显示人类可读的域和消息字段,而不是原始的十六进制字符串。 3. 该规范通过域分隔符哈希引入域分离,防止跨不同 dApp 或链的签名重放。 4. 每个签名的有效...

如何通过新合约交互获得空投资格?

如何通过新合约交互获得空投资格?

2026-01-24 21:00:23

了解合约交互要求1. 大多数空投活动都要求与部署在受支持的区块链(例如以太坊、Arbitrum 或 Base)上的智能合约进行直接交互。 2. 交互通常涉及使用连接到 dApp 接口的钱包执行诸如approve() 、 stake()或mint()之类的函数。 3. 某些协议需要多种交易类型,例如将...

如何监控智能合约的安全警报?

如何监控智能合约的安全警报?

2026-01-21 07:59:57

链上监控工具1. Etherscan和Blockscout等区块链浏览器允许实时检查合约字节码、交易日志和内部调用。 2. 在信任任何链上数据之前必须确认合约验证状态——未经验证的合约存在高风险。 3. 事件日志解析可以检测异常状态变化,例如意外的代币转移或所有权修改。 4. 可以针对特定事件签名设...

如何建立自动支付合同并为其提供资金?

如何建立自动支付合同并为其提供资金?

2026-01-26 08:59:35

了解智能合约部署1. 开发者必须根据gas效率和安全性要求选择兼容的区块链平台,例如以太坊、Polygon或Arbitrum。 2. Solidity 仍然是编写支付自动化逻辑的主要语言,特别是对于定期或有条件的转账。 3. 在主网部署之前,使用 Hardhat 或 Foundry 等本地开发环境来...

如何使用 OpenZeppelin 合约构建安全的 dApp?

如何使用 OpenZeppelin 合约构建安全的 dApp?

2026-01-18 11:19:49

了解 OpenZeppelin 合约基础知识1. OpenZeppelin Contracts 是一个可重用、经过社区审核的智能合约组件库,专为以太坊和 EVM 兼容的区块链而构建。 2. 库中的每个合约都遵循严格的安全实践,包括遵守“检查-效果-交互”模式以及广泛使用访问控制修饰符。 3. 该库提...

如何使用LayerZero合约执行跨链消息?

如何使用LayerZero合约执行跨链消息?

2026-01-18 13:19:39

了解 LayerZero 架构1. LayerZero 作为一种轻量级、无需许可的互操作性协议运行,无需依赖可信中介或包装资产即可实现区块链之间的通信。 2. 它利用部署在每条链上的超轻节点(ULN)来验证消息的完整性和一致性,而无需存储完整的区块链状态。 3. 核心组件包括处理消息路由的 Endp...

如何实施EIP-712进行安全签名验证?

如何实施EIP-712进行安全签名验证?

2026-01-20 22:20:26

EIP-712 概述和核心目的1. EIP-712 定义了以太坊应用程序中类型化结构化数据哈希和签名的标准。 2. 它使钱包能够在签名请求期间显示人类可读的域和消息字段,而不是原始的十六进制字符串。 3. 该规范通过域分隔符哈希引入域分离,防止跨不同 dApp 或链的签名重放。 4. 每个签名的有效...

如何通过新合约交互获得空投资格?

如何通过新合约交互获得空投资格?

2026-01-24 21:00:23

了解合约交互要求1. 大多数空投活动都要求与部署在受支持的区块链(例如以太坊、Arbitrum 或 Base)上的智能合约进行直接交互。 2. 交互通常涉及使用连接到 dApp 接口的钱包执行诸如approve() 、 stake()或mint()之类的函数。 3. 某些协议需要多种交易类型,例如将...

如何监控智能合约的安全警报?

如何监控智能合约的安全警报?

2026-01-21 07:59:57

链上监控工具1. Etherscan和Blockscout等区块链浏览器允许实时检查合约字节码、交易日志和内部调用。 2. 在信任任何链上数据之前必须确认合约验证状态——未经验证的合约存在高风险。 3. 事件日志解析可以检测异常状态变化,例如意外的代币转移或所有权修改。 4. 可以针对特定事件签名设...

如何建立自动支付合同并为其提供资金?

如何建立自动支付合同并为其提供资金?

2026-01-26 08:59:35

了解智能合约部署1. 开发者必须根据gas效率和安全性要求选择兼容的区块链平台,例如以太坊、Polygon或Arbitrum。 2. Solidity 仍然是编写支付自动化逻辑的主要语言,特别是对于定期或有条件的转账。 3. 在主网部署之前,使用 Hardhat 或 Foundry 等本地开发环境来...

如何使用 OpenZeppelin 合约构建安全的 dApp?

如何使用 OpenZeppelin 合约构建安全的 dApp?

2026-01-18 11:19:49

了解 OpenZeppelin 合约基础知识1. OpenZeppelin Contracts 是一个可重用、经过社区审核的智能合约组件库,专为以太坊和 EVM 兼容的区块链而构建。 2. 库中的每个合约都遵循严格的安全实践,包括遵守“检查-效果-交互”模式以及广泛使用访问控制修饰符。 3. 该库提...

查看所有文章

User not found or password invalid

Your input is correct