Solidity Cheatsheet
Data Types
Use this Solidity reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Value Types
Value types are copied on assignment. Stored in the EVM stack or directly in storage slots.
Integers
uint8 u8 = 255; // 0 to 2^8 - 1 uint256 u = 1_000_000; // 0 to 2^256 - 1 (most common) int256 i = -1; // -2^255 to 2^255 - 1 int8 i8 = -128; // Arithmetic (0.8+ reverts on overflow by default) uint256 a = type(uint256).max; // a + 1 reverts — use unchecked { } to skip the check unchecked { uint256 wrapped = a + 1; // 0 } // Common type(T) properties type(uint256).min // 0 type(uint256).max // 115792089237316195423570985008687907853269984665640564039457584007913129639935 type(int256).min // -2^255
| Type | Range | Gas slot |
|---|---|---|
uint8 … uint256 (steps of 8) | 0 to 2^N - 1 | packed if adjacent |
int8 … int256 (steps of 8) | -(2^(N-1)) to 2^(N-1) - 1 | packed if adjacent |
Use
uint256/int256for most arithmetic; smaller types save storage but cost extra gas for arithmetic due to masking.
Boolean
bool flag = true; bool other = !flag; // false bool result = flag && other; // short-circuits bool result2 = flag || other;
Address
address a = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2; // checksummed address payable p = payable(a); // can receive ether // Members a.balance; // wei balance (uint256) p.transfer(1 ether); // reverts on failure, 2300 gas stipend bool ok = p.send(1 ether);// returns false on failure, 2300 gas stipend (bool success, bytes memory data) = p.call{value: 1 ether}(""); // preferred // Type conversions address(this); // current contract as address address(uint160(someUint)); uint160(uint160(address(a)));
Fixed-Size Byte Arrays
bytes1 b1 = 0xFF; bytes32 b32 = keccak256("hello"); bytes32 b = 0xabcd; b[0]; // first byte (bytes32 is index 0 = leftmost) b.length; // 32 (fixed)
bytes32is the workhorse for hashes, identifiers, and packed storage.
Fixed-Point Numbers
Solidity declares fixed / ufixed but they are not yet implemented. Use integer arithmetic with explicit scaling (e.g., WAD = 1e18).
Enums
enum Status { Pending, Active, Closed } Status public state = Status.Pending; function close() external { state = Status.Closed; } // Casting uint8 n = uint8(Status.Active); // 1 Status s = Status(2); // Closed // type(Status).min / .max available since 0.8.8
User-Defined Value Types (0.8.8+)
type Price is uint256; type Timestamp is uint40; Price p = Price.wrap(1_000); uint256 raw = Price.unwrap(p); // Attach operators via library (0.8.19+) using {addPrices as +} for Price global; function addPrices(Price a, Price b) pure returns (Price) { return Price.wrap(Price.unwrap(a) + Price.unwrap(b)); }
Reference Types
Reference types must specify a data location: storage, memory, or calldata.
Arrays
// Fixed-size uint256[3] memory arr = [uint256(1), 2, 3]; // Dynamic — storage uint256[] public items; items.push(42); items.pop(); items.length; delete items[0]; // sets to 0, does NOT shrink array // Dynamic — memory (size fixed at creation) uint256[] memory buf = new uint256[](10); buf[0] = 99; // Calldata (read-only, cheapest for external args) function sum(uint256[] calldata nums) external pure returns (uint256 total) { for (uint i; i < nums.length; ++i) total += nums[i]; } // 2D uint256[][] public matrix;
Bytes and Strings
// bytes — arbitrary binary data bytes memory b = hex"deadbeef"; bytes memory b2 = abi.encodePacked(uint256(1)); b.push(0xFF); // only in storage b.length; b[0]; // string — UTF-8, no index access string memory s = "hello"; string memory joined = string.concat(s, " world"); // 0.8.12+ bytes memory asBytes = bytes(s); // convert to bytes for indexing uint len = bytes(s).length; // byte length, not character count // keccak256 comparison (no == for strings natively) keccak256(bytes(s)) == keccak256(bytes("hello"));
Structs
struct Point { uint256 x; uint256 y; } Point memory p = Point({ x: 1, y: 2 }); Point memory p2 = Point(3, 4); // positional // Storage struct — changes persist Point storage sp = points[0]; sp.x = 10; // writes directly to storage // Packing: order fields small-to-large for tight storage slots struct Packed { uint128 a; // slot 0 (bytes 0-15) uint128 b; // slot 0 (bytes 16-31) uint256 c; // slot 1 }
Mappings
mapping(address => uint256) public balances; mapping(address => mapping(address => uint256)) public allowances; balances[msg.sender] = 100; uint256 b = balances[msg.sender]; // unset keys return 0 delete balances[msg.sender]; // reset to 0 // Cannot iterate, cannot get length, cannot copy to memory // Keys are hashed — you cannot enumerate all keys
Type Conversions
// Implicit: smaller -> larger (safe) uint8 a = 1; uint256 b = a; // OK // Explicit: larger -> smaller (truncates) uint256 big = 500; uint8 small = uint8(big); // 244 (truncates high bits) // address <-> uint160 address addr = address(uint160(someUint)); uint160 n = uint160(addr); // bytes32 <-> bytes bytes32 h = bytes32(bytes("hello")); // right-pads bytes memory back = bytes(abi.encode(h)); // be careful with padding
Special Literals
// Hex literals bytes2 hx = hex"1234"; bytes memory hxMem = hex"deadbeef"; // Unicode literals string memory u = unicode"Hello ☃"; // snowman // Underscores in number literals (readability) uint256 million = 1_000_000; uint256 big = 1_000_000_000e18;
Default Values
| Type | Default |
|---|---|
uint / int | 0 |
bool | false |
address | address(0) |
bytes32 | bytes32(0) |
string | "" |
enum | first member (index 0) |
| array element | zero value of element type |
| struct | each field's zero value |