In Brownie console, for a deployed contract, public contract attributes can be accessed with contract.nameOfAttribute()
. This does not work for private attributes - how can one access private attribute values from the Brownie console? More generally, how does one dump the ongoing contract's state/storage from the Brownie console?
Add a comment
|
1 Answer
- Here is the original code using
web3.py
- I have updated this version for
brownie
#!/usr/bin/python3
from brownie import web3
from hexbytes import HexBytes
def display_storage(address, height=100, width=100):
for i in range(100):
# Regular slots
rs = web3.eth.get_storage_at(address, i)
if rs != HexBytes(
"0x0000000000000000000000000000000000000000000000000000000000000000"
):
print(i, rs)
# Slots for large values
slot = web3.solidityKeccak(["uint256"], [i])
slot_int = int(slot.hex(), 16)
for j in range(100):
s = web3.eth.get_storage_at(address, slot_int + j)
if s != HexBytes(
"0x0000000000000000000000000000000000000000000000000000000000000000"
):
print(slot_int + j, s)
display_storage("0x876807312079af775c49c916856A2D65f904e612")
If you get an error like this
ValueError: {'code': -32602, 'message': 'Errors encountered in param 1: Storage slot argument must have a length of 66 ("0x" + 32 bytes), but \'0x0\' has a length of 3', 'data': {'message': 'Errors encountered in param 1: Storage slot argument must have a length of 66 ("0x" + 32 bytes), but \'0x0\' has a length of 3'}}
- You can fix this by modifying the value of
i
fromint
to32 bytes
hex str. Updated script.
#!/usr/bin/python3
from brownie import web3
from hexbytes import HexBytes
def display_storage(address, height=100, width=100):
for i in range(100):
# Regular slots
rs = web3.eth.get_storage_at(address, i.to_bytes(32, byteorder="big")).hex()
if rs != "0x0000000000000000000000000000000000000000000000000000000000000000":
print(i, rs)
# Slots for large values
slot = i.to_bytes(32, byteorder="big")
slot_int = int.from_bytes(slot, byteorder="big")
for j in range(100):
s = web3.eth.get_storage_at(
address, "0x" + hex(slot_int + j)[2:].zfill(64)
).hex()
# print(s)
if (
s
!= "0x0000000000000000000000000000000000000000000000000000000000000000"
):
print(i, s)
if __name__ == "__main__":
display_storage("0x876807312079af775c49c916856A2D65f904e612")
- Notice the value of
i
now changed toi.to_bytes(32, byteorder="big")