Skip to main content

Function Visibility and State Mutability

You've seen much of this before, but this document outlines and highlights the options for function visibility and state mutability all in one document.


Objectives

By the end of this lesson you should be able to:

  • Categorize functions as public, private, internal, or external based on their usage
  • Describe how pure and view functions are different than functions that modify storage

Function Visibility

There are four types of visibility for functions in Solidity: external, public, internal, and private. These labels represent a further division of the public and private labels you might use in another language.

External

Functions with external visibility are only callable from other contracts and cannot be called within their own contract. You may see older references stating you should use external over public because it forces the function to use calldata. This is no longer correct, because both function visibilities can now use calldata and memory for parameters. However, using calldata for either will cost less gas.

contract Foo {
constructor() {
// Bad code example, will not work
uint bar = foo(3);
// ... other code
}

function foo(uint _number) external pure returns (uint) {
return _number*2;
}
}

Public

Public functions work the same as external, except they may also be called within the contract that contains them.

contract Foo {
constructor() {
// Public functions may be called within the contract
uint bar = foo(3);
// ... other code
}

function foo(uint _number) public pure returns (uint) {
return _number*2;
}
}

Private and Internal

Functions visible as private and internal operate nearly identically. Beyond writing hygienic code, these have a very important effect. Because they are not a part of the contract's ABI, you can use mappings and storage variable references as parameters.

The difference is that private functions can't be called from derived contracts. You'll learn more about that when we cover inheritance.

Some developers prepend an underscore to private and internal functions.

function _foo(uint _number) private returns (uint) {
return _number*2;
}
danger

All data on a blockchain is public. Don't mistake hiding visibility while coding for hiding information from the world!


Function State Mutability

State mutability labels are relatively unique to Solidity. They determine how a function can interact with state, which has a substantial impact on gas costs.

Pure

pure functions promise to neither read nor write state. They're usually used for helper functions that support other functionality.

function abs(int x) public pure returns (int) {
return x >= 0 ? x : -x;
}

pure functions can be called from outside the blockchain without using gas, if they are also public or external.

View

view functions access state, but don't modify it. You've used these for tasks such as returning all the values in an array.

function getArr() public view returns (uint[] memory) {
return arr;
}

view functions can be called from outside the blockchain without using gas, if they are also public or external.

Unlabeled Functions

Functions that are not labeled view or pure can modify state and the compiler will generate a warning if they do not.

function addToArr(uint _number) public {
arr.push(_number);
}

They can have any visibility and will always cost gas when called.


Conclusion

The visibility and mutability keywords in Solidity help you organize your code and alert other developers to the properties of each of your functions. Use them to keep your code organized and readable.


We use cookies and similar technologies on our websites to enhance and tailor your experience, analyze our traffic, and for security and marketing. You can choose not to allow some type of cookies by clicking . For more information see our Cookie Policy.