foundry
foundry copied to clipboard
feat(forge): inspect storage slot value
Motivation
After deploying the contract, it is often necessary to check whether the parameters are set successfully, so here is a simple method to query the value of the slot corresponding to the contract variable.
Solution
Obtain the value of the specified slot in the contract through getStorageAt, and then print it in a developer-friendly way to facilitate the review of related variables.
TODO
- [ ] fetch etherscan source and compile
- [ ] check upgradeable contract and implementation contract bytecode
- [ ] storage value for mapping, array and so on
- [ ] more tests
Imo this should be in Cast where we also already have cast storage
- could just add a flag or something to it to get this functionality
Imo this should be in Cast where we also already have
cast storage
- could just add a flag or something to it to get this functionality
It makes sense, maybe we need to expose more forge-related contract interfaces to cast, so that cast can expand more transaction-related details from a contract perspective.
I agree this is useful, but big +1 that this should not be part of forge. forge inspect
's purpose is to simply make solc output such as storage layout more accessible and readable.
Right now cast storage <address> <slot>
prints the the specified slot. Expanding on @onbjerg's suggestion, I'd propose cast storage <address>
(i.e. when no slot is specified) to behave as follows:
- Fetch the bytecode of the provided address.
- If we're in a foundry project, check artifacts for matching bytecode + recompile if needed to get storage layout.
- Otherwise, fetch source from etherscan and compile it with the specified settings to get storage layout (this is also useful for debugging txs against a live network where we'd recompile to get source maps).
- Print variable names, slots, sizes, offsets, and decoded values in a table similar to the existing one that you get with
forge inspect MyContract storage-layout --pretty
.
Note this PR does not properly handle dynamic types. It will print the length of an array for array types, and zero for mappings because it doesn't know the keys. I think that's ok for the first version, but I'd love for the next iteration to figure out array lengths and all mapping keys to print the all storage. @banteg has a POC for doing this here: https://github.com/banteg/storage-layout
Definitely +1 for @mds1 cast storage <address>
proposal, I think it would also be cool to have a --blocknumber
param that lets you do historical queries so that you can write a script that can see how state changes in a contract over a range of blocks
Agreed, --block <blockNumber/earliest/latest/pending>
is the syntax used elsewhere in cast which we should support here too
hey @b1u3h4t what are the best next steps here?
(we at a minimum want a unit test here)
Ping @b1u3h4t
On further thought I think we should go wiht @mds1 suggestion. Closing given stale, and we can revisit! Thanks!