Solidity Visibility
Visibility is the setting that says who can reach a function or a variable. Solidity has four visibility settings, and each one opens the code to a different group of callers.
A private value needs the contract's own reader
score is public, so anyone can read it. code is private, so it is reachable only through this contract's own readCode function.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract ScoreSafe {
uint256 public score;
uint256 private code;
function setScore(uint256 newScore) public {
score = newScore;
}
function setCode(uint256 newCode) public {
code = newCode;
}
function readCode() public returns (uint256) {
return code;
}
}
An external function answers outside callers
triple is marked external. The test contract sits outside this contract, and its call still reaches the function.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract Echo {
function triple(uint256 amount) external returns (uint256) {
return amount * 3;
}
}
Internal is the family-only setting
bonus is internal, the family-only setting for this contract and its children. totalWithBonus is public, so an outside call can use the helper through it.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract Points {
function bonus() internal returns (uint256) {
return 5;
}
function totalWithBonus(uint256 score) public returns (uint256) {
return score + bonus();
}
}
Example
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract ClubCounter {
uint256 public members;
uint256 private doorCode;
function join() public {
members = members + 1;
}
function setDoorCode(uint256 newCode) public {
doorCode = newCode;
}
function readDoorCode() public returns (uint256) {
return doorCode;
}
function startingBonus() internal returns (uint256) {
return 2;
}
function welcomePoints() public returns (uint256) {
return startingBonus();
}
function outsideTotal(uint256 points) external returns (uint256) {
return points * 2;
}
}
Key points
- Public: anyone can call it, and a public variable grows a reading function.
- Private: only code inside the same contract can reach it.
- Internal: code in this contract and in its child contracts can reach it.
- External: only callers from outside the contract can call the function.
- Variables: a state variable can be public, private, or internal, but never external.
In this example, members is public, so anyone can read the count after join runs. doorCode is private, so readDoorCode is the only way in from outside. startingBonus is internal and welcomePoints uses it, while outsideTotal is external and answers callers from outside the contract.
Note
private hides a value from other contracts, but the stored data still sits on the public chain.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Remix IDE
Exercise
Another contract wants to read a private variable directly. What happens?