Solidity 变量
Solidity 变量 Solidity 特殊变量 Solidity 变量默认值 Solidity 变量作用域 Solidity 常量Solidity 运算符
Solidity 运算符 Solidity 算术运算符 Solidity 比较运算符 Solidity 逻辑运算符 Solidity 位运算符 Solidity 赋值运算符 Solidity 条件运算符Solidity 条件语句
Solidity 条件语句 Solidity if语句 Solidity if…else 语句 Solidity if…else ifSolidity 循环语句
Solidity 循环语句 Solidity while 循环 Solidity do 循环 Solidity for 循环 break 与 continueSolidity 复杂数据
Solidity 字符串 Solidity 数组 Solidity 结构体 Solidity 映射 Solidity 枚举 Solidity 类型转换Solidity 数据位置
Solidity 数据位置 Solidity 变量数据位置 Solidity 赋值数据位置Solidity 函数
Solidity 函数 Solidity 函数返回值 Solidity pure函数 Solidity view函数 Solidity 构造函数 solidity 函数修改器 Solidity 函数重载 Solidity 数学函数 Solidity 加密函数Solidity 进阶编程
Solidity 事件 Solidity 不可变量 Solidity 日志 Solidity 继承 Solidity 多重继承 多重继承的构造函数 Solidity 调用父类函数 Solidity 异常处理 Solidity 编程风格 Solidity 访问权限 Solidity 存储位置 Solidity 引用类型 Solidity 值类型 Solidity 值类型与引用类型 Solidity 合约结构 Solidity 编写智能合约 Solidity delete Solidity 0.6 重大变化 Solidity transfer 转账 Solidity transfer send Solidity 单位 Solidity constant Solidity this & sender Solidity address Solidity 众筹智能合约 Solidity interface solidity gas使用模式 Solidity 常见编译错误 Solidity 调用合约 Solidity 支付Eth Solidity fallback Solidity receive Solidty 钱包合约 Solidity 发送Eth Solidity 自毁合约 Solidity 哈希算法 Solidity 工厂合约 Solidity 库合约 Solidity 权限控制合约 Solidity 验证签名Solidity 变量
Solidity 变量 Solidity 特殊变量 Solidity 变量默认值 Solidity 变量作用域 Solidity 常量Solidity 运算符
Solidity 运算符 Solidity 算术运算符 Solidity 比较运算符 Solidity 逻辑运算符 Solidity 位运算符 Solidity 赋值运算符 Solidity 条件运算符Solidity 条件语句
Solidity 条件语句 Solidity if语句 Solidity if…else 语句 Solidity if…else ifSolidity 循环语句
Solidity 循环语句 Solidity while 循环 Solidity do 循环 Solidity for 循环 break 与 continueSolidity 复杂数据
Solidity 字符串 Solidity 数组 Solidity 结构体 Solidity 映射 Solidity 枚举 Solidity 类型转换Solidity 数据位置
Solidity 数据位置 Solidity 变量数据位置 Solidity 赋值数据位置Solidity 函数
Solidity 函数 Solidity 函数返回值 Solidity pure函数 Solidity view函数 Solidity 构造函数 solidity 函数修改器 Solidity 函数重载 Solidity 数学函数 Solidity 加密函数Solidity 进阶编程
Solidity 事件 Solidity 不可变量 Solidity 日志 Solidity 继承 Solidity 多重继承 多重继承的构造函数 Solidity 调用父类函数 Solidity 异常处理 Solidity 编程风格 Solidity 访问权限 Solidity 存储位置 Solidity 引用类型 Solidity 值类型 Solidity 值类型与引用类型 Solidity 合约结构 Solidity 编写智能合约 Solidity delete Solidity 0.6 重大变化 Solidity transfer 转账 Solidity transfer send Solidity 单位 Solidity constant Solidity this & sender Solidity address Solidity 众筹智能合约 Solidity interface solidity gas使用模式 Solidity 常见编译错误 Solidity 调用合约 Solidity 支付Eth Solidity fallback Solidity receive Solidty 钱包合约 Solidity 发送Eth Solidity 自毁合约 Solidity 哈希算法 Solidity 工厂合约 Solidity 库合约 Solidity 权限控制合约 Solidity 验证签名Solidity 数据位置(data location)
1. 引用类型/复合数据类型
Solidity中,有一些数据类型由简单数据类型组合而成,相比于简单的值类型,这些类型通常通过名称引用,被称为引用类型,
引用类型包括:
- 数组 (字符串与bytes是特殊的数组,所以也是引用类型)
- struct (结构体)
- map (映射)
这些类型涉及到的数据量较大,复制它们可能要消耗大量Gas,非常昂贵,所以使用它们时,必须考虑存储位置。例如,是保存在内存中,还是在 EVM 存储区中。
2. 数据位置(data location)
在合约中声明和使用的变量都有一个数据位置,指明变量值应该存储在哪里。合约变量的数据位置将会影响Gas消耗量。
Solidity 提供 3 种类型的数据位置。
- storage
- memory
- calldata
1) storage
存储位置 storage 用来存储永久数据,可以被合约中的所有函数访问。
storage 变量,通常用于存储智能合约的状态变量,它在函数调用之间保持持久性。
storage 与其他数据位置相比,成本较高。
我们可以把它理解为计算机的硬盘数据,所有数据都永久存储。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SoldityTest {
struct MyData {
uint id;
string value;
}
MyData[] public myData;
constructor(){
myData.push(MyData(1, "value1"));
myData.push(MyData(2, "value2"));
}
function operations() external{
// storage 存储位置
MyData storage d = myData[0];
// 修改状态变量myData的内容
d.value = "new value";
}
}
合约 SoldityTest 部署后,调用 operations 方法,状态变量 myData 的数据被修改,其中 myData[0].value 变为 "new value"。
2) memory
存储位置 memory 用来存储临时数据,比 storage 便宜。
memory 变量,通常用于保存临时变量,以便在函数执行期间进行计算。一旦函数执行完毕,它的内容就会被丢弃。它只能在所在的函数中访问。
我们可以把它理解为每个单独函数的内存 RAM。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SoldityTest {
struct MyData {
uint id;
string value;
}
MyData[] public myData;
constructor(){
myData.push(MyData(1, "value1"));
myData.push(MyData(2, "value2"));
}
function operations() external{
// memory 存储位置
MyData memory d = myData[0];
// 修改状态变量myData的内容
d.value = "new value";
}
}
合约 SoldityTest 部署后,调用 operations 方法,状态变量 myData 的数据未被修改,其中 myData[0].value 仍然为 "value1"。
3) calldata
calldata 是不可修改的非持久性数据位置,类似于 memory,但只能出现在函数的输入参数位置。
外部函数 external function 的传入参数强制为 calldata 类型。
使用 calldata 的好处是在内部函数中作为输入参数传递时,省掉了数据拷贝的成本,节省 gas 费。memory 作为参数时,需要进行数据拷贝。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SoldityTest {
function operations(string calldata val) pure external{
// 使用 calldata 传递参数,省却复制成本
internalFunc1(val);
// 使用 memory 传递参数,需要进行复制
internalFunc2(val);
}
function internalFunc1(string calldata val) internal pure {
// ......
}
function internalFunc2(string memory val) internal pure {
// ......
}
}
下一章:Solidity 变量的数据位置规则
1. 规则1 – 状态变量状态变量总是存储在存储区中。// SPDX-License-Identifier: MITpragma solidity ^0.8.0;contract ...
AI 中文社