Functions & Visibility
Functions define what a contract can do. Visibility modifiers determine who can call them, and state mutability (view/pure) tells the EVM whether the function modifies state — which determines if a transaction is needed.
Visibility Modifiers
public — callable by anyone (external users + internal + derived contracts)
external — callable only from outside the contract (most gas-efficient for large params)
internal — callable only within this contract and derived contracts (like protected)
private — callable only within this exact contract (not even derived contracts)
State mutability:
view — reads state, does not modify. Can be called for free (no gas if called externally).
pure — neither reads nor modifies state. Math functions, utilities.
payable — can receive ETH with the call.
(none) — modifies state, requires a transaction.
Function selector: first 4 bytes of keccak256(signature)
increment() → keccak256("increment()")[0:4] → 0xd09de08aSpecial Functions: Constructor, Receive, Fallback
constructor — Runs once at deployment. Sets initial state. Cannot be called again.
receive() external payable — Called when ETH is sent to the contract with empty calldata. Required to accept plain ETH transfers.
fallback() external [payable] — Called when no function selector matches, or when calldata is sent but no receive() exists. Used for proxy contracts.
Function call resolution order:
1. If calldata is empty AND ETH is sent → receive()
2. If calldata doesn't match any function:
a. If receive() exists AND calldata is empty → receive()
b. Otherwise → fallback()
3. If calldata matches a selector → that functionCommon Mistakes
- Declaring a function public when it should be external — public functions copy calldata to memory for internal calls; use external for functions only called from outside.
- Forgetting receive() when your contract should accept ETH — without it, sending ETH to the contract will always revert.
- Writing view functions that actually modify state — the compiler catches this, but be explicit: if you modify state, you MUST pay gas.
- Using the same function name with different param types (overloading) — Solidity supports overloading but it can create confusing selectors. Keep function names descriptive and unique.
Tip
Tip
Practice Functions Visibility in small, isolated examples before integrating into larger projects. Breaking concepts into small experiments builds genuine understanding faster than reading alone.
Once deployed, smart contracts are immutable — code is law
Practice Task
Note
Practice Task — (1) Write a working example of Functions Visibility from scratch without looking at notes. (2) Modify it to handle an edge case (empty input, null value, or error state). (3) Share your solution in the Priygop community for feedback.
Quick Quiz
Common Mistake
Warning
A common mistake with Functions Visibility is skipping edge case testing — empty inputs, null values, and unexpected data types. Always validate boundary conditions to write robust, production-ready web3 code.
Key Takeaways
- Functions define what a contract can do.
- Declaring a function public when it should be external — public functions copy calldata to memory for internal calls; use external for functions only called from outside.
- Forgetting receive() when your contract should accept ETH — without it, sending ETH to the contract will always revert.
- Writing view functions that actually modify state — the compiler catches this, but be explicit: if you modify state, you MUST pay gas.