Solidity:使用 Ethers.js 的 Solidity 存储变量

Solidity:使用 Ethers.js 的 Solidity 存储变量

未标题-3

img

以太坊和智能合约状态

以太坊虚拟机(EVM)上的数据使用Modified Merkle Patricia Trie数据结构进行组织。区块链上的每个区块引用4个树:[全局]状态树、存储树、交易树和接收树。状态树包含EOA(外部拥有的帐户)数据作为地址到ETH余额的映射,而智能合约数据存储在指向状态树的存储树中。

存储树中的智能合约数据表示合约的持久状态,可以通过更新全局状态的交易进行更改。在一个Solidity的智能合约中,动态变量被存在持久化的存储中。内存中初始化的任何变量都是临时的,将在执行下一次外部函数调用之前被删除。此外,无法修改的常量变量不使用存储空间,因此,使用更少的gas。

智能合约存储布局

以太坊虚拟机(EVM)中的智能合约都有自己的永久存储空间,该存储空间在键-值对的映射中包含32字节的插槽(键和值都是32字节)。

32 字节的固定大小变量

固定大小的32字节变量,如字符串、uint256和int256,会按照它们在智能合约中列出的顺序分配一个单独的存储槽。在StorageLayoutOne合约中,常量变量hello没有存储槽,因为它不能被修改。变量numOne、goodbye和num分别使用存储槽0x0、0x1和0x2。

contract StorageLayoutOne {  string constant hello = "hello world"; // no storage
  uint256 numOne = 1; // slot 0x0
  string goodbye = "goodbye world"; // slot 0x1
  int256 num; // slot 0x2}

固定大小变量< 32字节

如果可能,小于32字节的固定大小的变量将被字节打包到单个存储槽中。在StorageLayoutTwo合约中,变量lock、byteX、bytesY和bytesZ都将被打包到slot 0x0(1+1+4+16 = 22字节)中。下一个变量bytesA存储在0x1槽中,因为它不能放入前一个变量中。最后,变量bytesB和bytesC被打包到槽0x2中。

contract StorageLayoutTwo {  bool lock; // slot 0x0
  byte byteX; // slot 0x0
  bytes4 bytesY; // slot 0x0
  bytes16 bytesZ; // slot 0x0  bytes28 bytesA; // slot 0x1  bytes16 bytesB; // slot 0x2
  bytes16 bytesC; // slot 0x2}

需要注意的是,EVM 在 32 字节上运行,因此使用小于 32 字节的变量可能会由于额外的转换操作而导致更高的 gas 成本。但是,字节打包允许EVM编译器在同一个存储槽内组合对变量的多个读和写操作,来抵消这一点。因此,以最有效的方式将小于32字节的变量组合在一起,以降低总体gas成本是很重要的。

动态大小的变量

使用 keccak-256 散列算法将可能超过 32 字节的动态大小的变量(例如动态数组和映射)散列到抗碰撞存储位置,该算法伪随机地选择 2²⁵⁶ 存储槽范围内的位置。如果你想知道࿰

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值