Solidity Cheatsheet

Basics

Use this Solidity reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

How to Use This Solidity Cheatsheet

Use this as a syntax reference while you learn Solidity as a programming language for smart contracts. If you already know JavaScript or TypeScript, the surface syntax may feel familiar, but the important differences are storage, gas, visibility, and security. For a broader software engineering foundation, pair this reference with Hack University's JavaScript or TypeScript language courses before building production smart-contract tooling.

File Structure

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./MyLibrary.sol";

contract MyContract {
    // state variables, events, modifiers, functions
}
  • SPDX comment is mandatory (or you get a compiler warning). Use UNLICENSED for proprietary code.
  • pragma solidity pins the compiler version. ^0.8.24 means >=0.8.24 <0.9.0.
  • Import paths: bare specifiers resolve via remappings (remappings.txt / foundry.toml); relative paths resolve from the file's directory.

Contract Declaration

// Plain contract
contract Token { }

// Abstract contract (has unimplemented functions)
abstract contract Base {
    function transfer(address to, uint amount) external virtual;
}

// Interface (all external, no state, no constructor)
interface IERC20 {
    function totalSupply() external view returns (uint256);
}

// Library (stateless helpers, no ether, no storage)
library Math {
    function max(uint a, uint b) internal pure returns (uint) {
        return a >= b ? a : b;
    }
}

Pragma Directives

pragma solidity ^0.8.24;          // caret range
pragma solidity >=0.8.0 <0.9.0;  // explicit range
pragma solidity 0.8.24;           // exact version (rarely used)
pragma abicoder v2;               // default since 0.8.0; enables complex types in ABI
pragma experimental SMTChecker;   // static analysis (dev only)

Comments

// Single-line comment

/* Multi-line
   comment */

/// @notice NatSpec single-line (user-facing)
/// @dev    NatSpec developer note
/// @param  amount The amount to transfer
/// @return        The resulting balance
/// @custom:security reviewed 2024-01
function deposit(uint256 amount) external returns (uint256) { }

NatSpec (/// or /** */) generates ABI documentation and is read by Etherscan and IDEs.

Imports

// Named import (preferred — explicit, avoids namespace pollution)
import { ERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

// Alias import
import { SafeERC20 as S } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

// Wildcard (avoid — imports everything into scope)
import * as OZ from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

// Plain import (imports all top-level symbols — avoid)
import "@openzeppelin/contracts/access/Ownable.sol";

Contract Size and Deployment

// EIP-170: max 24 576 bytes of deployed bytecode.
// Use libraries, proxies, or split contracts if you exceed the limit.

// Check size during tests (Foundry):
// assertLt(address(myContract).code.length, 24_576);

Global Constants and Units

// Ether units
1 wei   == 1
1 gwei  == 1e9
1 ether == 1e18

// Time units
1 seconds == 1
1 minutes == 60
1 hours   == 3600
1 days    == 86400
1 weeks   == 604800

// Usage
uint256 public constant LOCK_PERIOD = 30 days;
uint256 public fee = 0.01 ether;

ABI Encoding Utilities

bytes memory encoded = abi.encode(address(this), uint256(42));
bytes memory packed  = abi.encodePacked(msg.sender, block.timestamp); // no padding
bytes4   selector   = abi.encodeWithSelector(IERC20.transfer.selector, to, amount);
bytes memory callData = abi.encodeWithSignature("transfer(address,uint256)", to, amount);

// Decode
(address a, uint256 n) = abi.decode(encoded, (address, uint256));

abi.encodePacked is not collision-resistant for dynamic types — do not use it as a hash key with multiple variable-length args. Prefer abi.encode inside keccak256.

Version-Specific Features (0.8.x)

FeatureAdded in
Built-in overflow/underflow checks0.8.0
immutable keyword0.6.5
Custom errors (error Foo())0.8.4
try/catch0.6.0
unchecked { } block0.8.0
using A for B global0.8.13
User-defined value types (type Foo is uint256)0.8.8
bytes.concat / string.concat0.8.12
push() returns reference0.6.0
Transient storage (tstore/tload)0.8.24 (EIP-1153)