What Solidity is
The official documentation defines Solidity as an object-oriented, high-level language for implementing smart contracts, which are programs that govern the behavior of accounts within the Ethereum state. It is a curly-bracket language designed to target the Ethereum Virtual Machine, influenced by C++, Python and JavaScript.[1]
It is statically typed and supports inheritance, libraries and complex user-defined types. The documentation lists voting, crowdfunding, blind auctions and multi-signature wallets as typical contracts you can write with it.[1]
Solidity is not the only option. Ethereum.org's smart contract languages page covers Vyper, a Pythonic language, and Yul, an intermediate language for the EVM, and points beginners to the in-browser Remix IDE, which supports both Solidity and Vyper.[2]
What a contract looks like
The documentation's first example is SimpleStorage: a contract with one state variable, uint storedData, a set function that writes it, and a get function that reads it. The file begins with a pragma line, such as pragma solidity >=0.4.16 <0.9.0, which tells the compiler which versions may build it.[3]
Each piece maps to something on chain. The state variable becomes a slot in contract storage. The functions become entry points in the bytecode, selected by the first 4 bytes of the call data. Anyone can call set, which is why real contracts add access control such as an owner check.[3]
A second example in the same introduction is a minimal token called Coin, with a minter, a mapping of balances, a send function and an event. It is a short preview of the ideas that the ERC-20 standard later formalized.[3]
Functions declare their visibility and their relationship to state. External and public functions are part of the contract interface and can be called from outside; internal and private ones cannot. A view function promises not to modify state, and a pure function promises neither to read nor to modify it.[10]
Events are the other half of the interface. A contract emits an event such as Sent(from, to, amount), and off-chain software, including wallets and explorers, subscribes to those logs instead of polling storage. The Coin example in the documentation uses exactly this pattern.[3]
See also: What is ERC-20?
From source code to the EVM
The compiler, solc, turns Solidity into two outputs. The bytecode is what gets deployed and executed by the EVM. The ABI, the application binary interface, is a JSON description of the functions and events that wallets and libraries use to encode calls.[4]
The compiler targets a specific EVM version. The documentation describes an evmVersion setting because new Ethereum upgrades add opcodes; code compiled for a newer target may not run on a chain that has not adopted the same upgrade.[4]
Deployed code must also fit Ethereum's contract size limit of 24,576 bytes, set by EIP-170. The optimizer and splitting logic into libraries are the usual ways to stay under it.[5]
The ABI also defines how calls are addressed. The first four bytes of call data are the function selector, taken from the Keccak-256 hash of the function signature, such as transfer(address,uint256). That is why two functions with the same name but different parameter types are different entry points, and why block explorers can decode a transaction once they know the contract's ABI.[9]
See also: What is the EVM?
A worked example: the 0.8 overflow change
Consider a uint8 variable, which holds values from 0 to 255. Before version 0.8.0, adding 1 to 255 silently wrapped around to 0, and the compiler did not warn about it.[6]
Solidity 0.8.0 changed the default: arithmetic operations revert on underflow and overflow. The release notes give the reason: overflow checks were so common that making them the default improves readability, even at a slight gas cost.[6]
So today, x = 255; x + 1 reverts the whole transaction instead of returning 0. If you truly want wrapping arithmetic, for example in a gas-optimized loop counter that cannot overflow, you write it inside unchecked { ... }. The same page notes that failing assertions and internal checks such as division by zero now use a revert with a Panic error code rather than consuming all gas.[6]
The practical effect: old tutorials that import SafeMath for every addition are outdated for 0.8.x code. The check is built in.
One more habit matters in audits. Because unchecked switches off the safety net, reviewers search for every unchecked block and confirm, line by line, why the arithmetic inside cannot overflow. A loop counter bounded by an array length is a typical safe case; user-supplied amounts almost never are, so leave those checked and pay the small extra gas.
| Feature | What it means | Why it matters |
|---|---|---|
| Static typing | Every variable has a declared type | Many bugs are caught at compile time |
| Inheritance | Contracts can extend others | Reuse of audited base contracts |
| Checked arithmetic (0.8+) | Overflow reverts by default | Removes a classic class of token bugs |
| Pragma line | Pins allowed compiler versions | Builds are reproducible |
Security basics the documentation insists on
The Solidity documentation has a full Security Considerations chapter, and one of its first examples is reentrancy. A withdraw function that sends ETH with msg.sender.call before setting the caller's share to zero lets a malicious contract call withdraw again from inside that transfer and drain funds.[8]
The documented fix is the Checks-Effects-Interactions pattern: check conditions first, update your own state second, and interact with other contracts last. In the withdraw example, you set the share to zero before sending the ETH.[8]
The same chapter says plainly: never use tx.origin for authorization. tx.origin is the account that started the whole transaction, so a malicious contract the owner is tricked into calling can pass an owner check based on it. Use msg.sender instead.[8]
Its general recommendations are practical: take compiler warnings seriously, restrict the amount of ETH a contract holds, keep contracts small and modular, use Checks-Effects-Interactions, include a fail-safe mode, and ask for peer review. None of them requires advanced tooling.[8]
Versions and releases
Solidity is still on a 0.x version line, and minor releases can include breaking changes. The documentation keeps a separate breaking-changes page for each of 0.5.0, 0.6.0, 0.7.0 and 0.8.0.[1]
The Solidity team announced compiler v0.8.37 on September 10, 2026. The announcement mentions fixes for several important bugs and support for block.slotnum from the Amsterdam EVM version.[7]
The documentation also maintains a list of known compiler bugs by version. Before auditing or verifying a contract, check its pragma and the exact compiler version against that list.[1]
Tools and where to learn
Remix runs in the browser with no install, and ethereum.org's languages page points beginners to it. Local frameworks and audited contract libraries, such as those linked below, cover testing, deployment and standard implementations like ERC-20 and ERC-721.[2]
The linked course projects offer structured learning paths. Practice deployments belong on a testnet such as Sepolia, funded from a faucet, never on mainnet.
Whatever tool you pick, the compile step is the same solc compiler, so settings such as optimizer runs and evmVersion carry across. Match them to what you will later submit for source verification, or the explorer will report a bytecode mismatch.[4]
Read other people's verified contracts as part of learning. Etherscan shows source code for verified contracts, and reading a well-known token or vault is often faster than a tutorial for learning real patterns such as access control, pausing and upgrade proxies.
See also: Foundry · Hardhat · Remix · OpenZeppelin · Cyfrin Updraft · CryptoZombies · Speedrun Ethereum · Sepolia RPC · Best web3 education resources · Etherscan
The bottom line
Learn Solidity if you want to write contracts for Ethereum or any EVM chain: one language covers them all. Start on 0.8.x, pin the compiler version, rely on audited libraries instead of writing token logic from scratch, and deploy to Sepolia before mainnet. The language is small; the costly part is security, so budget more time for tests than for syntax. Read the documentation's Security Considerations chapter before your first mainnet deployment.
Educational content, not financial advice. Crypto assets are volatile; do your own research.