Solidity 存储位置 memory,storage,calldata
引用类型在 Solidity 中数据有一个额外的属性:存储位置,可选项为 memory 和 storage。
- memory:存储在内存中,即分配、即使用,越过作用域则不可访问,等待被回收。
- storage:永久存储在以太坊区块链中,更具体地说存储在存储 Merkle Patricia 树中,形成帐户状态信息的一部分。一旦使用这个类型,数据将永远存在。
- calldata:存储函数参数,它是只读的,不会永久存储的一个数据位置。外部函数的参数被强制指定为 calldata,效果与 memory 类似。
1. 强制的数据位置
外部函数 (external function) 的参数强制为:calldata。
状态变量强制为: storage。
pragma solidity ^0.8.0; contract StateVariable{ struct S{
string a;
uint b;
}
//状态变量,默认是 storage S s; }
2. 默认数据位置
函数参数,返回参数:memory。
局部变量:storage。
pragma solidity ^0.8.0; contract SimpleAssign{
struct S{
string a;
uint b;
}
function assign(S s) internal{
// 函数参数默认是 memory 类型,即 s 是 memory 类型 // 局部变量默认 storage 类型 // S tmp = s; 报错 } }
这里将一个memory类型的参数赋值给storage类型的局部变量会报错。
3. 转换问题
3.1 storage–>storage
把一个storage类型赋值给一个 storage 类型时,只是修改其指针(引用传递)。
pragma solidity ^0.8.0; contract StorageToStorageTest{ struct S{string a;uint b;}
//默认是storage的 S s; function storageTest(S storage s) internal{ S test = s; test.a = "Test"; }
function call() returns (string){ storageTest(s); return s.a; //Test }
}
3.2 memory–>storage
分为 2 种情况:
a. 将 memory–>状态变量; 即将内存中的变量拷贝到存储中(值传递)
pragma solidity ^0.8.0; contract StorageToStorageTest{ struct S{string a;uint b;}
//默认是storage S s; function storageTest(S s) internal{ s = s; s.a = "Test"; }
function call() returns (string){ storageTest(s); return s.a; } }
b.将memeory–>局部变量 报错
3.storage–>memory:即将数据从storage拷贝到memory中
pragma solidity ^0.4.0; contract StorageToMemory{ struct S{string a;uint b;} S s = S("storage", 1); function storageToMemory(S storage x) internal{ S memory tmp = x;//由Storage拷贝到memory中 //memory的修改不影响storage tmp.a = "Test"; } function call() returns (string){ storageToMemory(s); return s.a;//storage } }
4.memory–>memory 和storage转storage一样是引用传递
pragma solidity ^0.4.0; contract MemoryToMemory{ struct S{string a;uint b;} function smemoryTest(S s) internal{ S memory test = s; test.a = "Test"; } function call() returns (string){ //默认是storage的 S memory s = S("memory",10); smemoryTest(s); return s.a;//Test } }
本章节主要介绍 solidity 中引用类型的属性和注意点,引用类型包括: 可变字节数组,数组,结构体。1. 可变字节数组string:是一个动态尺寸的utf-8编码字符串,他其实是一个特殊的可变字节数组,同时其 ...