当前位置:   article > 正文

智能合约状态变量的存储体现_智能合约变量类型

智能合约变量类型

存储规则

智能合约的所有状态变量 - 或持久性变量 - 都驻留在合约的存储中。合约的存储是一个大型数组,组织成大小为32字节(256位)的槽,每个槽由一个唯一的索引标识,范围从0到$2^{256}-1$。对于每个给定的状态变量,存储槽索引必须以确定性的方式计算,以确保对存储数据的一致访问。事实上,这种存储槽中状态变量的布局由编译器确定,编译器考虑源代码中变量的声明顺序(Solidity 编译器为例)。

固定大小的变量类型。基本类型,如uint(32字节)、地址(20字节)和布尔值(1字节)以连续的方式存储在32字节的槽中,从槽0x0开始。值得注意的是,需要少于32字节的多个连续项被打包到单个存储槽中以节省空间,根据以下规则进行打包:

  • 存储槽中的第一项始终与到最低有效字节对齐。
  • 固定大小的类型仅使用所需的字节来存储它们。
  • 如果变量不适合存储槽的剩余部分,则将其存储在下一个存储槽中。

动态大小的变量类型。动态类型,如数组和映射,始终存储在新的槽中(基槽),它们的元素根据以下规则存储:

  • 基槽存储数组的长度,或者在映射的情况下,它被留空。
  • 每个数组元素(具有索引:INDEX)存储在槽keccak256(BASE)+INDEX中。
  • 映射的每个元素(具有键:KEY)存储在通过连接KEY和BASE并将结果值用作keccak256函数的输入计算得到的槽中(即,keccak256(KEY.BASE))。

注意

状态变量在存储中的位置是通过声明状态变量来分配空间的(占坑的)。

通过简单合约举例:

  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.0;
  3. struct Values {
  4. uint8 a;
  5. address b;
  6. bytes4 c;
  7. }
  8. contract Test {
  9. Values value;
  10. uint8 balance;
  11. bytes4 data;
  12. address addr;
  13. uint8[] uint8Array;
  14. mapping(address => uint256) isMapping;
  15. constructor(){
  16. balance = 8;
  17. addr = 0x358AA13c52544ECCEF6B0ADD0f801012ADAD5eE3;
  18. uint8Array.push(1);
  19. uint8Array.push(2);
  20. isMapping [addr] = 123;
  21. }
  22. }

Values结构体总体大小为25字节大小,第一个声明Values value;占用 Slot 0 这个坑,哪怕没对value进行赋值。

balance占用8字节,因此无法完全存储在slot 0 剩余大小的空间中,因此balance开始存储在slot 1的低位。data占用4字节,存储在slot 1中,而addr占用20字节,也存储在slot 1中。在构造函数中,被赋值的只有balanceaddr

slot1 在remix调试显示结果是:

可以看到两个被赋值的没有紧挨在一起存储,因为中间4字节被data声明给占坑了。

规则中数组和映射基槽都占用一整个32字节的 slot 作为基槽。

uint8Array的基槽就是 slot 2,keccak256(BASE)哈希计算出要存储的slot位置,将元素按keccak256(BASE)+INDEX要求存入。

在mapping中,keccak256(KEY.BASE)在EVM中的实现是通过执行keccak256操作码来完成的。这个操作码会消耗堆栈中的两个元素:stack(0)中的值表示要读取的内存起始位置,stack(1)中的值表示要读取字节的大小。

具体来说,memory(0)中缓存的是addr的值,而memory(1)中缓存的是基槽slot 3的值。然后,EVM会读取这两个值连接起来的64字节数据(memory(0)的32字节 + memory(1)的32字节),并对连接后的值进行哈希计算。

执行完后,isMapping [addr] = 123在storage中的体现是:

如果有任何错误,请指正。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/784113
推荐阅读
相关标签
  

闽ICP备14008679号