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.
New to EVM state? Start with Fundamentals for guided examples and Merkle Patricia Trie concepts.
Type Definition
Composite key primitive uniquely identifying storage locations in the Ethereum Virtual Machine by combining contract address with storage slot.
export type BrandedStorageKey = {
readonly address: AddressType;
readonly slot: bigint;
};
StorageKey combines a 20-byte contract address with a 256-bit storage slot number, enabling efficient tracking of contract state across multiple contracts in a single VM instance.
Quick Reference
API Methods
Constructors
StorageKey() - Factory function creating storage key from address and slot
from() - Universal constructor from various inputs
Serialization
Comparison & Type Guards
equals() - Compare two storage keys for equality
is() - Type guard checking if value is StorageKey
Utilities
Types
BrandedStorageKey
StorageKeyLike
export type BrandedStorageKey = {
readonly address: AddressType;
readonly slot: bigint;
};
Main type combining contract address with storage slot. Design rationale:
- Each contract has 2^256 storage slots
- Each slot stores 256-bit value
- Slots initially zero, consume gas on first write
type StorageKeyLike =
| BrandedStorageKey
| {
address: AddressType;
slot: bigint;
};
Union type accepting any input coercible to storage key. Accepted by StorageKey.from().See from for details.
Usage Patterns
Basic Storage Operations
import * as State from 'tevm/State';
import * as Address from 'tevm/Address';
// Create storage key
const contractAddr = Address("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
const key = State.StorageKey(contractAddr, 0n);
// Use in storage maps
const storage = new Map<string, bigint>();
storage.set(State.StorageKey.toString(key), 1000000000n);
// Retrieve value
const value = storage.get(State.StorageKey.toString(key)); // 1000000000n
String Serialization
import * as State from 'tevm/State';
const key = State.StorageKey(contractAddress, 42n);
// Convert to string for map keys
const keyStr = State.StorageKey.toString(key);
// "0x742d35cc6634c0532925a3b844bc9e7595f51e3e:42"
// Parse from string
const parsed = State.StorageKey(keyStr);
// { address: AddressType(...), slot: 42n }
// Round-trip conversion
State.StorageKey.equals(key, parsed); // true
Storage Slot Computation
import * as State from 'tevm/State';
import * as Address from 'tevm/Address';
import { Keccak256 } from 'tevm/crypto';
// USDC contract
const usdcAddress = Address("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
// Storage slot 0: total supply
const totalSupplyKey = State.StorageKey(usdcAddress, 0n);
// Mapping storage: balanceOf[userAddress]
// Slot = keccak256(abi.encode(userAddress, balanceSlot))
const userAddress = Address("0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e");
const balanceSlot = 1n;
// Compute mapping slot (Solidity storage layout)
const mappingSlotBytes = Bytes64();
mappingSlotBytes.set(userAddress, 0); // First 32 bytes (padded address)
mappingSlotBytes.set(encodeBigInt(balanceSlot, 32), 32); // Last 32 bytes
const computedSlot = BigInt(Hex.fromBytes(
Keccak256.hash(mappingSlotBytes)
).toString('hex'));
const userBalanceKey = State.StorageKey(usdcAddress, computedSlot);
Multi-Contract State
import * as State from 'tevm/State';
// Track state across multiple contracts
const stateDb = new Map<string, bigint>();
// USDC total supply
const usdcKey = State.StorageKey(usdcAddress, 0n);
stateDb.set(State.StorageKey.toString(usdcKey), 1000000000n);
// DAI total supply
const daiKey = State.StorageKey(daiAddress, 0n);
stateDb.set(State.StorageKey.toString(daiKey), 5000000000n);
// Query by contract
for (const [keyStr, value] of stateDb.entries()) {
const key = State.StorageKey(keyStr);
if (Address.equals(key.address, usdcAddress)) {
console.log(`USDC slot ${key.slot}: ${value}`);
}
}
Type Guards
import * as State from 'tevm/State';
function processStorage(key: unknown) {
if (State.StorageKey.is(key)) {
// TypeScript knows key is BrandedStorageKey
console.log(`Address: ${Address.toHex(key.address)}`);
console.log(`Slot: ${key.slot}`);
}
}
Tree-Shaking
Import only what you need for optimal bundle size:
// Import specific functions (tree-shakeable)
import { StorageKey, toString, fromString } from 'tevm/State';
const key = StorageKey(contractAddress, 0n);
const keyStr = toString(key);
const parsed = fromString(keyStr);
// Only these 3 functions included in bundle
Core Documentation
API Methods
- Address - Contract address type
- Uint - 256-bit unsigned integers for slot values
- Keccak256 - Keccak256 hashing for state roots
Specification