如果 require 语句中的字符串超过 32 字节,是否保存在 2 个存储槽中?坚固性
If string in require statement is over 32 bytes is it saved in 2 storage slots? Solidity
假设我有这样的要求声明:
require(owner == msg.sender, "只有所有者可以调用这个函数 xxxxxxxxxx");
该字符串超过 32 个字节,所以我的问题是它是否存储在 2 个存储槽中。
如果字符串短于 32 字节,我们是否可以节省 gas。
谢谢
您的假设有些正确。但它并不像“每 32 个字节一个存储槽,每个槽读取 2100 个 gas 单位”那么简单。
首先,它是一个常量,所以它被包含在编译的合约字节码中(即有效地存储在多个存储槽中)。根据同一槽中此字符串之前存储的字节码数量,有时甚至短于 32 字节的字符串理论上也可以在 2 个槽之间拆分。
但是因为它是合约字节码的一部分,所以整个执行的函数被加载到内存中,字符串从内存中返回,没有任何额外的存储读取。
因此,在合约部署期间,错误消息越长开销越大(需要存储更长的字节码)。但是每次内存槽访问执行成本只会增加3个gas单位,这在大多数情况下是微不足道的。
示例 1 - 字节码 374 字节,执行 foo()
21510 gas.
pragma solidity ^0.8;
contract MyContract {
function foo() external {
require(false, "Only owner can call this function xxxxxxxxxx");
}
}
示例 2 - 字节码 322 字节,执行 foo()
21492 gas.
pragma solidity ^0.8;
contract MyContract {
function foo() external {
require(false, "no");
}
}
假设我有这样的要求声明:
require(owner == msg.sender, "只有所有者可以调用这个函数 xxxxxxxxxx");
该字符串超过 32 个字节,所以我的问题是它是否存储在 2 个存储槽中。
如果字符串短于 32 字节,我们是否可以节省 gas。
谢谢
您的假设有些正确。但它并不像“每 32 个字节一个存储槽,每个槽读取 2100 个 gas 单位”那么简单。
首先,它是一个常量,所以它被包含在编译的合约字节码中(即有效地存储在多个存储槽中)。根据同一槽中此字符串之前存储的字节码数量,有时甚至短于 32 字节的字符串理论上也可以在 2 个槽之间拆分。
但是因为它是合约字节码的一部分,所以整个执行的函数被加载到内存中,字符串从内存中返回,没有任何额外的存储读取。
因此,在合约部署期间,错误消息越长开销越大(需要存储更长的字节码)。但是每次内存槽访问执行成本只会增加3个gas单位,这在大多数情况下是微不足道的。
示例 1 - 字节码 374 字节,执行 foo()
21510 gas.
pragma solidity ^0.8;
contract MyContract {
function foo() external {
require(false, "Only owner can call this function xxxxxxxxxx");
}
}
示例 2 - 字节码 322 字节,执行 foo()
21492 gas.
pragma solidity ^0.8;
contract MyContract {
function foo() external {
require(false, "no");
}
}