本文内容包括 Solidity 语言的状态变量可见性、函数可见性和 Getter 函数。由于 Solidity 有两种函数调用(内部调用不会产生实际的 EVM 调用或称为“消息调用”,而外部调用则会产生一个 EVM 调用), 函数和状态变量有四种可见性类型。 函数可以指定为 external
,public
,internal
或者 private
。 对于状态变量,不能设置为 external
,默认是 internal
。
public
公共状态变量与内部状态变量的不同之处在于,编译器会自动为它们生成 getter 函数,从而允许其他合约读取它们的值。当在同一个合约中使用时,外部访问 (例如 this.x
) 调用 getter,而内部访问 (例如 x
) 直接从存储中获取变量值。Setter 函数不会生成,因此其他合约不能直接修改它们的值。
internal
内部状态变量只能从定义它们的合约和派生合约中访问。外部无法访问它们。这是状态变量的默认可见级别。
private
私有状态变量与内部状态变量类似,但在派生合约中不可见。
将某些内容设置为 private
或 internal
只能防止其他合约读取或修改该信息,但它仍然对区块链以外的整个世界可见。
Solidity 有两种函数调用:创建实际 EVM 消息调用的外部函数调用和不创建实际 EVM 消息调用的内部函数调用。此外,派生合约无法访问内部函数。这就产生了四种类型的函数可见性。
external
外部函数是合约接口的一部分,这意味着可以从其他合约或通过事务调用它们。外部函数 f
不能在内部调用 (即 f()
不能工作,但 this.f()
可以工作)。
public
公共函数是合约接口的一部分,可以在内部调用,也可以通过消息调用。
internal
内部函数只能从当前合约或从当前合约派生的合约中访问,外部无法访问它们。由于它们没有通过合约的 ABI 向外部公开,所以它们可以接受内部类型的参数,比如映射或存储引用。
private
私有函数类似于内部函数,但它们在派生合约中不可见。
将某些内容设置为 private
或 internal
只能防止其他合约读取或修改该信息,但它仍然对区块链以外的整个世界可见。
可见性说明符在状态变量的类型之后以及函数的参数列表和返回参数列表之间给出。
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 =0.4.16 =0.4.16 =0.4.0 =0.4.16 =0.4.0 uint) map;
uint[3] c;
uint[] d;
bytes e;
}
mapping (uint => mapping(bool => Data[])) public data;
}
它生成如下形式的函数。省略结构中的映射和数组 (字节数组除外),因为没有好的方法来选择单个结构成员或为映射提供一个键:
function data(uint arg1, bool arg2, uint arg3)
public
returns (uint a, bytes3 b, bytes memory e)
{
a = data[arg1][arg2][arg3].a;
b = data[arg1][arg2][arg3].b;
e = data[arg1][arg2][arg3].e;
}