Solidity数据位置

  • 所有复杂的数据类型,即数组、结构和映射类型,都会有一个额外属性“数据位置”,用来指定数据的存储位置,即数据是存储在memory还是存储在storage里面
  • 根据上下文环境,IDE会自动指定数据的默认存储位置,但是也可以通过在类型名字之后添加关键字stirage或者memory进行修改
  • 函数参数(包括返回的参数)的数据位置默认是memory,局部变量的数据存储位置默认是storage,状态变量的数据位置强制是storage
  • 另外还有第三种数据存储位置,calldata,这个是一块只读的,不会永久存储的位置,用来存储函数的参数。外部函数的参数(非返回函数)的数据位置会被强制指定为calldata,效果和memory差不多。

数据位置总结

强制

  • 外部函数的参数(不包括返回的参数):calldata
  • 状态变量:storage默认存储位置

可变

  • 函数参数(包括返回参数):memory
  • 引用类型的局部变量:storage,例,动态数组使用哈希表,要求很大的存储空间,遍历key和value是可能的,防止哈希碰撞。
  • 值类型的局部变量:栈(stack)

特别要求

  • 公开可见(publicly visible)的函数参数一定是memory类型,如果要求是storage类型,则必须是private或者internal函数。这个的目的是为了防止公开调用占用资源。
  • memory和storage只要数据类型一致,就可以互相传数值。如果是memory传给storage,是对于数据的完整拷贝传过去,不是简简单单的引用。同样是storage,如果是状态变量就会改写原先内容,相当于拷贝,存储到永久性区间里面。如果是局部变量,不管对方是状态变量还是局部变量都是引用

例子

  • 讲解
  • 类型之间都是storage,那么就是引用,如果类型不同,就是复制然后操作。uint[] storage d是一个引用,相当于C语言中的指针,指向data1和data2
  • 函数参数默认是memory,需要将其改成stroage类型
  • 将public改成internal类型,防止公开调用,占用大量的资源
  • 代码
pragma solidity ^0.4.0;
contract C{uint[] public data1;uint[] public data2;function append1() public {append(data1);}function append2() public {append(data2);}function append(uint[] storage d)internal{d.push(23);}
}
  • 界面

纠错(1)

代码

pragma solidity ^0.4.0;
contract C{uint  public a;uint[] public data;function f() public {uint[] storage x;x.push(2);data=x;}
}

界面

问题

  • a变成了一个计数器,这个是Solidity的缺陷,原因在于uint[] storage x;它是一个指针,如果没有赋值,默认指定合约地址的整个存储空间的0位置,也就是uint public a 的位置。

  • uint[] storage x,指向变量a。每次调用f函数,x 的长度就会增加,并且将存储的长度存储在变量a上,因此每次a的数值每次增加1.

  • 如果修改代码如下

pragma solidity ^0.4.0;
contract C{uint  public a=23;uint[] public data;function g(uint input)public{a = input;}function f() public {uint[] storage x;x.push(2);data=x;}
}
  • 首先取a的值,为23,点击f函数,再点击a,得到a变成24,24之前的数据不可以访问,但是24是存储的2,由代码x.push(2)来完成。g函数也是一样的效果。

修正

  • 给uint[] storage x;初始化指定默认位置,比如改成uint[] x = data;x.push(2);删除data = x;这一句

深入理解Solidity 二相关推荐

  1. faster rcnn源码理解(二)之AnchorTargetLayer(网络中的rpn_data)

    转载自:faster rcnn源码理解(二)之AnchorTargetLayer(网络中的rpn_data) - 野孩子的专栏 - 博客频道 - CSDN.NET http://blog.csdn.n ...

  2. AQS理解之二,自己设计一个锁

    AQS理解之二,自己设计一个锁 一,实现锁的条件 首先我们想一想,如果我们自己实现一个类似于java中的锁,我们可能需要哪些必要的东西: 1,记录是哪个线程持有了锁. 2,如果有一个变量代表加锁,A线 ...

  3. 设计模式理解(二)创建型——单例、原型

    设计模式理解(二)单例(Singleton)与原型(Prototype) 为什么一起写,因为懒.... 单例,就是用了面向对象语言的一些奇技淫巧,把构造函数私有了,然后用一个自身类型的静态指针作为全局 ...

  4. Docker的一些理解(二)

    Docker的一些理解(二) 百度百科 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上 ...

  5. 本质安全设备标准(IEC60079-11)的理解(二)

    本质安全设备标准(IEC60079-11)的理解(二) 十,本安设备的测试 我们知道如何测试本安设备以及一些基本概念后, 现在需要进一步说明: (1),本安设备的测试和一般软件,硬件的测试是完全不同的 ...

  6. SVPWM算法理解(二)——关于非零基本矢量幅值和线电压幅值的解释

    SVPWM算法理解(二)--关于非零基本矢量幅值和线电压幅值的解释 1 引言 2 非零基本矢量的幅值 3 线电压的幅值 4 电压空间矢量图中的图形含义 5 如何保证逆变器的输出电压不失真 1 引言   ...

  7. DFT - 对芯片测试的理解(二) 详解

    DFT - 对芯片测试的理解(二) 详解 参考: https://www.docin.com/p-2014360649.html The basic view of DFT scan chain 这图 ...

  8. 通信系统中对眼图的理解(二)

    中文名称: 眼图 英文名称: eye diagram;eye pattern 定义: 示波器屏幕上所显示的数字通信符号,由许多波形部分重叠形成,其形状类似"眼"的图形." ...

  9. 对CAS机制的理解(二)

    一.Java当中CAS的底层实现 首先看看AtomicInteger的源码,AtomicInteger中常用的自增方法 incrementAndGet: public final int increm ...

最新文章

  1. 为什么AI的翻译水平还远不能和人类相比?
  2. React总结篇之十_动画
  3. 老而不死的三种编程语言!
  4. swift optionals - 1
  5. 浅析Mysql InnoDB存储引擎事务原理
  6. Oracle 配置监听和本地网络服务
  7. 农产品加工进销存单_农产品进销存ERP—物资的内部腾挪转换也是交易的一种形式...
  8. 如何从我的虚拟环境中更新pip本身?
  9. Layui数据表格动态禁用checkbox
  10. 数字图像处理matlab蔡利梅,数字图像处理:使用MATLAB分析与实现:using MATLAB
  11. SPICE 协议 USB 重定向
  12. 关于Froala Editor的简单使用
  13. CWaitCursor 光标设置为沙漏形状
  14. 在线旅游中需要上传获取那些信息,对接旅行社护照录入系统
  15. win10 更新计算机时间,win10电脑时间不能自动更新
  16. pkl形式的数据集读取和可视化
  17. 10电脑睡眠后自动关机怎么回事 win_win10电脑睡眠变关机怎么解决_win10睡眠变自动关机的处理方法-系统城...
  18. Vue ElementUI el-scrollbar 嵌套 el-tree 出现横向纵向滚动条
  19. UEFI Boot Flow 系列之 SEC Phase
  20. 【RS-Attack】攻击MF:Data Poisoning Attacks on Factorization-Based Collaborative Filtering (NIPS‘16)

热门文章

  1. nginx离线安装_web高可用-基于keepalived和nginx
  2. 对python生态系统的认识_SAS,R与Python的区别详细对比
  3. UML之用例图(use case)箭头方向
  4. 使用Linq时出现Row not found or changed. Linq 找不到行或行已更改的解决办法
  5. Java对象模型-oop和klass
  6. Oracle:ORA-28000异常(帐户已被锁定),修改账号登录失败次数
  7. 对分查找的最多次数_「剑指offer题解」数组中出现次数超过一半的数字
  8. php隐藏webshell_PHP 安全的十个必备技巧
  9. java中的并发类_java中并发常用工具类
  10. 【PAT甲级最新题解】PAT甲级2020.7月春季考试满分题解(附代码)