mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9853 from ethereum/event-function-indexed
Implemented events with function type as one of its indexed parameters
This commit is contained in:
commit
5cf84c0f83
@ -3,6 +3,7 @@
|
||||
Compiler Features:
|
||||
* SMTChecker: Support ``addmod`` and ``mulmod``.
|
||||
* Optimizer: Optimize ``exp`` when base is -1.
|
||||
* Code generator: Implemented events with function type as one of its indexed parameters.
|
||||
|
||||
|
||||
### 0.7.2 (2020-09-28)
|
||||
|
@ -867,11 +867,26 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
else
|
||||
{
|
||||
solAssert(paramTypes[arg - 1]->isValueType(), "");
|
||||
utils().convertType(
|
||||
*arguments[arg - 1]->annotation().type,
|
||||
*paramTypes[arg - 1],
|
||||
true
|
||||
);
|
||||
if (auto functionType = dynamic_cast<FunctionType const*>(paramTypes[arg - 1]))
|
||||
{
|
||||
auto argumentType =
|
||||
dynamic_cast<FunctionType const*>(arguments[arg-1]->annotation().type);
|
||||
solAssert(
|
||||
argumentType &&
|
||||
functionType->kind() == FunctionType::Kind::External &&
|
||||
argumentType->kind() == FunctionType::Kind::External &&
|
||||
!argumentType->bound(),
|
||||
""
|
||||
);
|
||||
|
||||
utils().combineExternalFunctionType(true);
|
||||
}
|
||||
else
|
||||
utils().convertType(
|
||||
*arguments[arg - 1]->annotation().type,
|
||||
*paramTypes[arg - 1],
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!event.isAnonymous())
|
||||
|
@ -929,6 +929,20 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
"(" <<
|
||||
IRVariable(arg).commaSeparatedList() <<
|
||||
")";
|
||||
else if (auto functionType = dynamic_cast<FunctionType const*>(paramTypes[i]))
|
||||
{
|
||||
solAssert(
|
||||
IRVariable(arg).type() == *functionType &&
|
||||
functionType->kind() == FunctionType::Kind::External &&
|
||||
!functionType->bound(),
|
||||
""
|
||||
);
|
||||
define(indexedArgs.emplace_back(m_context.newYulVariable(), *TypeProvider::fixedBytes(32))) <<
|
||||
m_utils.combineExternalFunctionIdFunction() <<
|
||||
"(" <<
|
||||
IRVariable(arg).commaSeparatedList() <<
|
||||
")\n";
|
||||
}
|
||||
else
|
||||
indexedArgs.emplace_back(convert(arg, *paramTypes[i]));
|
||||
}
|
||||
|
@ -2453,6 +2453,38 @@ BOOST_AUTO_TEST_CASE(event_indexed_string)
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("E(string,uint256[4])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_indexed_function)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
event Test(function() external indexed);
|
||||
function f() public {
|
||||
emit Test(this.f);
|
||||
}
|
||||
}
|
||||
)";
|
||||
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("f()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == bytes());
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
|
||||
|
||||
bytes functionHash = util::keccak256("f()").asBytes();
|
||||
bytes address = m_contractAddress.asBytes();
|
||||
bytes selector = bytes(functionHash.cbegin(), functionHash.cbegin() + 4);
|
||||
bytes padding = bytes(8, 0);
|
||||
bytes functionABI = address + selector + padding;
|
||||
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1).hex(), util::toHex(functionABI));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Test(function)")));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
|
@ -0,0 +1,6 @@
|
||||
contract C {
|
||||
event Test(function() external indexed);
|
||||
function f() public {
|
||||
emit Test(this.f);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
library L {
|
||||
function f() public {
|
||||
int x = 1;
|
||||
}
|
||||
}
|
||||
|
||||
contract C {
|
||||
event Test(function() external indexed);
|
||||
|
||||
function g() public {
|
||||
Test(L.f);
|
||||
}
|
||||
}
|
||||
|
||||
contract D {
|
||||
event Test(function() external);
|
||||
|
||||
function f() public {
|
||||
Test(L.f);
|
||||
}
|
||||
}
|
||||
|
||||
contract E {
|
||||
event Test(function() external indexed);
|
||||
|
||||
using L for D;
|
||||
|
||||
function k() public {
|
||||
Test(D.f);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9553: (140-143): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested.
|
||||
// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested.
|
||||
// TypeError 9553: (345-348): Invalid type for argument in function call. Invalid implicit conversion from function D.f() to function () external requested.
|
Loading…
Reference in New Issue
Block a user