Skip to content

Commit 9e62f21

Browse files
joshieDoMarenz
authored andcommitted
Add event and error identifiers to cli hashes cmd
1 parent 5c3bcb6 commit 9e62f21

File tree

7 files changed

+109
-2
lines changed

7 files changed

+109
-2
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Language Features:
66

77

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

libsolidity/interface/CompilerStack.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include <libsolutil/IpfsHash.h>
7676
#include <libsolutil/JSON.h>
7777
#include <libsolutil/Algorithms.h>
78+
#include <libsolutil/FunctionSelector.h>
7879

7980
#include <json/json.h>
8081

@@ -1024,6 +1025,37 @@ Json::Value CompilerStack::methodIdentifiers(string const& _contractName) const
10241025
return methodIdentifiers;
10251026
}
10261027

1028+
Json::Value CompilerStack::errorIdentifiers(string const& _contractName) const
1029+
{
1030+
if (m_stackState < AnalysisPerformed)
1031+
solThrow(CompilerError, "Analysis was not successful.");
1032+
1033+
Json::Value errorIdentifiers(Json::objectValue);
1034+
for (ErrorDefinition const* error: contractDefinition(_contractName).interfaceErrors())
1035+
{
1036+
string signature = error->functionType(true)->externalSignature();
1037+
errorIdentifiers[signature] = toHex(toCompactBigEndian(selectorFromSignature32(signature), 4));
1038+
}
1039+
1040+
return errorIdentifiers;
1041+
}
1042+
1043+
Json::Value CompilerStack::eventIdentifiers(string const& _contractName) const
1044+
{
1045+
if (m_stackState < AnalysisPerformed)
1046+
solThrow(CompilerError, "Analysis was not successful.");
1047+
1048+
Json::Value eventIdentifiers(Json::objectValue);
1049+
for (EventDefinition const* event: contractDefinition(_contractName).interfaceEvents())
1050+
if (!event->isAnonymous())
1051+
{
1052+
string signature = event->functionType(true)->externalSignature();
1053+
eventIdentifiers[signature] = toHex(u256(h256::Arith(keccak256(signature))));
1054+
}
1055+
1056+
return eventIdentifiers;
1057+
}
1058+
10271059
bytes CompilerStack::cborMetadata(string const& _contractName, bool _forIR) const
10281060
{
10291061
if (m_stackState < AnalysisPerformed)

libsolidity/interface/CompilerStack.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,12 @@ class CompilerStack: public langutil::CharStreamProvider
330330
/// @returns a JSON representing a map of method identifiers (hashes) to function names.
331331
Json::Value methodIdentifiers(std::string const& _contractName) const;
332332

333+
/// @returns a JSON representing a map of error identifiers (hashes) to error names.
334+
Json::Value errorIdentifiers(std::string const& _contractName) const;
335+
336+
/// @returns a JSON representing a map of event identifiers (hashes) to event names.
337+
Json::Value eventIdentifiers(std::string const& _contractName) const;
338+
333339
/// @returns the Contract Metadata matching the pipeline selected using the viaIR setting.
334340
std::string const& metadata(std::string const& _contractName) const { return metadata(contract(_contractName)); }
335341

solc/CommandLineInterface.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,14 +271,30 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract)
271271
return;
272272

273273
Json::Value methodIdentifiers = m_compiler->methodIdentifiers(_contract);
274-
string out;
274+
string out = "Function signatures:\n";
275275
for (auto const& name: methodIdentifiers.getMemberNames())
276276
out += methodIdentifiers[name].asString() + ": " + name + "\n";
277277

278+
Json::Value errorIdentifiers = m_compiler->errorIdentifiers(_contract);
279+
if (!errorIdentifiers.empty())
280+
{
281+
out += "\nError signatures:\n";
282+
for (auto const& name: errorIdentifiers.getMemberNames())
283+
out += errorIdentifiers[name].asString() + ": " + name + "\n";
284+
}
285+
286+
Json::Value eventIdentifiers = m_compiler->eventIdentifiers(_contract);
287+
if (!eventIdentifiers.empty())
288+
{
289+
out += "\nEvent signatures:\n";
290+
for (auto const& name: eventIdentifiers.getMemberNames())
291+
out += eventIdentifiers[name].asString() + ": " + name + "\n";
292+
}
293+
278294
if (!m_options.output.dir.empty())
279295
createFile(m_compiler->filesystemFriendlyName(_contract) + ".signatures", out);
280296
else
281-
sout() << "Function signatures:" << endl << out;
297+
sout() << out;
282298
}
283299

284300
void CommandLineInterface::handleMetadata(string const& _contract)

test/cmdlineTests/hashes/args

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--hashes

test/cmdlineTests/hashes/input.sol

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity >=0.0;
3+
4+
error fileLevelError(uint z);
5+
6+
library L {
7+
event libraryEvent(uint r);
8+
error libraryError(uint r);
9+
error libraryErrorUnused(uint u);
10+
event libraryEventUnused(uint u);
11+
}
12+
13+
contract C {
14+
struct S { uint x; }
15+
16+
event ev(uint y);
17+
event anon_ev(uint y) anonymous;
18+
19+
error err(uint z, uint w);
20+
21+
function f(S memory s) public {
22+
emit L.libraryEvent(3);
23+
if (s.x > 1)
24+
revert fileLevelError(3);
25+
else
26+
revert L.libraryError(4);
27+
}
28+
}

test/cmdlineTests/hashes/output

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
======= hashes/input.sol:C =======
3+
Function signatures:
4+
3fc03eeb: f((uint256))
5+
6+
Error signatures:
7+
619a0bb7: err(uint256,uint256)
8+
82b5f64f: fileLevelError(uint256)
9+
8c41f45c: libraryError(uint256)
10+
11+
Event signatures:
12+
2d4dd5fe18ada5a020a9f5591539a8dc3010a5c074ba6a70e1c956659f02786a: ev(uint256)
13+
14+
======= hashes/input.sol:L =======
15+
Function signatures:
16+
17+
Error signatures:
18+
8c41f45c: libraryError(uint256)
19+
c61c03f5: libraryErrorUnused(uint256)
20+
21+
Event signatures:
22+
81f3fb02f88d32d3bb08c80c9a622ca3b3223292f131c6ad049811f9a8a606dc: libraryEvent(uint256)
23+
0a994ad3600197f16ffe1ea1101caea3174efe5ebd9ba9a75d6d5524c5de28cd: libraryEventUnused(uint256)

0 commit comments

Comments
 (0)