0

If you try to read from:

Polygon Mumbai: https://mumbai.polygonscan.com/address/0xB9545dFae31d62571f121C63D04Cf063c2EF8803#readContract

Field metadata at slot 0.

let hex = await web3.eth.getStorageAt("0xB9545dFae31d62571f121C63D04Cf063c2EF8803", 0)

You will get: 0x00000000000000000000000000000000000000000000000000000000000000a5

1 Answer 1

3

You might be interested in reading about the storage layout of dynamic arrays here.

Long story short, your string "occupies" slot 0, but this slot only contains the string size. The data itself is stored at keccak256(0). You need to read as many slots as required to gather all of the data.

I'm just curious regarding the size returned, it does not seem to match the length of the string present in the contract you want to read from, I'll give it a look when I have more time. In the meantime you can do something like this :

const contract = "0xB9545dFae31d62571f121C63D04Cf063c2EF8803";

// Storage slot 0 contains the size of the string, not the data
const length = await web3.eth.getStorageAt(contract, 0);

// The data is stored as keccak256(slot) : here slot is 0 as the string
// we want to read is declared at slot 0 which contains its length
const dataSlot = web3.utils.toBN(
  web3.utils.soliditySha3({ t: "uint256", v: 0 })
);

const data = [];

// Loop over length // 32 slots to get the whole string data
// This iterates over as many storage slots as required
for (let i = 0; i * 32 < length; i = i + 1) {
  data.push(
    await web3.eth.getStorageAt(contract, dataSlot.add(web3.utils.toBN(i)))
  );
}

// Convert the hexadecimal results to Utf8 and print the result
console.log(data.map((item) => web3.utils.hexToUtf8(item)).join(""));

Which prints : https://faktura.mypinata.cloud/ipfs/QmV4nWcVpGM6kbWiXBdQfcwvkcXY3WxB8ZHs47Gxp3FQch

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.