Value Types
Value types are copied when assigned or passed as arguments.
7.1 Booleans
bool public isActive = true;
// operators: ! && || == != (&& and || short-circuit)7.2 Integers
int8 … int256 and uint8 … uint256 in steps of 8 bits. uint = uint256, int = int256.
Number literals: 1_000_000, 1e18, 0xff, 2.5 ether (scientific notation and denominations are evaluated at compile time with arbitrary precision).
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Integers {
uint256 public maxU = type(uint256).max;
int256 public minI = type(int256).min;
uint8 public small = 200;
function examples() external pure returns (uint256, int256, uint256) {
uint256 a = 7 / 2; // 3 — integer division truncates toward zero
int256 b = -7 / 2; // -3
uint256 c = 2 ** 10; // 1024
// uint256 d = 1 / 0; // compile-time error; runtime division by zero → Panic(0x12)
return (a, b, c);
}
function conversions(uint256 big) external pure returns (uint8, uint256) {
uint8 truncated = uint8(big); // explicit narrowing keeps lowest 8 bits (no revert!)
uint256 widened = uint256(truncated); // widening is always safe (implicit also allowed)
return (truncated, widened);
}
}7.3 Fixed-point numbers (note)
fixed / ufixed (e.g., ufixed128x18) are declared but not fully supported — you can declare them but not assign to them. In practice, use integers scaled by a power of ten (e.g., 18-decimal "WAD" math: 1e18 represents 1.0) or libraries such as PRBMath, Solady FixedPointMathLib, or ABDK.
7.4 Addresses
20-byte value; has .balance, .code, .codehash, .call, .delegatecall, .staticcall address payable same plus .transfer and .send
Address literals must pass the EIP-55 checksum test (mixed case), e.g. 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4. address(0) is the zero address — often a sentinel for "unset"; tokens sent there are effectively burned.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Addresses {
function info(address a) external view returns (uint256 bal, uint256 codeSize, bytes32 codeHash) {
return (a.balance, a.code.length, a.codehash);
}
function toPayable(address a) external pure returns (address payable) {
return payable(a); // explicit conversion
}
function fromUint(uint160 x) external pure returns (address) {
return address(x);
}
}7.5 Fixed-size byte arrays
bytes1 … bytes32. Support comparison, bitwise operators, shifts, index access (b[i] read-only) and .length.
Prefer bytes32 over string for fixed short identifiers — it's cheaper.
bytes32 public hash = keccak256("hello");
bytes4 public selector = bytes4(keccak256("transfer(address,uint256)")); // 0xa9059cbb
bytes1 public first = hash[0];7.6 Enums
Converting an out-of-range integer to an enum reverts with Panic(0x21).
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Order {
enum Status { Pending, Shipped, Delivered, Cancelled } // stored as uint8; Pending = 0
Status public status; // defaults to the first member
function ship() external {
require(status == Status.Pending, "not pending");
status = Status.Shipped;
}
function limits() external pure returns (Status, Status) {
return (type(Status).min, type(Status).max); // Pending, Cancelled
}
}7.7 Default values
Every variable starts at its type's zero value: false, 0, address(0), bytes32(0), first enum member, empty string/bytes/array. There is no null or undefined.
7.8 Type conversions summary
uint8 → uint256 implicit (widening) uint256 → uint8 explicit; keeps low-order bits uint256 ↔ int256 explicit; reinterprets bits bytes32 → bytes4 explicit; keeps leftmost (high-order) bytes uint160 ↔ address address → address payable bytes → string
string(b) (explicit, no copy semantics change) contract → address