Roadmap › Solidity & Smart Contract Development › Module: Language Basics
Lessons in this course (11)

1. Contract structure, state variables and types

Basic★ Must knowLesson 1 of 11
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract SimpleBank {
    // ---- state variables (stored on-chain) ----
    address public immutable owner;            // set once in constructor, stored in bytecode (cheap to read)
    uint256 public constant MIN_DEPOSIT = 0.01 ether;   // compile-time constant
    uint256 public totalDeposits;
    mapping(address => uint256) public balances;        // public → auto-generated getter
    bool private paused;

    // ---- events & errors ----
    event Deposited(address indexed account, uint256 amount);
    event Withdrawn(address indexed account, uint256 amount);
    error InsufficientBalance(uint256 requested, uint256 available);
    error NotOwner();

    constructor() {
        owner = msg.sender;                    // deployer
    }

    modifier onlyOwner() {
        if (msg.sender != owner) revert NotOwner();
        _;                                     // continue with the function body
    }

    function deposit() external payable {
        require(msg.value >= MIN_DEPOSIT, "Deposit too small");
        balances[msg.sender] += msg.value;
        totalDeposits += msg.value;
        emit Deposited(msg.sender, msg.value);
    }

    function withdraw(uint256 amount) external {
        uint256 bal = balances[msg.sender];
        if (amount > bal) revert InsufficientBalance(amount, bal);
        balances[msg.sender] = bal - amount;   // update state BEFORE the external call (checks-effects-interactions)
        totalDeposits -= amount;
        (bool ok, ) = payable(msg.sender).call{value: amount}("");
        require(ok, "Transfer failed");
        emit Withdrawn(msg.sender, amount);
    }

    function setPaused(bool p) external onlyOwner { paused = p; }
}

Value types: bool, uint8…uint256 (uint = uint256), int8…int256, address (20 bytes) / address payable, bytes1…bytes32, enum. Reference types: arrays (uint[], uint[10]), bytes, string, struct, mapping(K => V) (no iteration, no length; every key exists with a default zero value).

Units: 1 ether = 1e18 wei, gwei; time units seconds, minutes, hours, days, weeks. No floating point — use integers with fixed decimals.

Global variables: msg.sender (immediate caller), msg.value (wei sent), msg.data, block.timestamp, block.number, block.chainid, tx.origin (original EOA — never use for auth), gasleft(), address(this).balance.