目录

可见性或权限控制(Visibility And Accessors)

优质
小牛编辑
133浏览
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)
    }
}