evm_storage

package
v0.10.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2025 License: MIT Imports: 10 Imported by: 1

README

Solidity Smart Contracts Storage Layout Utilities

This code is used in e2e tests where we need to modify production contracts with Anvil's anvil_setStorageAt.

See a simple example where we override different types struct

Run it with (devbox shell)

./setup.sh
go test -v -run TestLayoutAPI
./teardown.sh

This test is more like a playground for you to figure out proper encoding for encodeFunc and use in your e2e tests.

See more package tests as examples.

Layout in testdata/layout.json can be found in out after forge build for any contract.

To double-check the layout you can also use forge inspect <ContractName> storageLayout in your forge directory.

To add more types for tests use forge build && forge inspect Counter storageLayout --json > ../testdata/layout.json

Useful Debug Commands

anvil &
forge script script/Deploy.s.sol:Deploy --rpc-url http://127.0.0.1:8545 --broadcast

forge script script/Counter.s.sol --rpc-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80  --broadcast

cast storage 0x5FbDB2315678afecb367f032d93F642f64180aa3 0x1 --rpc-url http://localhost:8545

cast call 0x5FbDB2315678afecb367f032d93F642f64180aa3 \
 "number()(uint256)" \
 --rpc-url http://localhost:8545
 
 cast call 0x5FbDB2315678afecb367f032d93F642f64180aa3 \
 "values(uint256)(uint256)" 0 \
 --rpc-url http://localhost:8545
 
  cast call 0x5FbDB2315678afecb367f032d93F642f64180aa3 \
 "scores(address)(uint256)" 0x5FbDB2315678afecb367f032d93F642f64180aa3 \
 --rpc-url http://localhost:8545

cast send 0x5FbDB2315678afecb367f032d93F642f64180aa3 \
  "increment()" \
  --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
  --rpc-url http://localhost:8545
  
 cast --to-uint256 200 | cast --to-bytes32
 
 cast rpc anvil_setStorageAt \
  0x5FbDB2315678afecb367f032d93F642f64180aa3 \
  0x0 \
  0x000000000000000000000000000000000000000000000000000000000000002c

Documentation

Index

Constants

View Source
const (
	StorageSlotSizeBytes = 32
)

Variables

View Source
var (
	ErrNoSlot = errors.New("no such slot found in layout JSON")
)

Functions

func MergeHex

func MergeHex(a, b string) string

MergeHex merges two hex strings with bitwise "OR" should be used when you see values with offsets in smart contract storage layout.json file

Example layout:
╭----------------+-------------------------------------------+------+--------+-------+-------------------------╮
| Name           | Type                                      | Slot | Offset | Bytes | Contract                |
|----------------+-------------------------------------------+------+--------+-------+-------------------------|
| number_uint8   | uint8                                     | 3    | 0      | 1     | src/Counter.sol:Counter |
|----------------+-------------------------------------------+------+--------+-------+-------------------------|
| boolean        | bool                                      | 3    | 1      | 1     | src/Counter.sol:Counter |
|----------------+-------------------------------------------+------+--------+-------+-------------------------|

func MustEncodeStorageSlot

func MustEncodeStorageSlot(solidityType string, value interface{}) string

MustEncodeStorageSlot encodes a value for Solidity storage slots based on type Panics if encoding fails

func ShiftHexByOffset

func ShiftHexByOffset(hexStr string, offset uint) string

ShiftHexByOffset is used to set values in slots with offsets

Types

type StorageEntry

type StorageEntry struct {
	Label  string `json:"label"`
	Slot   string `json:"slot"`
	Type   string `json:"type"`
	Offset int    `json:"offset"`
}

type StorageLayout

type StorageLayout struct {
	Storage []StorageEntry `json:"storage"`
}

func New

func New(filename string) (*StorageLayout, error)

New creates a new storage layout wrapper

func (*StorageLayout) GetSlots

func (s *StorageLayout) GetSlots() map[string]string

func (*StorageLayout) MustArraySlot

func (s *StorageLayout) MustArraySlot(label string, index int64) string

MustArraySlot calculates a slot in Solidity array for storage field and a key

func (*StorageLayout) MustMapSlot

func (s *StorageLayout) MustMapSlot(label, key string) string

MustMapSlot calculates a slot in Solidity mapping for storage field and a key

func (*StorageLayout) MustSlot

func (s *StorageLayout) MustSlot(label string) string

MustSlot calculates a slot in Solidity mapping for storage field and a key

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL