The Essentials at a Glance
Every Solidity file starts with a license identifier and a pragma pinning the compiler version, then declares a contract. The core value types are bool, uint/int (sized in 8-bit steps up to 256, with uint256 the default), address (and address payable for sending ETH), bytes32, and enums; reference types include arrays, structs, mappings, string, and bytes. Mappings are the workhorse for lookups (mapping(address => uint256) balances) but cannot be iterated—you track keys separately if you need to enumerate. Constants and immutables save gas: constant is fixed at compile time, immutable is set once in the constructor.
Cricket analogy: The type list is like a batting order card—each slot has a defined role; uint256 as default is your reliable number-three, and a mapping is the scorer's instant lookup of any player's runs.
Visibility, Modifiers, and Errors
Function visibility is public (anywhere + auto getter for variables), external (only from outside), internal (this contract and derived), and private (this contract only). State mutability keywords tell the compiler and callers what a function does: view reads state without modifying it, pure neither reads nor writes state, and payable can receive ETH. Custom modifiers wrap functions with reusable checks—the canonical onlyOwner reverts if msg.sender is not the owner, with the _ placeholder marking where the function body runs. For failures, use require(condition, "msg") for validation, custom errors with revert MyError() for gas-efficient structured failures, and assert() only for invariants.
Cricket analogy: Visibility keywords are like access levels in a stadium—public is the open stand, external the away section, internal the players' area, private the captain's room; a modifier is the gate steward checking passes before entry.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract QuickRef {
address public immutable owner; // set once in constructor
uint256 public constant MAX = 1000; // fixed at compile time
mapping(address => uint256) public balances;
event Deposited(address indexed who, uint256 amount);
error NotOwner();
modifier onlyOwner() {
if (msg.sender != owner) revert NotOwner();
_; // function body runs here
}
constructor() {
owner = msg.sender;
}
function deposit() external payable {
require(msg.value > 0, "no value");
balances[msg.sender] += msg.value;
emit Deposited(msg.sender, msg.value);
}
function total() external view returns (uint256) {
return address(this).balance; // global: contract's ETH balance
}
function withdrawAll() external onlyOwner {
payable(owner).transfer(address(this).balance);
}
}Handy globals: msg.sender (caller), msg.value (ETH sent, in wei), block.timestamp (current block time), block.number, address(this).balance (contract's ETH), and tx.gasprice. Units: 1 ether == 1e18 wei, and 1 gwei == 1e9 wei. Time units exist too: 1 days, 1 hours, and 1 weeks are valid literals.
Patterns You Reuse Constantly
A few patterns show up in nearly every contract. Emit events for anything off-chain tools should track, since events are cheap and indexable. Use the checks-effects-interactions order and prefer call{value: x}("") over the older transfer for sending ETH (with a require on the returned success flag). Reach for OpenZeppelin for standards: ERC20/ERC721 tokens, Ownable/AccessControl for permissions, and ReentrancyGuard for reentrancy safety. When receiving ETH directly, define receive() external payable for plain transfers and fallback() external payable for calls with unmatched selectors. These building blocks cover the majority of day-to-day Solidity work.
Cricket analogy: These patterns are like standard field placements every captain reuses—slip cordon, mid-on, third man; checks-effects-interactions is the drilled routine you never skip under pressure.
Common gotchas: division truncates (integer math has no decimals—scale up before dividing); uninitialized storage pointers and shadowed variables cause subtle bugs; and prefer call over transfer for sending ETH because transfer's fixed 2300 gas stipend can break with smart-contract recipients. Always check the boolean return of a low-level call and follow checks-effects-interactions.
- Start files with SPDX license + a pinned pragma; uint256 and address are the default value types.
- Mappings give O(1) lookups but are not iterable—track keys separately to enumerate.
- Visibility: public/external/internal/private; mutability: view (reads), pure (neither), payable (receives ETH).
- Modifiers wrap functions with reusable checks; _ marks where the body executes.
- Handle failures with require (validation), custom errors + revert (cheap structured), and assert (invariants).
- Know globals (msg.sender, msg.value, block.timestamp) and units (1 ether = 1e18 wei).
- Reuse OpenZeppelin (ERC20/721, Ownable, ReentrancyGuard); prefer call{value:x}("") over transfer for sending ETH.
Practice what you learned
1. What is the default and most common unsigned integer type in Solidity?
2. Which statement about mappings is true?
3. What does a payable function allow?
4. How many wei are in 1 ether?
5. Why prefer call{value: x}("") over transfer for sending ETH?
Was this page helpful?
You May Also Like
Solidity Syntax and Variables
Understand Solidity's file structure, the difference between state, local, and global variables, and how visibility and data location affect where values live and who can read them.
Solidity Data Types and Value Types
Explore Solidity's value types and reference types, including sized integers, booleans, addresses, bytes, enums, arrays, structs, and mappings, and how they are copied and stored.
Solidity Best Practices
A practical checklist of security, gas, and maintainability practices for production Solidity: checks-effects-interactions, access control, safe external calls, custom errors, and reuse of audited libraries.
Solidity Interview Questions
The concepts interviewers probe most for Solidity roles—data location, visibility, storage layout, gas, security patterns, and the EVM—framed as talking points with sharp, correct answers.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics