Why does putting `view` on a contract function stop it from changing any saved data, and how does the EVM brain make sure of this?
Putting `view` on a contract function signals that the function will only read data from the blockchain's saved state but will not change it. This keyword is a promise by the developer that the function will not alter any stored variable, emit events, deploy new contracts, or send Ether. The Ethereum Virtual Machine (EVM), which is the runtime environment for smart contracts, ensures this promise is kept through a strict enforcement mechanism primarily by distinguishing between how function calls are executed: as a read-only local execution (a "call") or as a state-changing global update (a "transaction").
When an external entity, such as a user interface or another contract, invokes a `view` function, it typically does so as a "call" (not a "transaction"). A "call" is a local simulation of the function's execution on an Ethereum node. It does not get broadcasted to the network, is not mined, and therefore does not consume gas or permanently alter the blockchain's state. The EVM, during the execution of such a "call," actively monitors the opcodes (low-level instructions) that the function attempts to execute.
Specifically, the EVM maintains a list of opcodes that are forbidden when executing a function marked as `view` (or `pure`, which is even stricter as it doesn't even read state). These forbidden opcodes are those that are designed to modify the blockchain's state. Key examples include `SSTORE`, which is used to write data to the contract's storage; `LOG` opcodes (like `LOG0` to `LOG4`), which are used to emit events that are recorded on the blockchain; `CREATE`, which deploys a new contract; `SELFDESTRUCT`, which removes a contract; and any `CALL` opcode that attempts to send Ether to another address or interact with another contract's state-modifying functions. If the EVM encounters any of these state-changing opcodes during the execution of a `view` function in a "call" context, it immediately reverts the execution. This reversion prevents any state modification from occurring, thereby guaranteeing that `view` functions remain purely read-only and do not impact the global state of the blockchain. The Solidity compiler, when compiling a contract, embeds metadata that allows the Ethereum node's EVM to enforce these restrictions at runtime.