State variables live in storage and persist between calls. Local variables live only for the duration of a call. Global variables such as `msg.sender`, `msg.value` and `block.timestamp` describe the current transaction and block.
Visibility on state variables controls Solidity-level access: `public` (auto-generates a getter), `internal` (this contract and children, the default) and `private` (this contract only).
uint256 public totalStaked; // getter generated uint256 internal cachedRate; address private _admin;
`private` is not secrecy: all storage is readable off chain. Never store secrets in a contract.