Understanding Visibility in Solidity
When using Solidity, it's crucial to know the different visibility specifiers to create efficient and secure smart contracts. In this blog post, we will look into visibility specifiers in Solidity—public, private, internal, and external—and talk about what they mean with a clear example.
What is Visibility in Solidity?
Visibility in Solidity decides where and how you can access functions and state variables in a contract. Each specifier has a specific use:
Public: Can be accessed everywhere, including:
Outside the contract (through the blockchain or other contracts).
Inside the contract itself.
Inherited contracts.
Other contracts using an instance of the contract.
Private: Can be accessed only within the contract where it is defined.
Internal: Can be accessed within the contract and in inherited contracts.
External: Can be accessed outside the contract but not inside the contract itself.
Visibility Table Overview
Here’s a quick reference table summarizing the accessibility of each specifier:
Let’s see how this table translates into code.
Solidity Example: Understanding Visibility
The following contract demonstrates the usage of visibility specifiers in Solidity.
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract demo {
//public function
function f1() public pure returns(uint){
return 1;
}
//private function
function f2() private pure returns(uint){
return 2;
}
//internal function
function f3() internal pure returns(uint){
return 3;
}
//external function
function f4() external pure returns(uint){
return 4;
}
}
// Derived contract from demo contract
contract child is demo {
uint public x = f3();
}
// Other contract
contract otherContract {
demo obj = new demo();
uint y = obj.f4();
}
Key Observations
1. Public Functions
Public functions are accessible everywhere, including directly via Remix IDE or other external tools.
In the example above, both
f1()
andf4()
are visible when theDemo
contract is deployed.
2. Private Functions
Private functions like
f2()
are accessible only within the same contract.Attempting to call
f2()
from theChild
orOther
contract results in a compilation error.
3. Internal Functions
Internal functions like
f3()
can be accessed within the contract itself and derived contracts (e.g., theChild
contract).They are not accessible from an external contract instance (e.g.,
Other
contract).
4. External Functions
- External functions like
f4()
can be accessed by other contracts or external tools but cannot be invoked from within the same contract.
Pro Tips for Mastering Visibility
Use private for functions or variables that should not be visible outside the contract.
Use internal for variables or functions that need to be shared with derived contracts.
Use public for functions that should be accessible everywhere, including from outside.
Use external when a function is meant to be called from outside the contract, but not from within it.
Conclusion
Understanding visibility in Solidity is important for creating smart contracts that work well and are safe. By selecting the right visibility specifier, you can control how and where your contract's functions and variables can be accessed.