Track EVM storage state changes for smart contracts through the SQD Portal — sample queries for analyzing slot writes, account changes, and code updates.
The kind field indicates the type of state change:
Kind
Meaning
Description
=
Unchanged
Storage slot was accessed but not modified
+
Added
New storage slot created
*
Modified
Existing storage slot value changed
-
Removed
Storage slot deleted (SSTORE with zero value)
// Filter only modificationsfor (const block of blocks) { if (block.stateDiffs) { for (const diff of block.stateDiffs) { if (diff.kind === "*") { console.log(`Modified at block ${block.header.number}`); console.log(` ${diff.prev} → ${diff.next}`); } } }}
Monitor a specific storage slot (e.g., owner variable):
// Example: Track owner changes// Owner is typically at slot 0 for many contractsconst OWNER_SLOT = "0x0000000000000000000000000000000000000000000000000000000000000000";const blocks = await dataSource.getBlocks({ from: 19000000, to: 19000003, fields: { block: { number: true, timestamp: true }, stateDiff: { address: true, key: true, prev: true, next: true, }, }, stateDiffs: [ { address: ["0xYourContractAddress"], }, ],});for (const block of blocks) { if (block.stateDiffs) { for (const diff of block.stateDiffs) { if (diff.key === OWNER_SLOT) { console.log({ block: block.header.number, timestamp: block.header.timestamp, previousOwner: diff.prev, newOwner: diff.next, }); } } }}
For mappings, the storage key is computed as keccak256(abi.encode(mappingKey, slot)). You’ll need to compute this off-chain to track specific mapping entries.