calldata memory storage 区别详细讲解

首先明确一点 calldata memory storage 都是用来修饰饮用类型的。

强制指定的数据位置:
    •    外部函数(就是说使用external关键字的函数)的参数(不包括返回参数): calldata,效果跟 memory 差不多
    •    状态变量: storage
默认数据位置:
    •    函数参数(包括返回参数): memory
    •    所有其它局部变量: storage

Solidity变量的数据存储位置

现在让我们回到memory关键字。从0.5.0版本开始,所有的复杂类型必须 显式指定其存储的数据位置,有三种可选的数据位置:memory、storage 和calldata。

注意:唯一可以省略数据位置声明的是状态变量,因为状态变量始终保存 在账号的存储中。

storage/存储

  • 存储中的数据是永久存在的。存储是一个key/value库
  • 存储中的数据写入区块链,因此会修改状态,这也是存储使用成本高的原因。
  • 占用一个256位的槽需要消耗20000 gas
  • 修改一个已经使用的存储槽的值,需要消耗5000 gas
  • 当清零一个存储槽时,会返还一定数量的gas
  • 存储按256位的槽位分配,即使没有完全使用一个槽位,也需要支付其开销

memory/内存

  • 内存是一个字节数组,槽大小位256位(32字节)
  • 数据仅在函数执行期间存在,执行完毕后就被销毁
  • 读或写一个内存槽都会消耗3gas
  • 为了避免矿工的工作量过大,22个操作之后的单操作成本会上涨

calldata/调用数据

  • 调用数据是不可修改、非持久化的区域,用来保存函数参数,其行为类似于内存
  • 外部函数的参数必须使用calldata,但是也可用于其他变量
  • 调用数据避免了数据拷贝,并确保数据不被修改
  • 函数也可以返回使用calldata声明的数组和结果,但是不可能分配这些类型

Storage 变量是指永久存储在区块链中的变量。 Memory 变量则是临时的,当外部函数对某合约调用完成时,内存型变量即被移除。

状态变量(在函数之外声明的变量)默认为“storage”形式,并永久写入区块链;而在函数内部声明的变量默认是“memory”型的,它们函数调用结束后消失。

处理函数内的结构体和数组的时候需要指定数据的类型是 storage 还是 memory。

扫描二维码关注公众号,回复: 14221312 查看本文章

猜你喜欢

转载自blog.csdn.net/bareape/article/details/123798916