文章目录
Solidity 存储布局
1. 理论介绍
Solidity 存储布局的核心是:Solidity 存储的单位是槽,这些槽是线性排列的,在一般情况下,合约中状态变量会按照排列顺序依次存储这些槽当中。
状态变量可以分成三类:
- 第一类,是大小固定、值不固定的变量,比如:uint256, address 等。
- 第二类,是大小固定、值也固定的的变量,比如 immutable 和 constant。
- 第三类,是大小不固定、值也不固定的变量,比如:动态数组 uint256[] 和映射 mapping(address => uint256)。
在某些状态变量下,状态变量的存储槽位会发生改变。
1.1 第一类:大小固定、值也固定的状态变量
这类变量包括基本数据类型,如 uint256
, address
等。它们的值会按照其存储的顺序,依次存储在槽中。
contract FixedSizeVariable {
uint256 public value1; // 存储在槽位0
address public value2; // 存储在槽位1
}
1.2 第二类:大小固定、值也固定的状态变量
这类变量包括 immutable
和 constant
变量。immutable
变量的值会在合约创建时确定,cosntant
变量会在合约编译时确定。在整个合约生命周期中,它们都不会发生改变。
contract FixedValueVariable {
uint256 public constant VALUE = 42; // 常量,存储在字节码中
uint256 public immutable i_value; // 不可变变量,存储在字节码中
constructor(uint256 _value) {
i_value = _value; // 在构造函数中赋值
}
}
1.3 第三类:大小不固定、值也不固定的状态变量
这类变量包括动态数组和映射。它们的大小会改变,但是动态数组的长度和映射的键-值对,依然会存储在槽中。
contract DynamicSizeVariable {
uint256[] public dynamicArray; // 动态数组,长度存储在槽位 0,元素存储在哈希位置
mapping(address => uint256) public mapVar; // 映射,占据了槽位1,其键-值对存储在哈希位置
}
动态数组和映