Yes. You'd only have to do a simple if
:
event E1(bytes32 arg1, bytes32 arg2);
event E2(bytes32 arg1, bytes32 arg2);
function foo() public {
dynamicEmit(E1.selector, 0x00, 0x00);
dynamicEmit(E2.selector, 0x00, 0x00);
}
function dynamicEmit(bytes32 eventSelector, bytes32 arg1, bytes32 arg2) internal {
// emit here event based on selector
if(E1.selector == eventSelector) {
emit E1(arg1, arg2);
} else if(E2.selector == eventSelector) {
emit E2(arg1, arg2);
}
}
In Remix, it prints something like:

It's not possible to "call" or "emit" an event directly from outside of the contract. An event is not a function. Even though it has a selector, it's not compiled nor used to access it directly. We cannot even declare an event as public
.
I compiled the code above and this is the running bytecode:
608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c298557814610030575b600080fd5b61003861003a565b005b61006b7f9a6311b27884bd845f20acbd9a955a4d2b083bc8631271b7520f317d3b4019c76000801b6000801b61009e565b61009c7f1000096eb75ded08a4c6ed11be5789e871886380989efb20fff024b38dadc2166000801b6000801b61009e565b565b827f9a6311b27884bd845f20acbd9a955a4d2b083bc8631271b7520f317d3b4019c703610103577f9a6311b27884bd845f20acbd9a955a4d2b083bc8631271b7520f317d3b4019c782826040516100f6929190610183565b60405180910390a1610165565b827f1000096eb75ded08a4c6ed11be5789e871886380989efb20fff024b38dadc21603610164577f1000096eb75ded08a4c6ed11be5789e871886380989efb20fff024b38dadc216828260405161015b929190610183565b60405180910390a15b5b505050565b6000819050919050565b61017d8161016a565b82525050565b60006040820190506101986000830185610174565b6101a56020830184610174565b939250505056fea26469706673582212209ebf6eb9c67d2c52a1bbd1251e0e75732c3f6b1404bf97066191d0252597f84564736f6c63430008100033
I then decompiled here: https://ethervm.io/decompile
And the entry point function of the decompiled contract, main
, looks like this:
function main() {
memory[0x40:0x60] = 0x80;
var var0 = msg.value;
if (var0) { revert(memory[0x00:0x00]); }
if (msg.data.length < 0x04) { revert(memory[0x00:0x00]); }
var0 = msg.data[0x00:0x20] >> 0xe0;
if (var0 != 0xc2985578) { revert(memory[0x00:0x00]); }
var var1 = 0x0038;
func_003A();
stop();
}
The code only has one public function, foo()
. And if we calculate the keccak256
hash of it, then we can see that is:
c2985578b8f3b75f7dc66a767be2a4ef7d7c2224896a1c86e92ccf30bae678b7
You can calculated it yourself here: https://emn178.github.io/online-tools/keccak_256.html
If you take the first 4 bytes of that hash, you endup with c2985578
. If you search those bytes in the main()
function, you will find it at line:
//...
if (var0 != 0xc2985578) { revert(memory[0x00:0x00]); }
//...
As you can see, since there's only 1 public function, there's only 1 check here. And if you 'call' a 'function' that does not have that selector, then it reverts. Thus, we cannot 'call' an event directly.
Event E1(bytes32,bytes32)
keccak256
hash is: 9a6311b27884bd845f20acbd9a955a4d2b083bc8631271b7520f317d3b4019c7
Event E2(bytes32,bytes32)
keccak256
hash is:
1000096eb75ded08a4c6ed11be5789e871886380989efb20fff024b38dadc216
We can find those hashes in the decompiled code, but not in the main()
function which is the entry point of the contract.
function func_003A() {
var var0 = 0x006b;
var var1 = 0x9a6311b27884bd845f20acbd9a955a4d2b083bc8631271b7520f317d3b4019c7;
var var2 = 0x00 << 0x00;
var var3 = 0x00 << 0x00;
func_009E(var1, var2, var3);
label_006B:
var0 = 0x009c;
var1 = 0x1000096eb75ded08a4c6ed11be5789e871886380989efb20fff024b38dadc216;
var2 = 0x00 << 0x00;
var3 = 0x00 << 0x00;
func_009E(var1, var2, var3);
label_009C:
}
function func_009E(var arg0, var arg1, var arg2) {
if (!(0x9a6311b27884bd845f20acbd9a955a4d2b083bc8631271b7520f317d3b4019c7 - arg0)) {
var0 = 0x9a6311b27884bd845f20acbd9a955a4d2b083bc8631271b7520f317d3b4019c7;
var1 = 0x00f6;
var2 = arg1;
var4 = memory[0x40:0x60];
var3 = arg2;
var1 = func_0183(var2, var3, var4);
var temp1 = memory[0x40:0x60];
log(memory[temp1:temp1 + var1 - temp1], [stack[-2]]);
return;
} else if (0x1000096eb75ded08a4c6ed11be5789e871886380989efb20fff024b38dadc216 - arg0) {
label_0164:
return;
} else {
var var0 = 0x1000096eb75ded08a4c6ed11be5789e871886380989efb20fff024b38dadc216;
var var1 = 0x015b;
var var2 = arg1;
var var3 = arg2;
var var4 = memory[0x40:0x60];
var1 = func_0183(var2, var3, var4);
var temp0 = memory[0x40:0x60];
log(memory[temp0:temp0 + var1 - temp0], [stack[-2]]);
goto label_0164;
}
}