What is Solidity?
Solidity is a high-level, object-oriented programming language used to write smart contracts on Ethereum and other EVM-compatible blockchains. It’s the most widely used smart contract language, powering virtually all major DeFi protocols, NFT platforms, and DAOs.
Created by Dr. Gavin Wood, Christian Reitwiessner, and others in 2014, Solidity was designed to be familiar to developers who know JavaScript, C++, or Python. Its syntax resembles JavaScript with added features for blockchain-specific operations like gas management, cryptographic functions, and contract-to-contract calls.
Over $100 billion in value is secured by Solidity smart contracts. If you’re learning Web3 development, Solidity is the #1 language to learn.
Key Features of Solidity
statically Typed
Solidity is statically typed — you must declare variable types:
uint256 public totalSupply; // unsigned integer
address public owner; // Ethereum address
mapping(address => uint256) balances; // key-value store
bool public paused; // boolean
string public name; // string
This prevents many common bugs (like type mismatches) that would be caught at compile time.
Contract-Oriented
Everything in Solidity is organized into contracts — similar to classes in object-oriented programming:
contract MyToken {
// State variables (stored on-chain, cost gas)
uint256 public totalSupply;
mapping(address => uint256) public balances;
// Events (logged to blockchain, cheap)
event Transfer(address indexed from, address indexed to, uint256 amount);
// Constructor (runs once at deployment)
constructor(uint256 _initialSupply) {
totalSupply = _initialSupply;
balances[msg.sender] = _initialSupply;
}
// Functions (callable by anyone or restricted)
function transfer(address to, uint256 amount) public returns (bool) {
require(balances[msg.sender] >= amount, "Insufficient balance");
balances[msg.sender] -= amount;
balances[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
}
Built-in Blockchain Types
Solidity includes blockchain-specific data types:
| Type | Description | Example |
|---|---|---|
address | 20-byte Ethereum address | 0x742d35Cc... |
payable address | Address that can receive ETH | payable(msg.sender).transfer(1 ether) |
msg.sender | Address calling the function | The current caller |
msg.value | Amount of ETH sent with the call | require(msg.value > 0) |
block.timestamp | Current block’s timestamp | For time-based logic |
block.number | Current block number | For block-based logic |
Writing Secure Solidity
Solidity development requires extreme care because mistakes are expensive and irreversible. Here are the most critical patterns:
1. Checks-Effects-Interactions Pattern
The #1 rule of Solidity — always update state before making external calls:
// VULNERABLE (reentrancy attack possible)
function withdraw() public {
uint256 amount = balances[msg.sender];
(bool ok, ) = msg.sender.call{value: amount}(""); // External call FIRST
balances[msg.sender] = 0; // State update LAST — too late!
}
// SECURE
function withdraw() public {
uint256 amount = balances[msg.sender];
balances[msg.sender] = 0; // State update FIRST
(bool ok, ) = msg.sender.call{value: amount}(""); // External call LAST
require(ok, "Transfer failed");
}
2. Access Control
Restrict who can call certain functions:
contract Owned {
address public owner;
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "Not authorized");
_;
}
function setFee(uint256 newFee) public onlyOwner {
fee = newFee;
}
}
3. SafeMath and Overflow Protection
Solidity 0.8+ has built-in overflow checks. For older versions:
// Solidity 0.8+ — automatic overflow check
balances[to] += amount; // Will revert on overflow
// Pre-0.8 — needed SafeMath library
balances[to] = balances[to].add(amount); // Manual overflow check
4. ReentrancyGuard
OpenZeppelin’s ReentrancyGuard prevents reentrancy attacks entirely:
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract MyContract is ReentrancyGuard {
function withdraw() public nonReentrant {
// Even if external call is first, reentrancy is blocked
}
}
Gas Optimization
Every operation in Solidity costs gas. Optimizing is crucial:
| Optimization | Savings | Example |
|---|---|---|
Use calldata instead of memory for function params | ~30% | function foo(string calldata name) |
| Pack structs (order by size) | 1 storage slot per 32 bytes | struct { uint128 a; uint128 b; } |
Use immutable for one-time set values | No SLOAD | address immutable owner; |
| Use events instead of storage | ~100x cheaper | emit Log(x) instead of state = x |
| Cache storage in memory | Avoid repeated SLOAD | uint bal = balances[user] |
| Use custom errors instead of require strings | ~50 gas per revert | error InsufficientBalance() |
Solidity Development Tools
| Tool | Purpose | Cost |
|---|---|---|
| Remix | Browser-based IDE, great for beginners | Free |
| Hardhat | Development framework (compile, test, deploy) | Free |
| Foundry | Fast development framework (Rust-based) | Free |
| OpenZeppelin | Audited contract library (ERC-20, ERC-721, etc.) | Free |
| Etherscan | Verify and publish source code | Free |
| Slither | Static analysis security tool | Free |
| Tenderly | Simulation, monitoring, debugging | Freemium |
Learning Resources
- Solidity by Example: solidity-by-example.org — code snippets for common patterns
- CryptoZombies: cryptozombies.io — gamified Solidity tutorial
- Patrick Collins’ Free Code Camp: 32-hour Solidity course on YouTube
- OpenZeppelin Contracts: Read the source code of audited contracts
- Foundry Book: book.getfoundry.sh — Foundry documentation with examples
Alternatives to Solidity
| Language | Chain | Why Use It |
|---|---|---|
| Vyper | EVM | Python-like, fewer features = fewer bugs (Curve uses it) |
| Rust | Solana, Near | High performance |
| Move | Aptos, Sui | Resource-oriented (assets can’t be duplicated) |
| Cairo | Starknet | Optimized for ZK proofs |
| Huff | EVM | Assembly-like, maximum gas optimization |
Frequently Asked Questions
Q: How long does it take to learn Solidity? A: If you already know JavaScript/Python: 2-4 weeks for basics, 3-6 months for production-ready skills. Security auditing requires 1+ years of experience.
Q: Is Solidity hard to learn? A: The syntax is similar to JavaScript, so the learning curve is gentle. The hard part is security — writing code that handles real money without bugs.
Q: Should I learn Solidity or Rust? A: If you want to build on Ethereum/L2s (largest ecosystem, most jobs): Solidity. If you want to build on Solana (high performance, growing): Rust. Learning both makes you very valuable.