Introduction to Function Visibility in Solidity

Here's a detailed thread on Function Visibility in Solidity.
Understanding visibility is key to writing secure and efficient smart contracts.
Let's dive in!
In Solidity, function visibility determines who can access and call the function. Solidity offers four types of visibility specifiers: public
, external
, internal
, and private
. Each serves a specific purpose, and choosing the right one can enhance both security and functionality. Let's break down each one!
2/ public
Visibility
What it is: Functions marked as
public
can be accessed both externally (outside the contract) and internally (within the contract and derived contracts).Use Cases: Use
public
for functions that need to be accessible to other contracts, users, or off-chain interactions (like reading data).Gas Cost Note: Public functions create a "getter" function when used with a state variable.
Example:
uint public data; // This variable is accessible from outside as a getter function is created.
function setData(uint _data) public {
data = _data;
}
3/ external
Visibility
What it is:
external
functions can be called from outside the contract but not from within. If accessed internally,this.functionName()
must be used, which can be less gas-efficient.Use Cases: Use
external
for functions primarily meant for external contract or user calls, especially if they don’t need to interact with internal functions.Gas Efficiency:
external
is often cheaper thanpublic
for large calldata arrays since it saves gas on internal calls.
Example:
function updateData(uint _data) external {
data = _data;
}
4/ internal
Visibility
What it is:
internal
functions are accessible only within the contract and by derived contracts. They’re not accessible from external calls.Use Cases: Use
internal
for helper functions that are only meant for the contract itself or inherited contracts. They are ideal for reusable logic within a contract family.
Example:
function _calculate(uint a, uint b) internal pure returns (uint) {
return a + b;
}
5/ private
Visibility
What it is:
private
functions are the most restrictive—they’re only accessible within the contract in which they are defined, not even in derived contracts.Use Cases: Use
private
for functions that should only be available within the contract and contain sensitive or confidential logic.
Example:
function _generateSecret() private view returns (uint) {
return uint(keccak256(abi.encodePacked(block.timestamp, msg.sender)));
}
6/ Choosing the Right Visibility
Security: Use the least permissive visibility whenever possible. If a function doesn’t need to be accessed externally, avoid
public
orexternal
.Gas Optimization:
external
functions are often cheaper for larger calldata arrays, whileinternal
functions save gas on internal calls compared topublic
.
7/ State Variable Visibility
Public Variables: Solidity automatically generates a getter function for
public
state variables. This can save effort in writing accessor functions but should be used cautiously to avoid unnecessary exposure.Private/Internal Variables: Both
private
andinternal
restrict external access. Useprivate
if a variable should be accessible only within the same contract.
8/ Practical Example
Here’s a contract demonstrating each type of visibility:
pragma solidity ^0.8.0;
contract VisibilityExample {
uint public publicData = 1; // Public variable with automatic getter
uint private privateData = 2; // Private variable, no automatic getter
// Public function
function updatePublicData(uint _data) public {
publicData = _data;
}
// External function
function updateExternalData(uint _data) external {
publicData = _data;
}
// Internal function
function _internalFunction() internal pure returns (string memory) {
return "Internal";
}
// Private function
function _privateFunction() private pure returns (string memory) {
return "Private";
}
}
9/ Key Takeaways
Use
public
andexternal
cautiously to avoid exposing unnecessary data or functionality.Prefer
internal
andprivate
when possible to improve security and limit access.Select visibility based on who needs access to the function or data—only open access if required.
10/ Wrapping Up
Mastering function visibility in Solidity is fundamental to writing secure, efficient contracts. Carefully consider access requirements for each function, and use the most restrictive visibility that meets your needs.
Happy coding, and remember: Security starts with visibility!
Subscribe to my newsletter
Read articles from Abraham Dominic Newton directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Abraham Dominic Newton
Abraham Dominic Newton
Hi, I’m Abraham Dominic Newton an ardent Front-End Developer with the brand name; Abraham Cyber Tech. I'm passionate about using codes to solve real life problems; thereby creating a sustainable world for all. 💻 I’m currently an Ingressive for Good Student Ambassador for Federal University Wukari, Taraba State, Nigeria. 👀 I’m interested in Cyber Security & Python Language 💻 ... 🌱 I’m currently learning Front-end & Python ... 💞️I’m looking to collaborate on different projects on Website Development, Python project particularly Front-End & Backend. 💬 Ask me anything about Ingressive for Good ⚡ Fun fact: I love participating in changemaking activities