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.
MemoryDump
EVM memory state snapshot captured during transaction execution. Memory is byte-addressable and organized in 32-byte words.
Overview
MemoryDump represents the complete memory state at a point in EVM execution. EVM memory grows dynamically during execution and is organized in 32-byte word boundaries for stack operations.
Type Definition
type MemoryDumpType = {
readonly data: Uint8Array; // Complete memory contents
readonly length: number; // Memory size in bytes
};
Usage
Creating Memory Dumps
import { MemoryDump } from '@tevm/voltaire/primitives';
// From raw bytes
const dump = MemoryDump.from(new Uint8Array(64));
// From object
const dump2 = MemoryDump.from({
data: memoryBytes,
length: 128
});
Reading Memory Words
EVM operations read memory in 32-byte chunks:
// Read first 32-byte word
const word = MemoryDump.readWord(dump, 0);
// Read second word
const word2 = MemoryDump.readWord(dump, 32);
// Read word at specific offset
const word3 = MemoryDump.readWord(dump, 64);
Slicing Memory
Extract memory ranges for analysis:
// First 64 bytes
const slice = MemoryDump.slice(dump, 0, 64);
// From offset to end
const tail = MemoryDump.slice(dump, 64);
// Specific range
const range = MemoryDump.slice(dump, 32, 96);
EVM Memory Model
Word-Aligned Operations
EVM stack operations work with 32-byte words:
MLOAD: Load 32-byte word from memory
MSTORE: Store 32-byte word to memory
MSTORE8: Store single byte to memory
Memory Expansion
Memory expands dynamically during execution with quadratic gas costs:
// Memory grows as needed
const initialSize = dump.length; // 64 bytes
// After MSTORE at offset 96
const expandedSize = 128; // Rounded up to 32-byte boundary
Gas Costs
Memory expansion incurs quadratic costs:
cost = (memory_size_word^2 / 512) + (3 * memory_size_word)
Debug Tracing
MemoryDump used with debug_traceTransaction for execution analysis:
// Trace with memory capture
const trace = await rpc.debug_traceTransaction(txHash, {
tracer: 'callTracer',
tracerConfig: {
withLog: true,
withMemory: true
}
});
// Analyze memory at each step
for (const step of trace.structLogs) {
if (step.memory) {
const dump = MemoryDump.from(step.memory);
const word = MemoryDump.readWord(dump, 0);
console.log('Memory word 0:', word);
}
}
Common Patterns
ABI Encoding Analysis
Memory contains ABI-encoded data during calls:
// Function selector (first 4 bytes of word 0)
const word0 = MemoryDump.readWord(dump, 0);
const selector = word0.slice(0, 4);
// First parameter (word 1)
const param1 = MemoryDump.readWord(dump, 32);
// Second parameter (word 2)
const param2 = MemoryDump.readWord(dump, 64);
Return Data
Return data stored in memory:
// Extract return data from memory
const returnDataOffset = 0;
const returnDataSize = 32;
const returnData = MemoryDump.slice(dump, returnDataOffset, returnDataSize);
API Reference
Constructors
MemoryDump.from(bytes) - Create from Uint8Array
MemoryDump.from({ data, length }) - Create from object
Methods
MemoryDump.readWord(dump, offset) - Read 32-byte word
MemoryDump.slice(dump, start, end?) - Extract memory range
See Also
- StateDiff - State changes during execution
- StorageDiff - Storage slot changes
- Hex - Hex encoding for memory display