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:专门用于函数参数,是只读的,存储在调用数据中,在函数执行期间不可变。

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

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Titans: 学习在测试时记忆 - 论文解读与总结

论文地址:https://arxiv.org/pdf/2501.00663v1 本文介绍了一篇由 Google Research 发表的关于新型神经网络架构 Titans 的论文,该架构旨在解决传统 Transformer 在处理长序列时的局限性。以下是对论文的详细解读,并结合原文图片进行说明&…

账号IP属地:依据手机号还是网络环境?

在数字化生活中,账号的IP属地信息往往成为我们关注的一个焦点。无论是出于安全考虑,还是为了满足某些特定服务的需求,了解账号IP属地的确定方式都显得尤为重要。那么,账号IP属地根据手机号还是网络来确定的呢?本文将深…

微信小程序实现自定义日历功能

文章目录 1. 创建日历组件实现步骤:2. 代码实现过程3. 实现效果图4. 关于作者其它项目视频教程介绍 1. 创建日历组件实现步骤: 创建日历组件:首先,你需要创建一个日历组件,包含显示日期的逻辑。样式设计:为…

YOLOv9改进,YOLOv9检测头融合RFAConv卷积,适合目标检测、分割任务

摘要 空间注意力已广泛应用于提升卷积神经网络(CNN)的性能,但它存在一定的局限性。作者提出了一个新的视角,认为空间注意力机制本质上解决了卷积核参数共享的问题。然而,空间注意力生成的注意力图信息对于大尺寸卷积核来说是不足够的。因此,提出了一种新型的注意力机制—…

【机器学习】深入无监督学习分裂型层次聚类的原理、算法结构与数学基础全方位解读,深度揭示其如何在数据空间中构建层次化聚类结构

🌟个人主页:落叶 🌟当前专栏: 机器学习专栏 目录 引言 分裂型层次聚类(Divisive Hierarchical Clustering) 1. 基本原理 2. 分裂型层次聚类的算法步骤 Step 1: 初始化 Step 2: 选择分裂的簇 Step 3: 执行分裂操作…

VirtualBox can‘t enable the AMD-V extension

个人博客地址:VirtualBox cant enable the AMD-V extension | 一张假钞的真实世界 最近一次完成Deepin的系统更新后,进入VirtualBox创建的虚拟机(Widows10)时,出现以下错误: 根据网址“https://askubuntu.…

[JavaScript] 数组与对象详解

文章目录 数组(Array)什么是数组数组的常用操作**访问数组元素****修改数组元素****数组的长度****添加和删除元素** 常用数组方法map():filter():reduce():**其他实用方法** 对象(Object)什么是对象对象的基本操作**访问属性****…

“模板”格式化发布新创诗(为《诗意 2 0 2 5》贡献力量)

预置MarkDown&Html文本,脚本读取f-string模板完成录入嵌套。 (笔记模板由python脚本于2025-01-22 19:19:58创建,本篇笔记适合喜欢分享的达人的coder翻阅) 【学习的细节是欢悦的历程】 博客的核心价值:在于输出思考与经验,而不…

论文速读|Multi-Modal Disordered Representation Learning Network for TBPS.AAAI24

论文地址:Multi-Modal Disordered Representation Learning Network for Description-Based Person Search 代码地址:未开源(2025.01.22) bib引用: inproceedings{yang2024multi,title{Multi-Modal Disordered Repres…

计算机视觉算法实战——实体物体跟踪

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​​​​​ ​ 1. 领域介绍✨✨ 实体物体跟踪(Object Tracking)是计算机视觉领域中的一个重要研究方向&#x…

C++17 新特性深入解析:constexpr 扩展、if constexpr 和 constexpr lambda

C17 不仅增强了现有特性,还引入了一些全新的编程工具,极大地提升了代码的效率和表达力。在这篇文章中,我们将深入探讨 C17 中与 constexpr 相关的三个重要特性:constexpr 的扩展用法、if constexpr 和 constexpr lambda。这些特性…

IVR:交互式语音应答系统解析及其应用

引言 IVR(Interactive Voice Response),即交互式语音应答系统,是一种功能强大的电话自动服务系统。它通过语音识别和按键反馈,使用户与系统之间实现实时交互,为用户提供自助服务、咨询、报告、投诉等多种功…

Observability:最大化可观察性 AI 助手体验的 5 大提示(prompts)

作者:来自 Elastic Zoia_AUBRY 在过去三年担任客户工程师期间,我遇到了数百名客户,他们最常问的问题之一是:“我的数据在 Elastic 中;我该如何利用它获得最大优势?”。 如果这适用于你,那么本…

【Vim Masterclass 笔记25】S10L45:Vim 多窗口的常用操作方法及相关注意事项

文章目录 S10L45 Working with Multiple Windows1 水平分割窗口2 在水平分割的新窗口中显示其它文件内容3 垂直分割窗口4 窗口的关闭5 在同一窗口水平拆分出多个窗口6 关闭其余窗口7 让四个文件呈田字形排列8 光标在多窗口中的定位9 调节子窗口的尺寸大小10 变换子窗口的位置11…

STM32_SD卡的SDIO通信_基础读写

本篇将使用CubeMXKeil, 创建一个SD卡读写的工程。 目录 一、SD卡要点速读 二、SDIO要点速读 三、SD卡座接线原理图 四、CubeMX新建工程 五、CubeMX 生成 SD卡的SDIO通信部分 六、Keil 编辑工程代码 七、实验效果 一、SD卡 速读 SD卡,全称Secure Digital M…

大模型GUI系列论文阅读 DAY2续:《一个具备规划、长上下文理解和程序合成能力的真实世界Web代理》

摘要 预训练的大语言模型(LLMs)近年来在自主网页自动化方面实现了更好的泛化能力和样本效率。然而,在真实世界的网站上,其性能仍然受到以下问题的影响:(1) 开放领域的复杂性,(2) 有限的上下文长度&#xff…

【ESP32】ESP32连接JY61P并通过WIFI发送给电脑

前言 手头上有个ESP32&#xff0c;发现有wifi功能&#xff0c;希望连接JY61P并通过WIFI把姿态数据发送给电脑 1.采用Arduino IDE编译器&#xff1b;需要安装ESP32的开发板管理器&#xff1b; 2.电脑接受数据是基于python的&#xff1b; 1. ESP32 连接手机WIFI #include <…

C语言程序设计十大排序—冒泡排序

文章目录 1.概念✅2.冒泡排序&#x1f388;3.代码实现✅3.1 直接写✨3.2 函数✨ 4.总结✅ 1.概念✅ 排序是数据处理的基本操作之一&#xff0c;每次算法竞赛都很多题目用到排序。排序算法是计算机科学中基础且常用的算法&#xff0c;排序后的数据更易于处理和查找。在计算机发展…

【Elasticsearch】腾讯云安装Elasticsearch

Elasticsearch 认识Elasticsearch安装Elasticsearch安装Kibana安装IK分词器分词器的作用是什么&#xff1f;IK分词器有几种模式&#xff1f;IK分词器如何拓展词条&#xff1f;如何停用词条&#xff1f; 认识Elasticsearch Elasticsearch的官方网站如下 Elasticsearch官网 Ela…

Django学习笔记(安装和环境配置)-01

Django学习笔记(安装和环境配置)-01 一、创建python环境 1、可以通过安装Anaconda来创建一个python环境 # 创建一个虚拟python环境 conda create -n django python3.8 # 切换激活到创建的环境中 activate django2、安装django # 进入虚拟环境中安装django框架 pip install …