Solidity access modifiers
A guide to public, private, internal, external access modifiers (visibility) in Solidity
Table of Contents for Solidity access modifiers
Public
- can be used by sub contracts that inhreit from the contract containing the public function/variable
- public variables automatically generate a getter function so you can easily access it via function calls in Solidity
contract Parent {
bool public parentProperty;
}
contract Child is Parent {
function example() external {
// this is ok!
parentProperty = true;
}
}
Private
- only the same contract can access this
- contracts which inherit the contract that the private function/variable resides in cannot access it
- No way to easily access the data outside of the smart contract
- remember: private state variables are still stored in the blockchain, so its not impossible or even very hard to access or read it
contract Parent {
bool private parentProperty;
}
contract Child is Parent {
function example() external {
// this will cause an error!
parentProperty = true;
}
}
Internal
- This is like
protected
in other languages. Contracts that inherit from the contract containinginternal
state variables/functions can still access/call them
contract Parent {
bool internal parentProperty;
}
contract Child is Parent {
function example() external {
// this is ok!
parentProperty = true;
}
}
External
- can only be accessed from other smart contracts
pragma solidity >=0.7.0 <0.9.0;
contract Parent {
function aPublicFunction() public {
}
function anExternalFunction() external {
}
}
contract Child is Parent {
function example() external {
aPublicFunction(); // is ok!
anExternalFunction(); // causes an error!
}
}
contract AnotherContract {
function getParentProperty(address someAddress) external {
// this is ok
Parent(someAddress).aPublicFunction();
Parent(someAddress).anExternalFunction();
}
}
What is the difference between external and public in Solidity
On the face of it, external and public seem very similar.
Both of them can be accessed from another smart contract.
External contracts cannot be accessed from its own contract though.
In older versions of Solidity, external
would always be much cheaper if the function had arrays/mapping as arguments, as external
would keep them as calldata
, but public
would copy them to memory
.
But since Solidity 0.8, the compiler no longer works like that.
If you really need to call an external function from another function in the same contract you can call it with the this.yourExternalFn()
(instead of just calling yourExternalFn()
) although it is rare/uncommon to see.
If you have getters for your storage variables (when you declare them with public
- like uint public someNumber
), these getters are defined as if they were external
. When your other functions access that variable (e.g. return someNumber
) it reads direct from storage. If you wanted to actually call the getter, use this.someNumber()
.
Spotted a typo or have a suggestion to make this crypto dev article better? Please let me know!
Next post
Previous post
π Solidity Auditing online quiz
Learn how to audit smart contracts by looking at some example code and trying to find the bugs
β½ Solidity Gas Optimizations Guide
How to optimize and reduce gas usage in your smart contracts in Solidity
π§ͺ Guide to testing with Foundry
Guide to adding testing for your Solidity contracts, using the Foundry and Forge tools
π Guide to UTXO
UTXO and the UTXO set (used by blockchains such as Bitcoin) explained
π Solidity Assembly Guide
Introduction guide to using assembly in your Solidity smart contracts
π¦ Ethereum EOF format explained
Information explaining what the upcoming Ethereum EOF format is all about