Functions and visibility

Who can call your functions — and what can they do? Visibility and state mutability explained.

Visibility modifiers

Every function and state variable in Solidity has a visibility level. Getting this wrong is one of the most common sources of security vulnerabilities.

public

Callable from anywhere: externally (from other contracts or wallets), internally (within the contract), and via the ABI. State variables marked public automatically get a getter function.

solidity
uint256 public totalSupply;  // auto-generates a totalSupply() getter

function mint(address to, uint256 amount) public {
    // Anyone can call this — be careful!
}

external

Can only be called from outside the contract — not from within. Slightly cheaper than public for functions that only need external access, because arguments are read from calldata instead of being copied to memory.

solidity
function deposit() external payable {
    // Can only be called from outside this contract
}

internal

Callable from within the contract and from derived contracts (via inheritance). Not accessible from outside.

solidity
function _beforeTransfer(address from, address to, uint256 amount) internal {
    // Shared logic used by multiple transfer functions
}

private

Only callable from within the contract itself. Not accessible from derived contracts.

solidity
function _updateBalance(address account, uint256 newBalance) private {
    balances[account] = newBalance;
}

State mutability

State mutability describes what a function is allowed to do with contract state.

view

Promises not to modify state. Reading state variables is fine. Free to call (no gas) when called externally.

solidity
function balanceOf(address account) public view returns (uint256) {
    return balances[account];
}

pure

Cannot read or write state. Used for pure computation.

solidity
function toWei(uint256 ether_amount) public pure returns (uint256) {
    return ether_amount * 1e18;
}

payable

Allows the function to receive Ether. Functions without payable will revert if you send ETH to them.

solidity
function deposit() external payable {
    require(msg.value > 0, 'Send some ETH');
    balances[msg.sender] += msg.value;
}

Return values

Functions can return multiple values using tuple syntax.

solidity
function getPoolInfo() external view returns (uint256 reserve0, uint256 reserve1, uint256 totalLiquidity) {
    return (_reserve0, _reserve1, _totalLiquidity);
}

Named return variables can be used to improve readability and skip the explicit return statement.

solidity
function divide(uint256 a, uint256 b) public pure returns (uint256 result, bool success) {
    if (b == 0) return (0, false);
    result = a / b;
    success = true;
    // no return statement needed — named variables are returned automatically
}
←   Data types and variablesControl flow   →