solidity基础 -- 存储类型

        在Solidity智能合约开发中,存储类型是一个至关重要的概念。它不仅影响合约的性能,还决定了数据的存储位置和生命周期。Solidity提供了三种主要的存储类型:storagememorycalldata。本文将结合给定的代码示例,并通过更多实例详细介绍 这三种储存类型的区别。

  • storage:用于合约状态变量,数据持久保存在区块链上,对其修改会影响合约的长期状态。
  • memory:用于局部变量,仅在函数执行期间存在,函数结束后数据消失,可修改,但不会影响 storage 中的数据。
  • calldata:专门用于函数参数,是只读的,存储在调用数据中,在函数执行期间不可变。

 

1. Storage:状态变量与持久化存储

        storage是Solidity中最持久的存储类型,它用于存储合约的状态变量。这些变量会永久存储在区块链上,直到被显式修改或删除。storage变量的生命周期与合约的生命周期相同,这意味着它们在合约部署后一直存在。

        在我们的示例合约中,myStructs是一个storage类型的映射,它存储了每个地址对应的MyStruct结构体。当我们通过myStructs[msg.sender]访问或修改它时,实际上是在操作区块链上的持久化数据。

myStructs[msg.sender] = MyStruct({foo: 123, text: "bar"});

        这行代码将一个MyStruct实例存储到myStructs映射中,它会永久保存在区块链上,直到被覆盖或删除。

使用场景

  • 存储合约的状态变量,如用户余额、配置参数等。

  • 在函数中引用和修改状态变量。

注意事项

  • storage变量的读写操作成本较高,因为它们需要与区块链交互。

  • 修改storage变量会消耗更多的Gas。

2. Memory:临时存储与局部变量

        memory是Solidity中用于临时存储数据的存储类型。它用于存储函数内部的局部变量,这些变量仅在函数执行期间存在,函数执行结束后,存储在memory中的数据会被销毁。

        在示例合约中,readOnly是一个memory类型的变量,它是myStructs[msg.sender]的一个副本。对readOnly的修改不会影响原始的storage变量:

MyStruct memory readOnly = myStructs[msg.sender];
readOnly.foo = 456;

这行代码将myStructs[msg.sender]的内容复制到memory中,并修改了副本的foo属性。然而,这个修改不会反映到链上的storage变量中。

使用场景

  • 存储函数内部的临时变量。

  • 创建数据的副本进行操作,而不影响原始数据。

注意事项

  • memory变量的生命周期仅限于函数执行期间。

  • 创建memory变量需要消耗Gas,但比storage操作更高效。

3. Calldata:函数参数的只读存储

        calldata是Solidity中一种特殊的存储类型,它用于存储函数的输入参数。calldata变量是只读的,不能被修改。它们存储在内存中,但与memory不同,calldata变量不能被分配或重新赋值。

在示例合约中,yscalldata类型的参数:

function examples(uint[] calldata y, string calldata s) external returns (uint[] memory)

这行代码声明了两个calldata参数。y是一个uint数组,s是一个字符串。这些参数在函数调用时由调用者提供,并且在函数内部只能被读取,不能被修改。

使用场景

  • 存储函数的输入参数。

  • 用于传递大量数据,如数组或结构体,而不需要复制到memory

注意事项

  • calldata变量是只读的,不能被修改。

  • calldata变量不能被分配或重新赋值。

 

4.示例合约:DataLocations

在我们开始之前,先来看一个简单的Solidity合约,它展示了这三种存储类型的使用:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract DataLocations {struct MyStruct {uint foo;string text;}mapping (address => MyStruct) public myStructs;function examples(uint[] calldata y, string calldata s) external returns (uint[] memory) {myStructs[msg.sender] = MyStruct({foo: 123, text: "bar"});MyStruct storage myStruct = myStructs[msg.sender];myStruct.text = "foo";// 修改存储在`storage`中的状态变量MyStruct memory readOnly = myStructs[msg.sender];readOnly.foo = 456;// 修改存储在`memory`中的副本,不影响链上数据_internal(y);uint[] memory memArr = new uint[](3);memArr[0] = 234;return memArr;}function _internal(uint[] calldata y) private {uint x = y[0];}
}

其他实例:深入理解存储类型

为了进一步理解这三种存储类型的区别,我们再来看一个简单的示例合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract StorageTypes {uint public storageVar = 10; // 存储在`storage`中的状态变量function example() public pure returns (uint memoryVar) {uint memory memoryVar = 20; // 存储在`memory`中的局部变量return memoryVar;}function example2(uint calldataVar) public pure returns (uint) {return calldataVar; // `calldata`变量,只读}
}

总结

  • storage:用于合约状态变量,数据持久保存在区块链上,对其修改会影响合约的长期状态。
  • memory:用于局部变量,仅在函数执行期间存在,函数结束后数据消失,可修改,但不会影响 storage 中的数据。
  • calldata:专门用于函数参数,是只读的,存储在调用数据中,在函数执行期间不可变。

        通过深入理解这三种储存类型的区别,开发者可以更好地优化智能合约的性能和资源使用,确保合约的正确性和稳定性。

 

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

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

相关文章

鸿蒙参考文档和问题记录

本文用于记录鸿蒙使用过程中的问题和相关参考文档 问题记录 1. 兼容性测试套件问题 ActsStartAbilityForResultNoTargetBundleListStageTest套件测试失败:模块FreeInstall 技术资料 1. HarmonyOS应用如何打包HAP并安装到真机 HarmonyOS应用如何打包HAP并安装到真…

NewStar CTF week1 web wp

谢谢皮蛋 做这题之前需要先去学习一些数据库的知识 1 order by 2 1可以理解为输入的id,是一个占位符,按第二列排序用来测试列数,如果没有两列则会报错-1 union select 1,2 -1同样是占位符,union的作用是将注入语句合并到原始语句…

3.CSS的背景

通过CSS背景属性,可以给页面元素添加背景样式。 背景属性可以设置背景颜色、背景图片、背景平铺、背景图片位置、背景图像固定等。 3.1 背景颜色 background-color属性定义了元素的背景颜色 background-color:颜色值; 一般情况下元素背景颜色默认值…

登录认证(4):令牌技术:JWT令牌

如上文所说(登录认证(1):登录的基本逻辑及实现思路登录),因为 HTTP协议是无状态的协议,我们需要使用会话跟踪技术实现同一会话中不同请求之间的数据共享,但Cookie技术和Session技术都…

2025.1.20——二、buuctf BUU UPLOAD COURSE 1 1 文件上传

题目来源:buuctf BUU UPLOAD COURSE 1 1 目录 一、打开靶机,查看信息 二、解题思路 step 1:上传一句话木马.php文件康康回显 step 2:蚁剑连接 三、小结 一、打开靶机,查看信息 这里提示到了文件会被上传到./uplo…

【玩转全栈】----Django制作部门管理页面

目录 大致效果 BootStrap BootStrap简介 BootStrap配置 BootStrap使用 基本配置 部分代码解释及注意: 用户编辑: 新添数据: 删除数据: 大致效果 我先给个大致效果,基本融合了Django、Bootstrap、css、html等等。 基于D…

新年好(Dijkstra+dfs/全排列)

1135. 新年好 - AcWing题库 思路: 1.先预处理出1,a,b,c,d,e到其他点的单源最短路,也就是进行6次Dijkstra 2.计算以1为起点的这6个数的全排列,哪种排列方式所得距离最小,也可以使用dfs 1.Dijkstradfs #define int long longusing …

Golang之Context详解

引言 之前对context的了解比较浅薄,只知道它是用来传递上下文信息的对象; 对于Context本身的存储、类型认识比较少。 最近又正好在业务代码中发现一种用法:在每个协程中都会复制一份新的局部context对象,想探究下这种写法在性能…

AIGC浪潮下,图文内容社区数据指标体系如何构建?

文章目录 01 案例:以图文内容社区为例实践数据指标体构建02 4个步骤实现数据指标体系构建1. 明确业务目标,梳理北极星指标2. 梳理业务流程,明确过程指标3. 指标下钻分级,构建多层级数据指标体系4. 添加分析维度,构建完…

数据结构:二叉树

目录 一、树型结构 1、基本概念 2、重要概念 3、树的表示形式 二、二叉树 1、概念 2、两种特殊的二叉树 3、二叉树的性质 4、二叉树的存储 5、二叉树的遍历 二叉树的构建 (1)前序遍历 (2)中序遍历 (3&am…

SpringBoot项目中的异常处理

定义错误页面 SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制。一旦程序中出现了异常 SpringBoot 会像/error 的 url 发送请求。在 springBoot 中提供了一个叫 BasicExceptionController 来处理/error 请求,然后跳转到…

《安富莱嵌入式周报》第349期:VSCode正式支持Matlab调试,DIY录音室级麦克风,开源流体吊坠,物联网在军工领域的应用,Unicode字符压缩解压

周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版: 《安富莱嵌入式周报》第349期:VSCode正式支持Matlab调试,DIY录音室级麦克风…

C++priority_queue模拟实现

Cpriority_queue模拟实现 1.priority_queue基本概念2.priority_queue基本结构3.size()成员函数4.empty()成员函数5.top()成员函数6.push()成员函数7.pop()成员函数8.构造函数9.完整代码 🌟🌟hello,各位读者大大们你们好呀🌟&#…

[STM32 HAL库]串口中断编程思路

一、前言 最近在准备蓝桥杯比赛(嵌入式赛道),研究了以下串口空闲中断DMA接收不定长的数据,感觉这个方法的接收效率很高,十分好用。方法配置都成功了,但是有一个点需要进行考虑,就是一般我们需要…

嵌入式 工程配置

本次用的STM32F4芯片系列 目录 1. 新建文件夹 2. 新建文件夹下创建 3. 打开keil5 3.1.1 点击菜单栏project 点击new project 3.1.2. 选择刚刚新建的文件夹 3.1.3.将项目文件保存到Project文件夹里 3.1.4. 将项目命名这里命名为STM32 保存 3.1.5. 保存好后会跳出选择芯…

我的图形布局 组织结构图布局

组织结构图布局,有的人也叫它树状布局,在图形中是经常用到的布局算法.形成类似如下图的图形布局方式 首先创建一个类, public class TreeLayouter {private int m_space 40;/// <summary>/// 空间间隔/// </summary>public int Space{get { return m_space; }se…

计算机网络介质访问控制全攻略:从信道划分到协议详解!!!

一、信道划分介质访问控制 介质访问控制&#xff1a;多个节点共享同一个“总线型”广播信道时&#xff0c;可能发生“信号冲突” 应该怎么控制各节点对传输介质的访问&#xff0c;才能减少冲突&#xff0c;甚至避免冲突? 时分复用(TDM) 时分复用&#xff1a;将时间分为等长的“…

sql主从同步

今天给大家介绍两种mysql的主从同步方式&#xff1a;第一种是基于binlogzhu主从同步&#xff1b;第二种就是基于gtid的主从同步方式。 首先给大家介绍一下什么是sql的主从复制。 主从复制&#xff1a; 通过将MySQL的某一台主机&#xff08;master&#xff09;的数据复制到其…

计算机组成原理——数据表示(二)

当生活的压力和困惑缠绕在身边&#xff0c;我们往往需要振奋精神&#xff0c;勇往直前。无论在何种困境中&#xff0c;我们都要保持积极的态度和坚定的信念。将悲观的情绪抛之脑后&#xff0c;展现出坚强的意志力和无尽的活力。振奋精神意味着我们要战胜自己内心的负面情绪&…

Spring Boot整合Thymeleaf、JDBC Template与MyBatis配置详解

本文将详细介绍如何在Spring Boot项目中整合Thymeleaf模板引擎、JDBC Template和MyBatis&#xff0c;涵盖YAML配置、依赖版本匹配、项目结构设计及代码示例。 一、版本兼容性说明 Spring Boot版本与Java版本对应关系 Spring Boot 2.x&#xff1a;支持Java 8、11&#xff08;推…