目录
官方文档对calldata的描述:
Calldata is a non-modifiable, non-persistent area where function arguments are stored, and behaves mostly like memory.
翻译:Calldata是一个不可修改的、非持久化的区域,函数参数存储在这里,其行为主要类似于内存。
它只能用于函数声明参数(而不是函数逻辑)
它是不可变的(不能被覆盖和更改),调用数据避免了数据拷贝,并确保数据不被修改
它必须用于external函数的动态参数
它是临时的(该值在事务完成后会销毁)
它是最便宜的存储位置,一般建议将函数参数声明为calldata,因为gas费会比较低。
是const
外部函数的参数(不包括返回参数)被强制指定为calldata
简介:在合约中的本地内存变量。它的生命周期很短,当函数执行结束后就销毁了
简介:在合约中可以被所有函数访问的全局变量。storage是永久的存储,意味着以太坊会把它保存到公链环境里的每一个节点
pragma solidity ^0.4.24;
contract Person {
int public _age;
constructor (int age) public {
_age = age;
}
function f() public view{
modifyAge(_age);
}
function modifyAge(int age) public pure{
age = 100;
}
}
pragma solidity ^0.4.24;
contract Person {
string public _name;
constructor() public {
_name = "chenqin";
}
function f() public view{
modifyName(_name);
}
function modifyName(string name) public pure{
string memory name1 = name;
bytes(name1)[0] = 'L';
}
}
pragma solidity ^0.4.24;
contract Person {
string public _name;
string public changedName;
constructor() public {
_name = "chenqin";
}
function f() public{//不能声明为view,因为改变了状态变量
modifyName(_name);
}
function modifyName(string name) public{//不能声明为view,因为改变了状态变量
changedName = name;
bytes(name)[0] = 'L';
}
}
pragma solidity ^0.4.24;
contract Person {
string public _name;
constructor() public {
_name = "chenqin";
}
function f() public{
modifyName(_name);
}
function modifyName(string storage name) internal {
string storage name1 = name;
bytes(name1)[0] = 'L';
}
}
PS:如果modifyName函数不声明为internal会报错:这是因为形参是默认为memory类型的,这里声明为storage,那么函数的类型就必须声明为internal或者private
引申:其实在这里如果将modifyName(string)函数改成如下,也是能够成功的,因为其实没必要进行两次引用传递
function modifyName(string storage name) internal {
bytes(name)[0] = 'L';
}
pragma solidity ^0.4.24;
contract Person {
function modifyName(string name) public pure returns(string){
string memory name1 = name;
bytes(name1)[0] = 'L';
return name;
}
}
pragma solidity ^0.4.24;
contract Person {
string public _name;
constructor() public {
_name = "chenqin";
}
function f(string name) public{
_name = name//(x)
name = "ikun"(y)
}
}