Add event and error identifiers to cli hashes cmd

This commit is contained in:
joshieDo 2022-01-17 21:28:58 +00:00 committed by Marenz
parent 5c3bcb6c2d
commit 9e62f21b25
7 changed files with 109 additions and 2 deletions

View File

@ -6,6 +6,7 @@ Language Features:
Compiler Features:
* Commandline Interface: Event and error signatures are also returned when using ``--hashes``.
* Yul Optimizer: Remove ``mstore`` and ``sstore`` operations if the slot already contains the same value.
* Yul: Emit immutable references for pure yul code when requested.

View File

@ -75,6 +75,7 @@
#include <libsolutil/IpfsHash.h>
#include <libsolutil/JSON.h>
#include <libsolutil/Algorithms.h>
#include <libsolutil/FunctionSelector.h>
#include <json/json.h>
@ -1024,6 +1025,37 @@ Json::Value CompilerStack::methodIdentifiers(string const& _contractName) const
return methodIdentifiers;
}
Json::Value CompilerStack::errorIdentifiers(string const& _contractName) const
{
if (m_stackState < AnalysisPerformed)
solThrow(CompilerError, "Analysis was not successful.");
Json::Value errorIdentifiers(Json::objectValue);
for (ErrorDefinition const* error: contractDefinition(_contractName).interfaceErrors())
{
string signature = error->functionType(true)->externalSignature();
errorIdentifiers[signature] = toHex(toCompactBigEndian(selectorFromSignature32(signature), 4));
}
return errorIdentifiers;
}
Json::Value CompilerStack::eventIdentifiers(string const& _contractName) const
{
if (m_stackState < AnalysisPerformed)
solThrow(CompilerError, "Analysis was not successful.");
Json::Value eventIdentifiers(Json::objectValue);
for (EventDefinition const* event: contractDefinition(_contractName).interfaceEvents())
if (!event->isAnonymous())
{
string signature = event->functionType(true)->externalSignature();
eventIdentifiers[signature] = toHex(u256(h256::Arith(keccak256(signature))));
}
return eventIdentifiers;
}
bytes CompilerStack::cborMetadata(string const& _contractName, bool _forIR) const
{
if (m_stackState < AnalysisPerformed)

View File

@ -330,6 +330,12 @@ public:
/// @returns a JSON representing a map of method identifiers (hashes) to function names.
Json::Value methodIdentifiers(std::string const& _contractName) const;
/// @returns a JSON representing a map of error identifiers (hashes) to error names.
Json::Value errorIdentifiers(std::string const& _contractName) const;
/// @returns a JSON representing a map of event identifiers (hashes) to event names.
Json::Value eventIdentifiers(std::string const& _contractName) const;
/// @returns the Contract Metadata matching the pipeline selected using the viaIR setting.
std::string const& metadata(std::string const& _contractName) const { return metadata(contract(_contractName)); }

View File

@ -271,14 +271,30 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract)
return;
Json::Value methodIdentifiers = m_compiler->methodIdentifiers(_contract);
string out;
string out = "Function signatures:\n";
for (auto const& name: methodIdentifiers.getMemberNames())
out += methodIdentifiers[name].asString() + ": " + name + "\n";
Json::Value errorIdentifiers = m_compiler->errorIdentifiers(_contract);
if (!errorIdentifiers.empty())
{
out += "\nError signatures:\n";
for (auto const& name: errorIdentifiers.getMemberNames())
out += errorIdentifiers[name].asString() + ": " + name + "\n";
}
Json::Value eventIdentifiers = m_compiler->eventIdentifiers(_contract);
if (!eventIdentifiers.empty())
{
out += "\nEvent signatures:\n";
for (auto const& name: eventIdentifiers.getMemberNames())
out += eventIdentifiers[name].asString() + ": " + name + "\n";
}
if (!m_options.output.dir.empty())
createFile(m_compiler->filesystemFriendlyName(_contract) + ".signatures", out);
else
sout() << "Function signatures:" << endl << out;
sout() << out;
}
void CommandLineInterface::handleMetadata(string const& _contract)

View File

@ -0,0 +1 @@
--hashes

View File

@ -0,0 +1,28 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
error fileLevelError(uint z);
library L {
event libraryEvent(uint r);
error libraryError(uint r);
error libraryErrorUnused(uint u);
event libraryEventUnused(uint u);
}
contract C {
struct S { uint x; }
event ev(uint y);
event anon_ev(uint y) anonymous;
error err(uint z, uint w);
function f(S memory s) public {
emit L.libraryEvent(3);
if (s.x > 1)
revert fileLevelError(3);
else
revert L.libraryError(4);
}
}

View File

@ -0,0 +1,23 @@
======= hashes/input.sol:C =======
Function signatures:
3fc03eeb: f((uint256))
Error signatures:
619a0bb7: err(uint256,uint256)
82b5f64f: fileLevelError(uint256)
8c41f45c: libraryError(uint256)
Event signatures:
2d4dd5fe18ada5a020a9f5591539a8dc3010a5c074ba6a70e1c956659f02786a: ev(uint256)
======= hashes/input.sol:L =======
Function signatures:
Error signatures:
8c41f45c: libraryError(uint256)
c61c03f5: libraryErrorUnused(uint256)
Event signatures:
81f3fb02f88d32d3bb08c80c9a622ca3b3223292f131c6ad049811f9a8a606dc: libraryEvent(uint256)
0a994ad3600197f16ffe1ea1101caea3174efe5ebd9ba9a75d6d5524c5de28cd: libraryEventUnused(uint256)