Ethereum: Smart Contracts in Practice
The Anatomy of a Real Solidity Contract · 1/2

State variables, functions, and visibility

A Solidity contract is really just a piece of persistent state plus a set of functions that are allowed to read or change it. State variables live in the contract's storage on the blockchain permanently, which is why writing to them costs gas and reading them is comparatively cheap. When you declare a variable like `uint256 public totalSupply;`, you're reserving a permanent slot in the contract's storage layout, not a temporary value that disappears when a function returns.

Every function needs a visibility modifier, and picking the wrong one is a common source of bugs. `public` functions can be called from anywhere, inside the contract, from other contracts, or from an external transaction, and Solidity automatically generates a getter for public state variables. `external` functions can only be called from outside the contract, which is slightly cheaper in gas since arguments don't need to be copied into memory the same way. `private` and `internal` restrict a function to the contract itself, or to the contract plus anything that inherits from it. Defaulting to the most restrictive visibility that still works is the safer habit, since an accidentally public function is a door left open.