20.Visibility
函数和状态变量必须声明它们是否可以被其他合约访问。 函数可以声明为:
- public - 任何合约和账户都可以调用 ,可以从合约内外访问。
- private - 仅在定义该函数的合约内部 ,只能从当前合约访问。
- internal - 仅在继承了internal函数的合约内部 ,只能从当前合约或从继承合约访问。
- external - 仅其他合约和账户可以调用,仅可从合约外部访问。这个修饰符只能用于函数
状态变量可以声明为public、private或internal,但不能声明为external。
在Solidity中,
public
和external
是两种不同的函数修饰符,它们有以下区别:
public
:使用public
修饰符标记的函数可以从合约内外访问。这意味着它们可以在合约内部调用,也可以在合约外部通过合约地址调用。如果函数返回一个值,则该值将作为事务的一部分返回给调用方。如果函数没有返回值,则调用方只能确定事务是否成功。external
:使用external
修饰符标记的函数只能从合约外部访问。这个修饰符只能用于函数。这意味着它们不能在合约内部直接调用,而必须通过合约地址调用。如果函数返回一个值,则该值将作为事务的一部分返回给调用方。如果函数没有返回值,则调用方只能确定事务是否成功。因此,
public
和external
的主要区别在于它们是否可以在合约内部直接调用。如果函数需要在合约内部调用,则应该使用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();
}
}