2

Is it possible to view the amount of storage a smart contract uses from an existing tool? Or if not is it possible to determine it by making json rpc calls?

There are a few similar questions such as the following, however none of the answers are satisfactory:

They all suggest using the eth_getStorageAt json rpc method. However that doesn't seem to work too well with dynamic variables such as mappings.

I'd appreciate it if anyone could provide a function that works on a common Ethereum mainnet smart contract that has dynamic data types such as mappings and lists.

Edit: The recently released Slots dataset by Paradigm seems to indicate that it is in fact possible to determine the exact storage a contract uses.

3 Answers 3

0

The actual size of a smart contract cannot be determined dynamically since it's a different way that Ethereum stores it. It means that the actual storage size of a smart contract can differ from the theoretical size due to the way that EVM packs data into storage slots.

And, since we cannot know the size of maps, we can also not determine the size it takes according to the data type.

Hence, it is not possible to view the amount of storage a smart contract uses.

Hope this helps!

1
  • Thanks for the answer, can you provide authoritative references?
    – MShakeG
    Mar 15 at 6:59
0

it works for static variables and addresses but not for dynamic data types.

To estimate the storage used by a smart contract with dynamic data types, you can follow these steps:

Analyze the contract's source code to identify the storage variables, especially the dynamic data types like mappings and arrays.

Deploy the contract or interact with an existing contract on the Ethereum mainnet.

Monitor and record the gas usage for transactions interacting with the contract.

The gas usage can give you an estimate of the storage consumption since a significant portion of the gas is spent on storage operations.

Unfortunately, there isn't an existing function or tool that can provide an accurate measurement of storage consumption for dynamic data types directly. The closest solution is using gas consumption as a proxy to estimate storage usage.

3
  • How would EIPs related to storage rent such as github.com/ethereum/EIPs/issues/1418 work if the exact storage a smart contract uses is not easily computable?
    – MShakeG
    Mar 16 at 6:58
  • EIPs related to storage rent, like EIP-1418, aim to address the ever-increasing state size in the Ethereum blockchain by introducing fees for storing data. However, accurately determining the storage usage of a smart contract is a challenge. Potential solutions include making assumptions and approximations based on gas costs or base storage requirements, although these methods may be imperfect or prone to manipulation. More sophisticated mechanisms or protocol changes might be necessary to track storage usage more precisely and effectively implement storage rent
    – vgonearth
    Mar 16 at 11:29
  • Can you provide authoritative references?
    – MShakeG
    Mar 17 at 5:50
0

I was working on a tool, which can export the storage dumps for a contract, and this is what I've found out, what you could possibly do:

  1. Read the database directly. For example, you could extend the go-ethereum to use the ForEachStorage method for iterating the all storage slots for an Address.

  2. Index all transactions with debug_traceTransaction to find out all storage modifications of the contract. You must analyze not just the direct contract transactions, but also the so-called "Internal Transaction" to find out all the method calls.

  3. It turns out, if you have the source code of the contract, the only problem is the mapping type. For all other dynamic types, like string, bytes, or array you have the length value in the storage. From the source code you'll get:

    1. Storage variables and their types.
    2. Slots locations, also you can handle the storage packing.
    3. Work-around the mapping issue with Logs, though not always to 100%. Often, when a contract modifies the mapping it emits some sort of event, which you could parse out from the source code. For example in IERC20: when we transfer tokens from A to B, we have a Transfer event emitted. And fetch the logs for a contract is way easier than the previous options.

I've decided to go the 3rd way:

  1. Extending the go-etherem would require direct access to the blockchains directory, and it is difficult to maintain various EVM blockchains.
  2. To index traces would take too much time
  3. It Doesn't support all contracts to 100%, but for your own and well-implemented contracts it would work and supports all EVMs.

You can take a look into:

  • SlotsParser.ts how to extract state variables, their types and locations from the source code.
  • MappingSettersResolver.ts how to parse solidity contracts to find all mapping mutations and corresponding Logs with MappingKey parameter, (if any)
  • SlotsDump.ts how to export contract's storage as the Key-Value slots and as the JSON object.

You can try out with:

npm i 0xweb -g
0xweb i 0xccf4429db6322d5c611ee964527d42e5d685dd6a --name compoundWBTC --chain eth --implementation 0x3363BAe2Fc44dA742Df13CD3ee94b6bB868ea376
0xweb c dump compoundWBTC --output storage/compound

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.