New to blockchain software development? Read my beginners guide here

Solidity access modifiers

Created on May 2022 β€’ Tags: guides

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 containing internal 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.

See guide on calldata here

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!

See all posts (70+ more)

See all posts (70+ more)

Was this post helpful? πŸ“§

If you liked this content and want to receive emails about future posts like this, enter your email. I'll never spam you.

Or follow me on @CryptoGuide_Dev on twitter

By using this site, you agree that you have read and understand its Privacy Policy and Terms of Use.
Use any information on this site at your own risk, I take no responsibility for the accuracy of safety of the information on this site.