Data types and variables

Solidity's type system is strict and storage-aware. Here's what you need to know.

Value types

Value types are copied when assigned or passed to functions. They live entirely in the variable — no pointer magic.

Integers

solidity
uint8 small = 255;       // unsigned, 8-bit (0 to 255)
uint256 big = 1e18;      // unsigned, 256-bit (most common)
int256 signed = -100;    // signed integer

Integer overflow and underflow were historically a major bug source. Since Solidity 0.8.0, arithmetic reverts on overflow by default — no need for SafeMath.

Booleans

solidity
bool isActive = true;
bool hasVoted = false;

Addresses

An address holds a 20-byte Ethereum address. address payable can receive Ether.

solidity
address owner = 0xAbCd...;
address payable treasury = payable(0xAbCd...);

Bytes and strings

solidity
bytes32 hash = keccak256(abi.encodePacked('hello'));
string name = 'Doodledapp';  // dynamic size, stored in memory or storage

Prefer bytes32 over string for fixed-size identifiers — it's cheaper to store and compare.

Reference types

Reference types — arrays, structs, mappings, and strings — don't copy their data on assignment. You must specify a data location: storage, memory, or calldata.

solidity
// storage: persisted on-chain
uint256[] public storedNumbers;

// memory: temporary, exists only during the function call
function process(uint256[] memory input) public pure returns (uint256) {
    return input.length;
}

// calldata: read-only, for external function parameters
function processCalldata(uint256[] calldata input) external pure returns (uint256) {
    return input.length;
}

State vs. local variables

State variables are declared at the contract level. They persist between transactions and cost gas to write. Local variables (declared inside functions) live only for the duration of the call.

solidity
contract Example {
    uint256 public counter;   // state variable — stored on-chain

    function increment() public {
        uint256 temp = counter + 1;  // local variable — in memory
        counter = temp;              // write to state — costs gas
    }
}

Constants and immutables

For values that don't change, constant and immutable save significant gas because they're inlined at compile time or set once at deployment.

solidity
contract Token {
    uint256 public constant MAX_SUPPLY = 1_000_000 * 1e18;  // compile-time constant
    address public immutable deployer;                        // set once in constructor

    constructor() {
        deployer = msg.sender;
    }
}
←   Your first contractFunctions and visibility   →