深入理解Solidity 二

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;这一句

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447186.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VOIP简介

一、什么是VOIP VOIP全称为(VoiceOver Internet Protocol),是一种利用Internet网络进行语音通信的技术,更通俗一点说,就是IP电话。就是以IP分组交换网为传输平台,对模拟的语音信号进行编码压缩&#xff0c…

深入理解Solidity 三

Solidity函数声明和类型 函数的值类型有两类:内部(internal)类型和外部(external)类型内部函数只可以在当前合约内部被调用(即在当前代码块内,包括内部库函数和继承函数)&#xff0c…

HTTP状态代码及其定义

状态行包含HTTP版本、状态代码、与状态代码对应的简短说明信息。在大多数情况下,除了Content-Type之外的所有应答头都是可选的。但Content-Type是必需的,它描述的是后面文档的MIME类型。虽然大多数应答都包含一个文档,但也有一些不包含&#…

安装solc模块4.25版本

使用国产阿里云的cnpm 如果不知道cnpm 参考链接 安装solc模块4.25版本 npm i solc0.4.25 --save -g查看安装是否成功 可以配置软连接使用solc,我的没有配置 solcjs --version

conda关键命令

创建环境 创建名字为python3的虚拟环境,并且指定conda的python版本为3.6--name也可以缩写为-namepython3.6 是指定python的版本号,如果不指定就默认为装anaconda时python版本python3是创建的新的虚拟环境的名字,创建完,虚拟环境安装在anacon…

GDB 调试程序 详解 使用实例

用GDB调试程序 GDB概述 ———— GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化…

在pycharm中使用conda虚拟环境(conda虚拟环境是已经创建好的),解决python安装包文件很费劲的问题

查看conda的虚拟环境 使用PyCharm连接conda创建的虚拟环境,需要一个前提就是虚拟环境必须存在,使用conda env list命令查看虚拟环境列表打开PyCharm软件 打开pycharm,选择File->setting->Project:****->Project Interperter&#…

YUV测试序列下载地址

1、http://www.tkn.tu-berlin.de/research/vid/(此网站已经移走,正在寻找。) CIF: Akiyo、Bridge (far) 、Bridge (close) 、Bus 、Container 、Coastguard 、Flower 、Football 、Foreman 、Hall 、Highway 、Mobile & Calen…

flask 安装flask_resultful

命令如下 conda install -c https://conda.anaconda.org/conda-forge flask-restful

完成一个H.265/HEVC码流分析工具

经过大约一个月左右的业余时间,终于初步完成一个H.265/HEVC码流分析工具。时间包括平时的周末、晚上,以及调休的集中时间。当然,中秋回家过节不写代码。截至今天,经过多种H.265序列测试,也有各种工具对比,基…

Linux中创建用户并且配置sudo权限,百分百简单有效

配置步骤如下: 登陆或切换到root用户下;因为只有root用户才具有权限进行用户的添加,使用命令sudo su,切换为管理员用户添加用户 adduser -m youuser,并且在home路径下创建同名的用户文件夹passwd youuser,…

Java 计算两个日期之间的相差天数

代码如下 package com.data.dp;import org.apache.commons.lang3.StringUtils;import java.text.ParseException; import java.text.SimpleDateFormat;public class testDate {public static void main(String[] args) throws ParseException {SimpleDateFormat df new Simpl…

【HEVC】目前H265分析软件推荐

2014-11-14liuwri本帖最后由 zxdaemon 于 2012-12-25 04:06 PM 编辑 1,Codecvisa: http://codecian.com/国产软件,从最早的H264visa发展至今,感觉从刚开始的玩票,发展到今天专业级别的商业软件,值得支持。软…

将IPFS 配置服务器,电脑连接远程服务器,环境配置

先前安装配置的步骤省略,仅仅涉及后期的环境修改步骤 1,找到配置文件config,现需要使用命令ipfs init,从而生成.ipfs文件 ipfs init cd ~/.ipfs2,使用命令ls查看当前文件夹下面所包含的文件,正常情况小会…

Golomb及指数哥伦布编码原理介绍及实现

文章来源: https://www.cnblogs.com/wangguchangqing/p/6297792.html , 写的不错,转发出来。 2017年的第一篇博文。 本文主要有以下三部分内容: 介绍了Golomb编码,及其两个变种:Golomb-Rice和Exp-Golo…

解决ipfs 出现Error: can‘t publish while offline: pass `--allow-offline` to override的问题

原因 出现这个问题的原因是因为,ipfs未与公网上的节点相互连接,因此此时处于离线状态 使用场景 部署自己的博客,后期的改动,累计追加在同一个地址,这个地址是唯一的,也就是创建ipfs生成的ID号 步骤 1&…

HEVC 编解码资源

资料 overview 等 csvt系列详见HHI主页,适合:入门 Encoder Description 适合入门 Recommendation H.265 pdf 2016-12-22 标准文档,适合:提高;解码 High Efficiency Video Coding (HEVC): Algorithms and Architectures…

安装ipfs-http-client出现constants@0.1.2 install: node build.js > index.browser.js错误的解决办法

错误截图 原先的命令 npm install --save-dev ipfs-http-client 修改后的命令 npm install --save-dev ipfs-http-client --unsafe-permtrue --allow-root

安装ipfs-api的命令变了,最新版的命令如下

原先使用的命令安装ipfs-api npm install --save-dev ipfs-api 现在使用的命令安装ipfs-api npm install --save-dev ipfs-http-client 官方文档 参考教程 官方文档

执行truffle unbox react报错,出现Error: connect ECONNREFUSED 0.0.0.0:443问题的解决办法

前提:我是用的是MAC系统,不知道使用windows系统是否也可以 react-box 项目构建 localhost:ReactDapp liyuechun$ truffle unbox react-boxStarting unbox... ✔ Preparing to download box ✖ Downloading Unbox failed! RequestError: Error: connect…