Layout of a Source File

6.1 Structure

// SPDX-License-Identifier: MIT                 // 1. license identifier (machine-readable)
pragma solidity ^0.8.24;                        // 2. version pragma
pragma abicoder v2;                             //    (default since 0.8.0 — optional)

import "./Token.sol";                           // 3. imports
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import * as Utils from "./Utils.sol";

uint256 constant MAX_SUPPLY = 1_000_000e18;    // 4. file-level constants
error Unauthorized(address caller);             //    file-level errors
event Log(string message);                      //    file-level events (0.8.22+)
struct Point { uint128 x; uint128 y; }          //    file-level structs and enums
enum Status { Pending, Active, Closed }
type Price is uint256;                          //    user-defined value types

function square(uint256 x) pure returns (uint256) { return x * x; }   // free functions

interface IExample { function ping() external returns (bool); }
library MathLib { function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } }
abstract contract Base { function hook() internal virtual; }
contract Example is Base
…

6.2 SPDX license identifier

The compiler warns if it is missing. Common values: MIT, GPL-3.0-or-later, Apache-2.0, BUSL-1.1, UNLICENSED (proprietary).

6.3 Version pragmas

pragma solidity 0.8.28; pragma solidity ^0.8.20; ≥ 0.8.20 and < 0.9.0 pragma solidity >=0.8.4 <0.9.0; pragma experimental SMTChecker; old way to enable SMTChecker (now a compiler setting)

6.4 Imports

import "./A.sol";                         // imports all global symbols (discouraged — pollutes namespace)
import {A, B as Bee} from "./AB.sol";     // named imports (preferred)
import * as Lib from "./Lib.sol";         // namespace import: Lib.Something
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";   // resolved through remappings / node_modules

6.5 Comments and NatSpec

NatSpec tags: @title, @author, @notice, @dev, @param, @return, @inheritdoc, @custom:<name> (e.g., @custom:security-contact, @custom:oz-upgrades-unsafe-allow).

// single-line comment
/* multi-line
   comment */

/// @title Vault
/// @author Your Name
/// @notice Explains to end users what this does
/// @dev Explains to developers extra details
contract Vault {
    /// @notice Deposit Ether
    /// @param minShares Minimum shares expected (slippage protection)
    /// @return shares The number of shares minted
    function deposit(uint256 minShares) external payable returns (uint256 shares) {
        shares = msg.value;
        require(shares >= minShares, "slippage");
    }
}

6.6 Naming conventions (Solidity style guide)

Contracts, libraries, structs, events, errors, enums TokenVault, Transfer Functions, variables, modifiers balanceOf, onlyOwner UPPER_CASE or mixedCase (projects vary) OWNER, i_owner Private/internal members often _leadingUnderscore constructor, receive, fallback, external, public, internal, private; view/pure last within each group