Visibility
Introduction
Visibility in Solidity 0.8.16 refers to the accessibility of functions and state variables from other contracts and external accounts. Solidity offers four visibility types: public, external, internal, and private. Each visibility type determines the level of access to a function or state variable and affects how the contract interacts with other contracts.
Smart Contract Example
Here is an example smart contract that demonstrates the use of different visibility types:
pragma solidity 0.8.16;
contract VisibilityExample {
uint256 public publicVariable;
uint256 private privateVariable;
uint256 internal internalVariable;
constructor(uint256 _public, uint256 _private, uint256 _internal) {
publicVariable = _public;
privateVariable = _private;
internalVariable = _internal;
}
// public: accessible by all in any context
function publicFunction() public pure returns (string memory) {
return "This is a public function";
}
// external: can only be called by external accounts and contracts
function externalFunction() external pure returns (string memory) {
return "This is an external function";
}
// internal: can only be accessed from within the contract
// or its derived contracts. Usually helper functions
function internalFunction() internal pure returns (string memory) {
return "This is an internal function";
}
// private: only accessed by contract
// often used for implenmentation details that should not be exposed
function privateFunction() private pure returns (string memory) {
return "This is a private function";
}
}
Public: Public functions and state variables are accessible from any context, including other contracts and external accounts. When a function is marked public, Solidity automatically generates a getter function that allows other contracts to read the value of the state variable. However, it does not generate a setter function, and the state variable can only be modified by functions within the same contract.
// public function
function publicFunction() public pure returns (string memory) {
return "This is a public function";
}
External: External functions are similar to public functions, but they can only be called by external accounts and contracts. This means that they cannot be called by other functions within the same contract. External functions are often used to reduce gas costs because they do not need to update the contract state.
// external function
function externalFunction() external pure returns (string memory) {
return "This is an external function";
}
Internal: Internal functions and state variables can only be accessed from within the contract or its derived contracts. This means that they cannot be called from external accounts or contracts. They are often used for helper functions that are only needed within the contract.
// internal function
function internalFunction() internal pure returns (string memory) {
return "This is an internal function";
}
Private: Private functions and state variables can only be accessed from within the contract. They are not accessible from derived contracts or external accounts. Private functions and state variables are often used for internal implementation details that should not be exposed to other contracts or external accounts.
// private function
function privateFunction() private pure returns (string memory) {
return "This is a private function";
}
Second Smart Contract Example
Here is another example using as Simple Storage contract:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
contract SimpleStorage {
uint256 private _data;
event ValueSet(uint256 value);
function setValue(uint256 newValue) public {
_data = newValue;
emit ValueSet(_data);
}
// public function: returns value to anyone
function getValue() public view returns (uint256) {
return _data;
}
// internal function: returns value to anyone
function getDoubleValue() internal view returns (uint256) {
return _data * 2;
}
// private function:
function getTripleValue() private view returns (uint256) {
return _data * 3;
}
// external function:
function getQuadrupleValue() external view returns (uint256) {
return _data * 4;
}
}
In this example, the setValue
and getValue
functions have public
visibility, which means they can be called from anywhere, including other contracts and external accounts.
The getDoubleValue
function has internal
visibility, which means it can only be called from within the contract and any contracts that inherit from it.
The getTripleValue
function has private
visibility, which means it can only be called from within the contract and cannot be accessed by any inheriting contracts.
Finally, the getQuadrupleValue
function has external
visibility, which means it can only be called from outside the contract, such as from an external account or another contract.
Conclusion
By using different visibility options, developers can control access to functions and variables in their smart contracts and ensure that they are only used in the appropriate contexts.
Feedback
Have feedback? Found something that needs to be updated, accurate, or explained?
Join our discord and share what can be improved.
Any and all feedback is welcomed.