可见性或权限控制(Visibility And Accessors)
优质
小牛编辑
136浏览
2023-12-01
Solidity有两种函数调用方式,一种是内部调用,不会创建一个EVM调用(也叫做消息调用),另一种则是外部调用,会创建EVM调用(会发起消息调用)。Solidity对函数和状态变量提供了四种可见性。分别是external
,public
,internal
,private
。其中函数默认是public
。状态变量默认的可见性是internal
。
可见性
external
:
外部函数是合约接口的一部分,所以我们可以从其它合约或通过交易来发起调用。一个外部函数f
,不能通过内部的方式来发起调用,(如f()
不可以,但可以通过this.f()
)。外部函数在接收大的数组数据时更加有效。
public
:
公开函数是合约接口的一部分,可以通过内部,或者消息来进行调用。对于public
类型的状态变量,会自动创建一个访问器(详见下文)。
internal
:
这样声明的函数和状态变量只能通过内部访问。如在当前合约中调用,或继承的合约里调用。需要注意的是不能加前缀this
,前缀this
是表示通过外部方式访问。
private
:
私有函数和状态变量仅在当前合约中可以访问,在继承的合约内,不可访问。
备注
所有在合约内的东西对外部的观察者来说都是可见,将某些东西标记为private
仅仅阻止了其它合约来进行访问和修改,但并不能阻止其它人看到相关的信息。
可见性的标识符的定义位置,对于state variable
是在类型后面,函数是在参数列表和返回关键字中间。来看一个定义的例子:
pragma solidity ^0.4.0;
contract C {
function f(uint a) private returns (uint b) { return a + 1; }
function setData(uint a) internal { data = a; }
uint public data;
}
在下面的例子中,D
可以调用c.getData()
来访问data
的值,但不能调用f
。合约E
继承自C
,所以它可以访问compute
函数。
pragma solidity ^0.4.0;
contract C {
uint private data;
function f(uint a) private returns(uint b) { return a + 1; }
function setData(uint a) { data = a; }
function getData() public returns(uint) { return data; }
function compute(uint a, uint b) internal returns (uint) { return a+b; }
}
contract D {
function readData() {
C c = new C();
uint local = c.f(7); // error: member "f" is not visible
c.setData(3);
local = c.getData();
local = c.compute(3, 5); // error: member "compute" is not visible
}
}
contract E is C {
function g() {
C c = new C();
uint val = compute(3, 5); // acces to internal member (from derivated to parent contract)
}
}