Documentation Index
Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
Use this file to discover all available pages before exploring further.
GasCosts
Constants for gas costs of EVM operations, based on Yellow Paper Appendix G and various EIPs.
Constants
Transaction Costs
import { GAS_COSTS } from '@tevm/primitives';
GAS_COSTS.TRANSACTION // 21000n - Base transaction cost
GAS_COSTS.CREATE // 32000n - Contract creation
GAS_COSTS.CALL_VALUE // 9000n - Non-zero value transfer
GAS_COSTS.CALL_STIPEND // 2300n - Stipend for call with value
Storage Operations
GAS_COSTS.SLOAD // 2100n - Cold SLOAD (EIP-2929)
GAS_COSTS.SLOAD_WARM // 100n - Warm SLOAD
GAS_COSTS.SSTORE_SET // 20000n - Zero to non-zero
GAS_COSTS.SSTORE_RESET // 5000n - Non-zero to non-zero
GAS_COSTS.SSTORE_CLEAR // 15000n - Refund (pre-London)
Account Access (EIP-2929)
GAS_COSTS.BALANCE // 2600n - Cold BALANCE
GAS_COSTS.EXTCODECOPY // 2600n - Cold EXTCODECOPY
GAS_COSTS.COLD_ACCOUNT_ACCESS // 2600n - Cold account
GAS_COSTS.WARM_STORAGE_READ // 100n - Warm access
Logging
GAS_COSTS.LOG // 375n - LOG0 base
GAS_COSTS.LOG_TOPIC // 375n - Per topic
GAS_COSTS.LOG_DATA // 8n - Per byte of data
Calldata
GAS_COSTS.CALLDATA_ZERO // 4n - Zero byte
GAS_COSTS.CALLDATA_NONZERO // 16n - Non-zero byte
Memory & Copying
GAS_COSTS.MEMORY // 3n - Per word expansion
GAS_COSTS.COPY // 3n - Per word copy
Cryptographic Operations
GAS_COSTS.SHA3 // 30n - KECCAK256 base
GAS_COSTS.SHA3_WORD // 6n - Per word
GAS_COSTS.BLOCKHASH // 20n - BLOCKHASH opcode
Other Operations
GAS_COSTS.SELFDESTRUCT // 5000n - SELFDESTRUCT
GAS_COSTS.CALL // 100n - Base message call
GAS_COSTS.EXP // 10n - EXP base
GAS_COSTS.EXP_BYTE // 50n - EXP per byte
GAS_COSTS.JUMPDEST // 1n - JUMPDEST
Opcode Cost Tiers
GAS_COSTS.BASE // 2n - Most opcodes
GAS_COSTS.VERY_LOW // 3n - ADD, SUB, etc
GAS_COSTS.LOW // 5n - MUL, DIV, etc
GAS_COSTS.MID // 8n - ADDMOD, MULMOD
GAS_COSTS.HIGH // 10n - JUMPI
Block Limits
import { BLOCK_GAS_LIMITS } from '@tevm/primitives';
BLOCK_GAS_LIMITS.MAINNET // 30_000_000n - Typical mainnet
BLOCK_GAS_LIMITS.MINIMUM // 5000n - EIP-1559 minimum
Transaction Type Costs
import { TRANSACTION_COSTS } from '@tevm/primitives';
TRANSACTION_COSTS.SIMPLE_TRANSFER // 21000n
TRANSACTION_COSTS.ERC20_TRANSFER // 65000n
TRANSACTION_COSTS.UNISWAP_SWAP // 150000n
TRANSACTION_COSTS.CONTRACT_DEPLOY // 32000n (base)
Usage Examples
Calculate Calldata Cost
import { GAS_COSTS } from '@tevm/primitives';
function calculateCalldataCost(data: Uint8Array): bigint {
let cost = 0n;
for (const byte of data) {
cost += byte === 0
? GAS_COSTS.CALLDATA_ZERO
: GAS_COSTS.CALLDATA_NONZERO;
}
return cost;
}
const calldata = new Uint8Array([0x00, 0x01, 0x02]);
const cost = calculateCalldataCost(calldata);
// 4n + 16n + 16n = 36n
Calculate LOG Cost
import { GAS_COSTS } from '@tevm/primitives';
function calculateLogCost(topics: number, dataBytes: number): bigint {
const baseCost = GAS_COSTS.LOG;
const topicCost = BigInt(topics) * GAS_COSTS.LOG_TOPIC;
const dataCost = BigInt(dataBytes) * GAS_COSTS.LOG_DATA;
return baseCost + topicCost + dataCost;
}
// LOG3 with 64 bytes of data
const cost = calculateLogCost(3, 64);
// 375n + (3 × 375n) + (64 × 8n) = 1887n
Estimate Transaction Base Cost
import { GAS_COSTS, TRANSACTION_COSTS } from '@tevm/primitives';
function estimateTransactionCost(
calldata: Uint8Array,
hasValue: boolean
): bigint {
let cost = GAS_COSTS.TRANSACTION; // 21000n base
// Add calldata cost
for (const byte of calldata) {
cost += byte === 0
? GAS_COSTS.CALLDATA_ZERO
: GAS_COSTS.CALLDATA_NONZERO;
}
// Add value transfer cost
if (hasValue) {
cost += GAS_COSTS.CALL_VALUE;
}
return cost;
}
Compare Storage Operations
import { GAS_COSTS } from '@tevm/primitives';
const operations = {
'Set (0 → X)': GAS_COSTS.SSTORE_SET,
'Reset (X → Y)': GAS_COSTS.SSTORE_RESET,
'Clear (X → 0)': GAS_COSTS.SSTORE_RESET, // Cost to clear
'Load (cold)': GAS_COSTS.SLOAD,
'Load (warm)': GAS_COSTS.SLOAD_WARM,
};
for (const [op, cost] of Object.entries(operations)) {
console.log(`${op}: ${cost} gas`);
}
EIP Changes
EIP-2929 (Berlin)
Cold vs warm access distinction:
// Pre-EIP-2929
SLOAD: 800 gas (always)
// Post-EIP-2929
SLOAD (cold): 2100 gas (first access)
SLOAD (warm): 100 gas (subsequent access)
EIP-3529 (London)
Refund reduction:
// Pre-EIP-3529
SSTORE clear refund: 15000 gas
SELFDESTRUCT refund: 24000 gas
// Post-EIP-3529
SSTORE clear refund: 15000 gas (capped at gasUsed/5)
SELFDESTRUCT refund: 0 gas
EIP-1559 (London)
Changed fee structure but not gas costs:
// Gas costs unchanged
// But introduced:
// - Base fee (burned)
// - Priority fee (to miner)
// - Max fee per gas
Cost Categories
Cheap Operations (≤ 10 gas)
- Stack operations: PUSH, POP, DUP, SWAP
- Arithmetic: ADD, SUB, MUL, DIV
- Logic: AND, OR, XOR, NOT
- Comparison: LT, GT, EQ
Medium Operations (10-100 gas)
- SHA3/KECCAK256: 30 + 6 per word
- BLOCKHASH: 20
- Message calls (base): 100
Expensive Operations (100-2600 gas)
- SLOAD (warm): 100
- SLOAD (cold): 2100
- Account access (cold): 2600
Very Expensive Operations (5000-20000 gas)
- SSTORE (reset): 5000
- SELFDESTRUCT: 5000
- SSTORE (set): 20000
Transaction Base Costs (≥ 21000 gas)
- Simple transfer: 21000
- Contract creation: 32000+
- Complex interactions: 50000-1000000+
Memory Costs
Memory expansion is quadratic:
const memoryCost = (words: bigint): bigint => {
return (GAS_COSTS.MEMORY * words) + (words * words) / 512n;
};
memoryCost(10n); // 30n + 0n = 30n
memoryCost(100n); // 300n + 19n = 319n
memoryCost(1000n); // 3000n + 1953n = 4953n
See Also