Ethereum

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

#NameTypeRequiredDescription
1addressstring (hex)YesThe contract whose storage to read.
2storageSlotstring (hex)YesStorage position to read. For mappings, this is the keccak256-derived slot.
3blockTagstringNoBlock at which to read.Default: latest

Response

TypeDescription
string (hex)32-byte hex-encoded value stored at the slot, left-padded with zeros.

Example request

curl https://ethereum.therpc.io/YOUR_API_KEY \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getStorageAt",
"params": [
"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"0x0",
"latest"
],
"id": 1
}'

Try it live in the Ethereum playground.

Errors & troubleshooting

CodeMessageCause
-32602Invalid paramsAddress or slot index is malformed.
-32000Missing trie nodeHistorical 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/address fields 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 k lives at keccak256(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"

curl https://ethereum.therpc.io/YOUR_API_KEY \
-X POST \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getStorageAt","params":["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045","",""]}'

Ready to call this in production?

Free tier covers personal projects. Pay-as-you-go scales without a card.