20.Visibility

函数和状态变量必须声明它们是否可以被其他合约访问。 函数可以声明为:

image-20231007135128817

  • public - 任何合约和账户都可以调用 ,可以从合约内外访问。
  • private - 仅在定义该函数的合约内部 ,只能从当前合约访问。
  • internal - 仅在继承了internal函数的合约内部 ,只能从当前合约或从继承合约访问。
  • external - 仅其他合约和账户可以调用,仅可从合约外部访问。这个修饰符只能用于函数

状态变量可以声明为public、private或internal,但不能声明为external。

在Solidity中,publicexternal是两种不同的函数修饰符,它们有以下区别:

  • public:使用public修饰符标记的函数可以从合约内外访问。这意味着它们可以在合约内部调用,也可以在合约外部通过合约地址调用。如果函数返回一个值,则该值将作为事务的一部分返回给调用方。如果函数没有返回值,则调用方只能确定事务是否成功。
  • external:使用external修饰符标记的函数只能从合约外部访问。这个修饰符只能用于函数。这意味着它们不能在合约内部直接调用,而必须通过合约地址调用。如果函数返回一个值,则该值将作为事务的一部分返回给调用方。如果函数没有返回值,则调用方只能确定事务是否成功。

因此,publicexternal的主要区别在于它们是否可以在合约内部直接调用。如果函数需要在合约内部调用,则应该使用public修饰符。如果函数只需要从合约外部调用,则应该使用external修饰符。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;

contract Base {
    // Private function 只能在合约内部调用,子合约也不能调用
    function privateFunc() private pure returns (string memory) {
        return "private function called";
    }

    function testPrivateFunc() public pure returns (string memory) {
        return privateFunc();
    }

    // Internal function can be called, 可以被子合约继承
    function internalFunc() internal pure returns (string memory) {
        return "internal function called";
    }

    function testInternalFunc() public pure virtual returns (string memory) {
        return internalFunc();
    }

    // Public functions can be called
    // - inside this contract
    // - inside contracts that inherit this contract
    // - by other contracts and accounts
    function publicFunc() public pure returns (string memory) {
        return "public function called";
    }

    // External functions can only be called
    // - by other contracts and accounts
    function externalFunc() external pure returns (string memory) {
        return "external function called";
    }

    // This function will not compile since we're trying to call
    // an external function here.
    // function testExternalFunc() public pure returns (string memory) {
    //     return externalFunc();
    // }

    // State variables
    string private privateVar = "my private variable";
    string internal internalVar = "my internal variable";
    string public publicVar = "my public variable";
    // State variables cannot be external so this code won't compile.
    // string external externalVar = "my external variable";
}

contract Child is Base {
    // 子合约无法获取父合约的 private functions 和 state variables.
    // function testPrivateFunc() public pure returns (string memory) {
    //     return privateFunc();
    // }

    // Internal function 可以被子合约调用
    function testInternalFunc() public pure override returns (string memory) {
        return internalFunc();
    }
}