Hi there, on PG 168, 3.14.2 JSON Output section about storage layout of a contract, the sample given has “slot” and “offset” fields, however, I checked local folders from Hardhat and found no JSON files containing such information. I am wondering where I can find the standard JSON interface? Thanks.
You need to specifically request this output with storageLayout
in outputSelection
in Standard JSON. Apparently Hardhat does not need it so it does not request it. The description of Standard JSON input is here: Input Description.
Example
Input:
{
"language": "Solidity",
"sources": {
"contract.sol": {
"content": "contract C {uint a; address b;}"
}
},
"settings": {"outputSelection": {"*": { "*": ["storageLayout"]}}}
}
Output:
{
"contracts": {
"contract.sol": {
"C": {
"storageLayout": {
"storage": [
{
"astId": 2,
"contract": "contract.sol:C",
"label": "a",
"offset": 0,
"slot": "0",
"type": "t_uint256"
},
{
"astId": 4,
"contract": "contract.sol:C",
"label": "b",
"offset": 0,
"slot": "1",
"type": "t_address"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
}
},
"errors": [
{
"component": "general",
"errorCode": "1878",
"formattedMessage": "Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n--> contract.sol\n\n",
"message": "SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.",
"severity": "warning",
"sourceLocation": {
"end": -1,
"file": "contract.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "3420",
"formattedMessage": "Warning: Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.6;\"\n--> contract.sol\n\n",
"message": "Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.6;\"",
"severity": "warning",
"sourceLocation": {
"end": -1,
"file": "contract.sol",
"start": -1
},
"type": "Warning"
}
],
"sources": {
"contract.sol": {
"id": 0
}
}
}
@cameel Thanks for this. I’m just wondering if there could be more specification on how this works.
On the command line, I’ll need to run this command, right?
solc --standard-json setting.json
What is in setting.json
then? Is the following script sufficient to produce the storage layout?
{
"language": "Solidity",
"sources": {
"ComplicatedContract.sol"
},
"settings": {"outputSelection": {"*": { "*": ["storageLayout"]}}}
}
Also running
solc --standard-json setting.json
solcjs --standard-json setting.json
produces different results.
Besides, I never made this “standard” approach work. Is this expired?
solc --storage-layout Contract.sol
Many thanks.
On the command line, I’ll need to run this command, right?
Yes.
Is the following script sufficient to produce the storage layout?
You’re missing the content
key under sources
. But that requires the full text of the contract and I see you’re trying to use a path instead. For that use urls
, e.g. "sources": {"ComplicatedContract.sol": {"urls": ["ComplicatedContract.sol"]}}
.
Also running (…) produces different results.
Does it still produce different results with a valid input file?
Besides, I never made this “standard” approach work. Is this expired?
It works for me. Maybe you’re giving it a more complicated path, e.g. with ../
segments or something? The compiler has to normalize paths you give it on the CLI to make them match the way you might import the same file and that can get complicated. To avoid having to deal with that make sure you are compiling a file that’s inside your project dir (i.e. --base-path
), which is the current working directory by default.
Thanks for the detailed answer. I think more details are still needed.
For a project with a structure like this, where should I put the setting.json
file?
├───artifacts
├───cache
├───contracts
│ ├───Contract.sol
├───deploy
├───node_modules
│ ├───@nomiclabs
│ ├───@openzeppelin
│ ├───ethers
│ ├───solc
├───scripts
├───test
Also when I run solc --storage-layout Contract.sol
, I’m getting this line at the top of returned messages:
solc --storage-layout Contract.sol
Warning: 'storage-layout' is not in the list of known options, but still passed to Electron/Chromium.
Similarly,
solc --standard-json .\contracts\settings.json
Warning: 'standard-json' is not in the list of known options, but still passed to Electron/Chromium.
I’m really interested in getting a clear understanding on the storage layout to have a clear understanding on the proxy logic upgradeable pattern. Many thanks again.
For a project with a structure like this, where should I put the
setting.json
file?
Ah, looks like you’re confusing two things: Standard JSON input and framework settings.
You need to pass StandardJSON input to the compiler when you invoke it. Either via standard input or by giving the compiler --standard-json <path>
option. There’s no standard location or file name for StandardJSON input because the compiler is agnostic to your project structure and does not even necessarily assume that a filesystem exists at all (when using it via solc-js).
The file structure you’re showing looks like a Hardhat or Truffle project. When you’re using the compiler through a framework, it’s the framework that creates StandardJSON input based on various things and passes it to the compiler. You interact only with the framework. For example the settings
key is usually something you can specify directly in the framework’s config file. sources
on the other hand is filled out by the framework based on the files you have under contracts/
and what dependencies you have.
As for outputs, that’s also under framework’s control. Usually you’ll find all or parts of the StandardJSON output in the “artifacts” that might be under artifacts/
or build
/. The storage layout will be there only if the framework requests it though. Not sure if Hardhat does it by default but it seems to have a plugin for doing that (hardhat-storage-layout
).
Also when I run
solc --storage-layout Contract.sol
, I’m getting this line at the top of returned messages:
From the error message it looks like the solc
binary on your system is not the compiler binary. It’s apparently some Electron thing? A broken wrapper script? Try checking what it actually is:
type solc
You should get something like this:
solc is hashed (/usr/bin/solc)
Whatever it is, I’d recommend uninstalling it and getting one of the official binaries from solc-bin.
how to get solidity state variable storage layout in solc which version is blew 0.5, for example, how to get weth’s storage layout
You’d have to use a separate tool or calculate that yourself based on variable sizes.
Check if maybe ethers.js or one of the available debuggers can give you that info. Unfortunately the compiler at that version did not have that feature.