Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] How to convert address/bignumber to hex string? #1079

Closed
shanecarey17 opened this issue Oct 2, 2020 · 7 comments
Closed

[question] How to convert address/bignumber to hex string? #1079

shanecarey17 opened this issue Oct 2, 2020 · 7 comments
Labels
discussion Questions, feedback and general information.

Comments

@shanecarey17
Copy link

Hello, trying to implement the following tutorial in ethers https://medium.com/aigang-network/how-to-read-ethereum-contract-storage-44252c8af925 in order to load data from a "private" mapping.

With respect to the mapping example, how would the following code look in ethers?

index = '0000000000000000000000000000000000000000000000000000000000000005'
key =  '00000000000000000000000xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6'
let newKey =  web3.sha3(key + index, {"encoding":"hex"})
console.log(web3.eth.getStorageAt(contractAddress, newKey))
console.log('DEC: ' + web3.toDecimal(web3.eth.getStorageAt(contractAddress, newKey)))

I have tried the following which raises an error EXCEPTION Error: data out-of-bounds (length=32, offset=64, code=BUFFER_OVERRUN, version=abi/5.0.5):

let key = ethers.getAddress('0x...');
let offset = ethers.BigNumber.from(5);
let mappingKey = ethers.utils.keccak256([key, offset]);
let mappingData = await ethers.provider.getStorageAt(contractAddress, mappingKey, blockNumber);

Specifically, how does one convert the key and offset to appropriately sized hex strings for the hash function? Thanks in advance!

@ricmoo
Copy link
Member

ricmoo commented Oct 3, 2020

Heya!

You are on the right track. To accomplish the same thing in ethers, here is the demo re-written a bit, with more documentation added.

const { BigNumber, ethers, utils } = require("ethers");

(async function() {
    // Connect to Ropsten
    const provider = ethers.getDefaultProvider("ropsten");

    // The contract address
    const addr = "0xf1f5896ace3a78c347eb7eab503450bc93bd0c3b";

    // The key into the mapping which is located at the given Solidity slot
    const key = "0xbccc714d56bc0da0fd33d96d2a87b680dd6d0df6";
    const index = 5;

    // The pre-image used to compute the Storage location
    const newKeyPreimage = utils.concat([
        // Mappings' keys in Solidity must all be word-aligned (32 bytes)
        utils.hexZeroPad(key, 32),

        // Similarly with the slot-index into the Solidity variable layout
        utils.hexZeroPad(BigNumber.from(index).toHexString(), 32),
    ]);

    console.log("New Key Preimage:", utils.hexlify(newKeyPreimage));
    // "0x000000000000000000000000bccc714d56bc0da0fd33d96d2a87b680dd6d0df60000000000000000000000000000000000000000000000000000000000000005"

    const newKey = utils.keccak256(newKeyPreimage);
    console.log("New Key:", newKey);
    // "0xafef6be2b419f4d69d56fe34788202bf06650015554457a2470181981bcce7ef"

    const value = await provider.getStorageAt(addr, newKey);
    console.log("Value:", value);
    // "0x0000000000000000000000000000000000000000000000000000000000000058"
})();

I hope that helps! Let me know if you have any other questions. :)

@ricmoo ricmoo added the discussion Questions, feedback and general information. label Oct 3, 2020
@shanecarey17
Copy link
Author

Thanks for the help! I am still getting the same error with the updated code:

let hexKey = ethers.utils.hexZeroPad(key, 32);
let hexIndex = ethers.utils.hexZeroPad(ethers.BigNumber.from(index).toHexString(), 32);
let mappingKeyPreimage = ethers.utils.concat([hexKey, hexIndex]);
let mappingKey = ethers.utils.keccak256(mappingKeyPreimage);

The error is

[Sat Oct 03 2020 16:42:21] [ERROR]  Error: data out-of-bounds (length=32, offset=64, code=BUFFER_OVERRUN, version=abi/5.0.5)
    at Logger.makeError (/app/node_modules/@ethersproject/logger/src.ts/index.ts:205:28)
    at Logger.throwError (/app/node_modules/@ethersproject/logger/src.ts/index.ts:217:20)
    at Reader._peekBytes (/app/node_modules/@ethersproject/abi/src.ts/coders/abstract-coder.ts:171:24)
    at Reader.readBytes (/app/node_modules/@ethersproject/abi/src.ts/coders/abstract-coder.ts:185:26)
    at Reader.readValue (/app/node_modules/@ethersproject/abi/src.ts/coders/abstract-coder.ts:192:36)
    at NumberCoder.decode (/app/node_modules/@ethersproject/abi/src.ts/coders/number.ts:44:28)
    at /app/node_modules/@ethersproject/abi/src.ts/coders/array.ts:108:31
    at Array.forEach (<anonymous>)
    at Object.unpack (/app/node_modules/@ethersproject/abi/src.ts/coders/array.ts:89:12)
    at TupleCoder.decode (/app/node_modules/@ethersproject/abi/src.ts/coders/tuple.ts:27:41) {
  reason: 'data out-of-bounds',
  code: 'BUFFER_OVERRUN',
  length: 32,
  offset: 64
}

I don't understand what the error is indicating. It looks like there is a fixed sized buffer somewhere. Is this because of my inputs? key is an address from ethers.utils.getAddress(...) and index is just an int.

@shanecarey17
Copy link
Author

Also, utils.hexConcat does not appear to be a function as the docs suggest https://docs.ethers.io/v5/api/utils/bytes/#utils-hexConcat, I've tried it as a substitute to utils.concat.

@shanecarey17
Copy link
Author

Ah! Your solution worked perfectly, I was dealing with parsing the return of getStorageAt but was confused because the stack trace did not show which function I had called. Obviously this is because its an async function, but I hadnt realized. Thanks!

@ricmoo
Copy link
Member

ricmoo commented Oct 3, 2020

Glad to hear it! :)

@ricmoo
Copy link
Member

ricmoo commented Oct 3, 2020

(I'll also be sure to export hexConcat in the next release too)

ricmoo added a commit that referenced this issue Oct 5, 2020
@SZharkov
Copy link

SZharkov commented Apr 9, 2023

utils.hexZeroPad(utils.getAddress(address), 32)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Questions, feedback and general information.
Projects
None yet
Development

No branches or pull requests

3 participants