diff --git a/Changelog.md b/Changelog.md index 2472d9467..031fe5a67 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,7 +5,7 @@ Language Features: Compiler Features: * Metadata: Added support for IPFS hashes of large files that need to be split in multiple chunks. - + * Commandline Interface: Enable output of storage layout with `--storage-layout`. Bugfixes: * Inline Assembly: Fix internal error when accessing incorrect constant variables. diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index e91f6446c..90c2931c5 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -147,6 +148,7 @@ static string const g_strOptimizeYul = "optimize-yul"; static string const g_strOutputDir = "output-dir"; static string const g_strOverwrite = "overwrite"; static string const g_strRevertStrings = "revert-strings"; +static string const g_strStorageLayout = "storage-layout"; /// Possible arguments to for --revert-strings static set const g_revertStringsArgs @@ -207,6 +209,7 @@ static string const g_argOptimizeRuns = g_strOptimizeRuns; static string const g_argOutputDir = g_strOutputDir; static string const g_argSignatureHashes = g_strSignatureHashes; static string const g_argStandardJSON = g_strStandardJSON; +static string const g_argStorageLayout = g_strStorageLayout; static string const g_argStrictAssembly = g_strStrictAssembly; static string const g_argVersion = g_strVersion; static string const g_stdinFileName = g_stdinFileNameStr; @@ -231,7 +234,8 @@ static set const g_combinedJsonArgs g_strOpcodes, g_strSignatureHashes, g_strSrcMap, - g_strSrcMapRuntime + g_strSrcMapRuntime, + g_strStorageLayout }; /// Possible arguments to for --machine @@ -293,7 +297,8 @@ static bool needsHumanTargetedStdout(po::variables_map const& _args) g_argNatspecUser, g_argNatspecDev, g_argOpcodes, - g_argSignatureHashes + g_argSignatureHashes, + g_argStorageLayout }) if (_args.count(arg)) return true; @@ -433,6 +438,18 @@ void CommandLineInterface::handleABI(string const& _contract) sout() << "Contract JSON ABI" << endl << data << endl; } +void CommandLineInterface::handleStorageLayout(string const& _contract) +{ + if (!m_args.count(g_argStorageLayout)) + return; + + string data = jsonCompactPrint(m_compiler->storageLayout(_contract)); + if (m_args.count(g_argOutputDir)) + createFile(m_compiler->filesystemFriendlyName(_contract) + "_storage.json", data); + else + sout() << "Contract Storage Layout:" << endl << data << endl; +} + void CommandLineInterface::handleNatspec(bool _natspecDev, string const& _contract) { std::string argName; @@ -833,7 +850,8 @@ Allowed options)", (g_argSignatureHashes.c_str(), "Function signature hashes of the contracts.") (g_argNatspecUser.c_str(), "Natspec user documentation of all contracts.") (g_argNatspecDev.c_str(), "Natspec developer documentation of all contracts.") - (g_argMetadata.c_str(), "Combined Metadata JSON whose Swarm hash is stored on-chain."); + (g_argMetadata.c_str(), "Combined Metadata JSON whose Swarm hash is stored on-chain.") + (g_argStorageLayout.c_str(), "Slots, offsets and types of the contract's state variables."); desc.add(outputComponents); po::options_description allOptions = desc; @@ -1276,6 +1294,8 @@ void CommandLineInterface::handleCombinedJSON() contractData[g_strOpcodes] = evmasm::disassemble(m_compiler->object(contractName).bytecode); if (requests.count(g_strAsm) && m_compiler->compilationSuccessful()) contractData[g_strAsm] = m_compiler->assemblyJSON(contractName); + if (requests.count(g_strStorageLayout) && m_compiler->compilationSuccessful()) + contractData[g_strStorageLayout] = jsonCompactPrint(m_compiler->storageLayout(contractName)); if (requests.count(g_strSrcMap) && m_compiler->compilationSuccessful()) { auto map = m_compiler->sourceMapping(contractName); @@ -1653,6 +1673,7 @@ void CommandLineInterface::outputCompilationResults() handleSignatureHashes(contract); handleMetadata(contract); handleABI(contract); + handleStorageLayout(contract); handleNatspec(true, contract); handleNatspec(false, contract); } // end of contracts iteration diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index 417501907..f6972cf04 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -74,6 +74,7 @@ private: void handleNatspec(bool _natspecDev, std::string const& _contract); void handleGasEstimation(std::string const& _contract); void handleFormal(); + void handleStorageLayout(std::string const& _contract); /// Fills @a m_sourceCodes initially and @a m_redirects. bool readInputFilesAndConfigureRemappings();