State Access — Storage Visibility
Blocked by default. Available only when the server is running with
--unrestricted.
Subscribe
{"subscribe": ["AccountAccess", "StorageAccess"]}
Available types: AccountAccess, StorageAccess, AccountAccessListHeader.
Description
State Access events provide execution-level storage visibility: which accounts and storage slots the EVM touches during execution. This information is not available through standard JSON-RPC.
These events are blocked by default because:
- They generate a high event volume (thousands of events per block)
- They are intended for specialized consumers (analytics, indexers)
Check blocked_events in the Hello frame to confirm.
Event Types
AccountAccess
EVM access to account state.
| Payload Field | Type | Description |
|---|---|---|
txn_index | number | null | Transaction index |
address | string | Account address |
balance | string | Balance (hex U256) |
nonce | number | Account nonce |
code_hash | string | Contract code hash |
StorageAccess
Read or write to a storage slot.
| Payload Field | Type | Description |
|---|---|---|
txn_index | number | null | Transaction index |
account_index | number | Account index (reference) |
key | string | Storage slot key (bytes32) |
value | string | Storage slot value (bytes32) |
AccountAccessListHeader
Header for a batch of account accesses.
| Payload Field | Type | Description |
|---|---|---|
txn_index | number | null | Transaction index |
entry_count | number | Number of AccountAccess entries following |
Filtering
To track a specific account, use the advanced subscription:
{
"subscribe": {
"events": ["AccountAccess"],
"filters": [{
"event_name": "AccountAccess",
"field_filters": [
{"field": "address", "filter": {"values": ["0xTARGET_ADDRESS"]}}
]
}]
}
}
Note: the
addressfilter in the AccountAccess context applies to the payloadaddressfield (not the TxnLog address field).
Usage Example
Monitor Account Accesses
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.Events) {
for (const e of msg.Events) {
if (e.event_name === "AccountAccess") {
console.log(`Account ${e.payload.address}: balance=${e.payload.balance}, nonce=${e.payload.nonce}`);
}
if (e.event_name === "StorageAccess") {
console.log(`Storage [${e.payload.key}] = ${e.payload.value}`);
}
}
}
};
Frequency
Very high, thousands of events per block. Use filters and fast processing, otherwise backpressure is inevitable.