1

There are 3 variables in one slot(number2) in my contract:

  uint8 private flattening = 10; //2
  uint8 private denomination = 255; //2
  uint16 private awkwardness = uint16(block.timestamp); //2

This is the data that I receive from getstorageAt():

Slot 2 0x000000000000000000000000000000000000000000000000000000008430ff0a

I know how to decode it with 1 variable, but I can't find how to do it with several uints.I tried to do this :

value = "0x000000000000000000000000000000000000000000000000000000008430ff0a"
    
y = ethers.utils.defaultAbiCoder.decode(["uint8","uint8","uint16"],value)
console.log(y)

And I got an error:

const error: any = new Error(message);
                           ^
Error: data out-of-bounds (length=32, offset=64, code=BUFFER_OVERRUN, version=abi/5.7.0)

I'm sure that these 3 variable are in my 2nd slot:

  bool public locked = true; //0
  uint256 public ID = block.timestamp; //1
  uint8 private flattening = 10; //2
  uint8 private denomination = 255; //2
  uint16 private awkwardness = uint16(block.timestamp); //2
  bytes32[3] private data;//3-4-5

Maybe I need to slice this bytes32 somehow? Thanks for your help.

2
  • where are you assigning const: error ? can you post it?
    – immaxkent
    Commented Dec 16, 2022 at 16:06
  • You should first try with decoding only two uint8 values. Just to be sure as to what is happening.
    – Sky
    Commented Dec 16, 2022 at 16:14

1 Answer 1

1

It seems that ethersjs does not yet know how to decode packed data.

You can check this thread here: https://github.com/ethers-io/ethers.js/discussions/2373

web3js cannot do it either.

Solidity has a function to encodePacked, but does not have a function to decode packed data. Check here: https://github.com/ethereum/solidity/issues/6919

It seems it's not that easy to create a tool that can decode packed data dynamically. Check: https://docs.soliditylang.org/en/v0.8.11/abi-spec.html#non-standard-packed-mode

If you know the data, you could try decoding it yourself.

For example, your data is practically 0x8430ff0a. It has 4 bytes. The smallest values uint8 are put at the end, and the biggest value uint16 is put at the beginning.

So 10 is 0a in your data. 255 is ff. And the uint16(block.timestamp) is the rest: 8430. Knowing this you could try to implement a logic in js to decode it.

1
  • 1
    Thanks for your advice. Now I know how to do it manually) Commented Dec 16, 2022 at 19:09

Your Answer

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

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