区块链学习(6)-EVM有6种方式可以存储数据
  n52Qc2vwKhjY 2023年11月02日 95 0

一、在Ethereum虚拟机(EVM)中,有6种主要方式可以存储数据。这些数据存储方式具有不同的用途、特性和Gas成本。

  1. 存储(Storage):存储是EVM中永久保存数据的地方。合约的状态变量会存储在此处。对存储的读写操作相对较慢且昂贵,因为数据需要永久保存在区块链上。

storage类型的数据可以在智能合约中进行修改。storage是Ethereum区块链上永久存储数据的地方,用于保存合约的状态变量。与memorycalldata等临时存储区域不同,storage中的数据在合约的整个生命周期内保持持久化。

在Solidity智能合约中,可以通过对状态变量的赋值操作来修改storage中的数据。例如:

pragma solidity ^0.8.0;

contract SimpleStorage {
    uint256 public storedData;

    function set(uint256 x) public {
        storedData = x;
    }
}

在上面的示例中,storedData是一个uint256类型的状态变量,存储在storage中。通过调用set函数并传入一个新的值,可以更新storedData的值,从而修改storage中的数据。

需要注意的是,对storage数据的修改会消耗Gas,因为这些修改需要在区块链上永久保存。因此,在编写智能合约时,务必注意优化对storage数据的操作以降低Gas成本。在某些情况下,可以考虑使用memory或其他临时存储区域来降低Gas成本,但请注意,这些临时存储区域的数据在函数执行结束后会被丢弃。


  1. 内存(Memory):内存是EVM中临时保存数据的地方。它用于在函数执行期间存储中间变量。内存的读写操作相对较快且便宜。但在函数执行完成后,内存中的数据会被丢弃,不会永久保存。
  2. 栈(Stack):栈是EVM中另一个用于临时保存数据的地方。它用于存储局部变量和操作数。栈是一种后进先出(LIFO)的数据结构,对其进行操作非常快速且便宜。但与内存一样,栈中的数据在函数执行完成后会被丢弃。
  3. 函数调用数据(Calldata):函数调用数据是传递给合约函数的输入参数。它是只读的临时存储区,类似于内存。在EVM中,访问calldata的成本较低,但不能对其进行修改。
  4. 代码(Code):代码是EVM中存储合约字节码的地方。合约代码在部署时写入区块链,随后不可更改。访问合约代码的成本较低,但只能以只读方式访问。
  5. 日志(Logs):日志是EVM中存储事件数据的地方。当合约发出事件时,相关数据会存储在日志中。日志数据在区块链上保存,但与存储不同,日志数据不能直接从合约中访问。日志主要用于在链下读取区块链事件和数据。

在编写智能合约时,了解这些数据存储方式以及它们的特性和Gas成本非常重要。选择合适的数据存储方式可以帮助优化合约性能、降低Gas成本,并提高合约的安全性。

二、其中memory、calldata、storage是我们常用到三种,其中memory、calldata是作为零时存储的,使用完可以随时丢弃掉,不会永久保存,经常在函数传参中使用,所以结构体、数组、映射被作为函数参数时必须使用到memory、calldata作为关键修饰词,否则会报错。


三、对于永久存储我们需要区别合约中的常量,常量初始化后是无法修改的,对于其他Storage存储的变量,我们多次赋值持久话,这里每次复值操作都会有gas费即发起一次交易。

在Solidity中可以定义常量。常量是在编译时确定的值,不能在运行时进行修改。在Solidity中,可以使用constantimmutable关键字来定义常量。

  1. constantconstant关键字用于定义编译时常量。这些常量的值必须是可以在编译时计算的常量表达式。constant常量可用于定义基本类型、数组和结构体的常量值。例如:
pragma solidity ^0.8.0;

contract ConstantsExample {
    uint constant public MY_CONSTANT = 42;
    bytes32 constant public MY_HASH = keccak256("Hello, World!");
}
  1. immutableimmutable关键字用于定义部署时常量。这些常量的值可以在部署合约时设置,但在部署完成后不可更改。immutable常量只能用于定义基本类型(例如uintaddress等)的常量值。例如:
pragma solidity ^0.8.0;

contract ImmutableExample {
    uint256 public immutable myImmutableValue;

    constructor(uint256 _value) {
        myImmutableValue = _value;
    }
}

在上面的示例中,myImmutableValue是一个immutable常量,它在合约部署时通过构造函数设置。在合约部署完成后,myImmutableValue的值将不可更改。

定义常量可以帮助提高代码的可读性和可维护性,同时减少不必要的状态修改。在适当的场景下使用常量可以提高合约的性能和安全性。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
n52Qc2vwKhjY