4. 智能合约中的存储方式

前面我们学习了智能合约的编写和部署,还学习了 Solidity 的基本数据类型,今天我们需要学习智能合约中的存储方式。

这一章和其他语言略有区别,不能算作内存管理。

一、Solidity 中的存储方式

Solidity 中的存储方式 一共有 6 种:

  1. storage 永久性
  2. memory 暂时性
  3. calldata 暂时行
  4. stack
  5. codes
  6. logs

所有你在 Solidity 中声明的变量、函数调用传入的、代码本身等所有数据都存储在这 6 种当中。

二、 存储方式的分类

以上 6 种存储方式分为两类:

  1. 永久性存储
  2. 暂时性存储

2.1 永久性

永久性是指永久存在于区块链上,无论何时我来访问,他都是一个固定的值,除非我手动更新它。

注意:智能合约的私有属性例( 不是声明在方法内部的变量)如前面的 boolVar、strVal 等都是永久性存储,但是不允许显式的声明。

2.2 暂时性

暂时性:只在函数运行时可以拿到的,例如函数实参等,一旦交易执行完成后,这个变量就被释放掉了的例如 memory、calldata

举例子:把上面 setHelloWorld 中的 string 后面的 memory 修改为 calldata 编译器不报错,但是有啥区别呢?

java 复制代码
pragma solidity ^0.8.20;

contract HelloWorld {


    bytes32 varChar = 'hello world';


    string strVar = 'hello world';


    function sayHello () public view returns(string memory) {
    
        return addinfo(strVar);

    }



    function setHelloWorld(string memory newString) public {
        strVar = newString;

    }

  

    function addinfo(string memory helloWorld) internal pure returns(string memory) {

        return string.concat(helloWorld, " from Frank's concat.");

    }


    function setHelloWorld2(string calldata newString) public {

        // newString = "Hi world";

        // 把存储类型修改为 calldata 后给 newString 重新赋值,

        // 编译器报错:from solidity: TypeError: Type literal_string "Hi world" is not implicitly convertible to expected type string calldata.

        strVar = newString;

    }

}

三、memory vs calldta

同样都为临时存储,那么 memory 和 calldata 有什么区别呢?又该如何选择呢?

memory vs calldata 辨析: calldata 在运行时不允许修改,而存储在 memory 是可以修改(重新赋值)

四、总结:

  1. 如果你的数据不希望被修改,就声明成 storage,如果是暂时例如函数入参就声明成 calldata 或者 memory。如果你的入参会被重新赋值就选择 memory,否则选择 calldata

  2. storage/memory/calldata 存储类型声明主要针对的是数组、Mapping、Struct 等数据结构的,基础数据类型如 uint、bytes、int 等基础数据类型默认 memory或者calldata 。这是因为编译器足够智能,可以识别简单数据类型,但是例如 string(string在智能合约中认为是bytes数组),如果声明了复杂的数据结构是临时性存储,需要显式的声明存储类型,告知编译器。

  3. 在课程官方仓库中提供了更多数据存储类型在 EVM 的底层是怎么实现的,有兴趣的可以去看看。

相关推荐
xfchsjh1 天前
科技赋能空间,河北保定廊坊沧州艺术设计公司解锁展厅价值新高度
科技·设计·艺术·展厅设计·展馆设计·科技展厅设计·数字展厅设计
天若有情6734 天前
详解Two Pair函数:「一次握手,一次挥手」,让函数调用更严谨、更安全
网络·c++·后端·安全·设计
小杨同学497 天前
C 语言实战:超市水果结算系统(深度解析与优化)
后端·算法·设计
晚风予星10 天前
简记 | 一个基于 AntD 的高效 useDrawer Hooks
前端·react.js·设计
一线大码10 天前
服务端架构的演进与设计
后端·架构·设计
用户79519727308512 天前
AI可编辑架构图!这个 8.2k stars 的项目如何把 30 分钟的绘图工作压缩到 30 秒
设计
金銀銅鐵13 天前
From Nand to Tetris 里的 Project 5 (Memory 部分)
设计
xrczsjq14 天前
深圳河北北京展馆设计公司-2026用数字科技创意雕琢空间灵魂
科技·设计·艺术·展厅设计·展馆设计·科技展厅设计·数字展厅设计
航Hang*16 天前
第五章:综合布线技术 —— 管理间(电信间)设计与施工
网络·笔记·学习·设计·光纤
航Hang*16 天前
第八章:综合布线技术 —— 进线间和建筑群子系统设计
网络·笔记·学习·设计·期末·光纤