Ethereum
eth_getStorageAt
eth_getStorageAt reads one raw 32-byte word straight out of a contract's storage on Ethereum mainnet (chain ID 1, the EVM network whose gas is paid in ETH). Every contract keeps its state in a flat key-value store of 256-bit slots, and this method returns the value at the slot you name — no ABI, no getter function required. You give it a contract address, a slot index, and a block, and it answers with the 32-byte value left-padded with zeros. Pass a historical block and you read the slot as it stood at that height, not just at the head. The endpoint is https://ethereum.therpc.io/YOUR_API_KEY. It's the unfiltered counterpart to calling a public view function: closer to the metal, and it works even when no getter is exposed.
Use cases
- Read a proxy's implementation address straight from the EIP-1967 logic slot (
0x360894...bbc) when the contract exposes no getter for it. - Inspect on-chain governance directly — proposal state, vote tallies, queued timelock actions in a MakerDAO/Sky or Compound-style system — by reading the slots those values live in.
- During an audit, confirm a deployed contract's storage layout matches the source by reading known slots and checking the values line up.
- Debug surprising state: when a view function returns something you didn't expect, drop to the raw slot to see what's actually written underneath.
Parameters
| # | Name | Type | Required | Description |
|---|---|---|---|---|
| 1 | address | string (hex) | Yes | The contract whose storage to read. |
| 2 | storageSlot | string (hex) | Yes | Storage position to read. For mappings, this is the keccak256-derived slot. |
| 3 | blockTag | string | No | Block at which to read.Default: latest |
Response
| Type | Description |
|---|---|
| string (hex) | 32-byte hex-encoded value stored at the slot, left-padded with zeros. |
Example request
Try it live in the Ethereum playground.
Errors & troubleshooting
| Code | Message | Cause |
|---|---|---|
-32602 | Invalid params | Address or slot index is malformed. |
-32000 | Missing trie node | Historical block pruned on a non-archive node. |
Common pitfalls
- Storage layout isn't in the ABI. Solidity assigns slots by declaration order, so you have to know or derive which slot holds which variable, often by reading the compiler's storage-layout output.
- Small variables get packed together: several
uint8/bool/addressfields can share one 32-byte slot. Reading that slot gives you all of them at once, and you mask and shift to pull out the field you want. - Mapping entries don't sit at the base slot. A value for key
klives atkeccak256(abi.encode(k, baseSlot)), so you compute that hash first, then read it — the base slot itself is empty.
Supported networks
- Mainnet — Chain ID: 1
- Sepolia — Chain ID: 11155111
See also
Parameters
0x-prefixed 20-byte contract address
0x-prefixed 32-byte slot index (e.g. "0x0")
hex block number or "latest"/"earliest"/"pending"/"safe"/"finalized"