Solidity Cheatsheet
Data Types
Use this Solidity reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
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 |