Value types
Value types are copied when assigned or passed to functions. They live entirely in the variable — no pointer magic.
Integers
uint8 small = 255; // unsigned, 8-bit (0 to 255)
uint256 big = 1e18; // unsigned, 256-bit (most common)
int256 signed = -100; // signed integerInteger 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
bool isActive = true;
bool hasVoted = false;Addresses
An address holds a 20-byte Ethereum address. address payable can receive Ether.
address owner = 0xAbCd...;
address payable treasury = payable(0xAbCd...);Bytes and strings
bytes32 hash = keccak256(abi.encodePacked('hello'));
string name = 'Doodledapp'; // dynamic size, stored in memory or storagePrefer 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.
// 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.
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.
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;
}
}