Solidity变量与函数的可见性

        合约(contract)和其他语言的类(class)很类似,合约添加的变量与函数,也是使用public private等关键字来控制变量和函数是否可以被外部使用。

Counter合约的如下定义:

    uint public counter;

使用了 public 关键字, 表示 counter 是可以被公开访问的。

除 public 之外,还有几个关键字,来修饰属性与函数的可见性。

Solidity对函数和状态变量提供了4种可见性:externalpublicinternalprivate

1.状态变量可见性

状态变量有 3 种可见性:

public:

        对于 public 状态变量会自动生成一个gitter 函数。 以便其他的合约读取他们的值。 当在用一个合约里使用是,外部方式访问 (如: this.x) 会调用getter 函数,而内部方式访问 (如: x) 会直接从存储中获取值。 Setter函数则不会被生成,所以其他合约不能直接修改其值。

internal:

        内部可见性状态变量只能在它们所定义的合约和派生合同中访问。 它们不能被外部访问。 这是状态变量的默认可见性。

private:

        私有状态变量就像内部变量一样,但它们在派生合约中是不可见的。

2.函数可见性

        由于 Solidity 有两种函数调用:外部调用则会产生一个 EVM 调用,而内部调用不会, 更进一步, 函数可以确定器被内部及派生合约的可访问性,这里有 4 种可见性:

external:

        外部可见性函数作为合约接口的一部分,意味着我们可以从其他合约和交易中调用。 一个外部函数 f 不能从内部调用(即 f 不起作用,但 this.f() 可以)。

public:

        public 函数是合约接口的一部分,可以在内部或通过消息调用。

internal:

        内部可见性函数访问可以在当前合约或派生的合约访问,不可以外部访问。 由于它们没有通过合约的ABI向外部公开,它们可以接受内部可见性类型的参数:比如映射或存储引用。

private:

        private 函数和状态变量仅在当前定义它们的合约中使用,并且不能被派生合约使用。

        可见性标识符的定义位置,对于状态变量来说是在类型后面,对于函数是在参数列表和返回关键字中间。

pragma solidity  >=0.6.0 <0.9.0;

contract C {
    function f(uint a) private pure 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.16 <0.9.0;

contract C {
    uint private data;

    function f(uint a) private returns(uint b) { 
        return a + 1; 
    }
    function setData(uint a) public { 
        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() public {
        C c = new C();
        uint local = c.f(7); // 错误:成员 `f` 不可见,private
        c.setData(3);
        local = c.getData();
        local = c.compute(3, 5); // 错误:成员 `compute` 不可见
    }
}

contract E is C {
    function g() public {
        C c = new C();
        uint val = compute(3, 5); // 访问内部成员(从继承合约访问父合约成员)
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值