Merge pull request #13135 from ethereum/foreign-event-access-revert-and-selector-cleanup

Revert access to foreign events and clean up event/error selector tests/docs
This commit is contained in:
Kamil Śliwak 2022-06-14 18:14:30 +02:00 committed by GitHub
commit dccc06cc29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 86 additions and 110 deletions

View File

@ -6,7 +6,6 @@ Important Bugfixes:
Language Features: Language Features:
* Add `E.selector` for a non-anonymous event `E` to access the 32-byte selector topic. * Add `E.selector` for a non-anonymous event `E` to access the 32-byte selector topic.
* Errors and Events allow qualified access from other contracts.
Compiler Features: Compiler Features:

View File

@ -19,7 +19,7 @@ We assume that all contracts will have the interface definitions of any contract
This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. This specification does not address contracts whose interface is dynamic or otherwise known only at run-time.
.. _abi_function_selector: .. _abi_function_selector:
.. index:: selector .. index:: ! selector; of a function
Function Selector Function Selector
================= =================
@ -503,6 +503,7 @@ efficient search and arbitrary legibility by defining events with two arguments
indexed, one not — intended to hold the same value. indexed, one not — intended to hold the same value.
.. _abi_errors: .. _abi_errors:
.. index:: error, selector; of an error
Errors Errors
====== ======

View File

@ -116,7 +116,7 @@ efficient code, for example:
} }
} }
.. index:: selector; of a function
Access to External Variables, Functions and Libraries Access to External Variables, Functions and Libraries
----------------------------------------------------- -----------------------------------------------------

View File

@ -1,5 +1,4 @@
.. index:: ! error, revert .. index:: ! error, revert, ! selector; of an error
.. _errors: .. _errors:
******************************* *******************************
@ -80,3 +79,8 @@ of the built-in type ``Panic(uint256)``.
by default. This means that an inner call by default. This means that an inner call
can "forge" revert data that looks like it could have come from the can "forge" revert data that looks like it could have come from the
contract that called it. contract that called it.
Members of Errors
=================
- ``error.selector``: A ``bytes4`` value containing the error selector.

View File

@ -1,4 +1,4 @@
.. index:: ! event .. index:: ! event, ! event; anonymous, ! event; indexed, ! event; topic
.. _events: .. _events:
@ -73,6 +73,8 @@ four indexed arguments rather than three.
In particular, it is possible to "fake" the signature of another event In particular, it is possible to "fake" the signature of another event
using an anonymous event. using an anonymous event.
.. index:: ! selector; of an event
Members of Events Members of Events
================= =================
@ -147,7 +149,7 @@ The output of the above looks like the following (trimmed):
} }
Additional Resources for Understanding Events Additional Resources for Understanding Events
============================================== =============================================
- `Javascript documentation <https://github.com/ethereum/web3.js/blob/1.x/docs/web3-eth-contract.rst#events>`_ - `Javascript documentation <https://github.com/ethereum/web3.js/blob/1.x/docs/web3-eth-contract.rst#events>`_
- `Example usage of events <https://github.com/ethchange/smart-exchange/blob/master/lib/contracts/SmartExchange.sol>`_ - `Example usage of events <https://github.com/ethchange/smart-exchange/blob/master/lib/contracts/SmartExchange.sol>`_

View File

@ -215,7 +215,7 @@ In comparison to contracts, libraries are restricted in the following ways:
(These might be lifted at a later point.) (These might be lifted at a later point.)
.. _library-selectors: .. _library-selectors:
.. index:: selector .. index:: ! selector; of a library function
Function Signatures and Selectors in Libraries Function Signatures and Selectors in Libraries
============================================== ==============================================

View File

@ -548,7 +548,7 @@ these **create calls** and normal message calls is that the payload data is
executed and the result stored as code and the caller / creator executed and the result stored as code and the caller / creator
receives the address of the new contract on the stack. receives the address of the new contract on the stack.
.. index:: selfdestruct, self-destruct, deactivate .. index:: ! selfdestruct, deactivate
Deactivate and Self-destruct Deactivate and Self-destruct
============================ ============================

View File

@ -1216,7 +1216,7 @@ public:
FunctionTypePointer functionType(bool /*_internal*/) const override; FunctionTypePointer functionType(bool /*_internal*/) const override;
bool isVisibleInDerivedContracts() const override { return true; } bool isVisibleInDerivedContracts() const override { return true; }
bool isVisibleViaContractTypeAccess() const override { return true; } bool isVisibleViaContractTypeAccess() const override { return false; /* TODO */ }
EventDefinitionAnnotation& annotation() const override; EventDefinitionAnnotation& annotation() const override;

View File

@ -1,18 +0,0 @@
library L {
error E();
}
library S {
error E(uint);
}
library T {
error E();
}
contract C {
function f() public pure returns (bytes4, bytes4) {
assert(L.E.selector == T.E.selector);
assert(L.E.selector != S.E.selector);
return (L.E.selector, S.E.selector);
}
}
// ----
// f() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000

View File

@ -7,32 +7,26 @@ library S {
library T { library T {
event E(); event E();
} }
interface I {
event E();
}
contract D { contract D {
event F(); event F();
} }
contract C is D { contract C is D {
function test1() external pure returns (bytes32, bytes32, bytes32) { function test1() external pure returns (bytes32, bytes32) {
assert(L.E.selector == T.E.selector); assert(L.E.selector == T.E.selector);
assert(I.E.selector == L.E.selector);
assert(L.E.selector != S.E.selector); assert(L.E.selector != S.E.selector);
assert(T.E.selector != S.E.selector); assert(T.E.selector != S.E.selector);
assert(I.E.selector != S.E.selector);
return (L.E.selector, S.E.selector, I.E.selector); return (L.E.selector, S.E.selector);
} }
bytes32 s1 = L.E.selector; bytes32 s1 = L.E.selector;
bytes32 s2 = S.E.selector; bytes32 s2 = S.E.selector;
bytes32 s3 = T.E.selector; bytes32 s3 = T.E.selector;
bytes32 s4 = I.E.selector; function test2() external returns (bytes32, bytes32, bytes32) {
function test2() external returns (bytes32, bytes32, bytes32, bytes32) { return (s1, s2, s3);
return (s1, s2, s3, s4);
} }
function test3() external returns (bytes32) { function test3() external returns (bytes32) {
@ -42,6 +36,6 @@ contract C is D {
// ==== // ====
// compileViaYul: also // compileViaYul: also
// ---- // ----
// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028 // test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0
// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028 // test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028
// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a // test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a

View File

@ -2,7 +2,7 @@ contract C {
event E(); event E();
} }
contract Test { contract Test is C {
event E(uint256, uint256); event E(uint256, uint256);
function f() public { function f() public {
emit C.E(); emit C.E();

View File

@ -1,48 +1,34 @@
library L { library L {
error E(); error E(bytes4, bool, bytes);
}
library S {
error E(uint);
}
library T {
error E();
} }
error E(); error E(bytes4, bool, bytes);
interface I { interface I {
error E(); error E(bytes4, bool, bytes);
function f() external pure;
} }
contract D { contract B {
error F(); error E(bytes4, bool, bytes);
} }
contract C is D { contract C is B {
function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) { bytes4 public librarySelector = L.E.selector;
assert(L.E.selector == T.E.selector); bytes4 internal freeSelector = E.selector;
assert(L.E.selector != S.E.selector); bytes4 internal contractSelector = B.E.selector;
assert(E.selector == L.E.selector); bytes4 private interfaceSelector = I.E.selector;
assert(I.E.selector == L.E.selector);
return (L.E.selector, S.E.selector, E.selector, I.E.selector);
}
bytes4 s1 = L.E.selector; function f(bool condition) public view {
bytes4 s2 = S.E.selector; assert(librarySelector == L.E.selector);
bytes4 s3 = T.E.selector; assert(E.selector == B.E.selector);
bytes4 s4 = I.E.selector;
function test2() view external returns (bytes4, bytes4, bytes4, bytes4) { if (condition)
return (s1, s2, s3, s4); revert E(E.selector, true, "123");
} else
revert L.E((B.E.selector), true, "123");
function test3() pure external returns (bytes4) {
return (F.selector);
} }
} }
// ---- // ----
// Warning 2519: (16-26): This declaration shadows an existing declaration. // Warning 2519: (16-45): This declaration shadows an existing declaration.
// Warning 2519: (45-59): This declaration shadows an existing declaration. // Warning 2519: (98-127): This declaration shadows an existing declaration.
// Warning 2519: (78-88): This declaration shadows an existing declaration. // Warning 2519: (148-177): This declaration shadows an existing declaration.
// Warning 2519: (122-132): This declaration shadows an existing declaration.

View File

@ -0,0 +1,11 @@
contract D {
event E();
}
contract C {
function f() external pure returns (bytes32) {
return D.E.selector;
}
}
// ----
// TypeError 9582: (110-113): Member "E" not found or not visible after argument-dependent lookup in type(contract D).

View File

@ -0,0 +1,11 @@
interface I {
event E();
}
contract C {
function f() external pure returns (bytes32) {
return I.E.selector;
}
}
// ----
// TypeError 9582: (111-114): Member "E" not found or not visible after argument-dependent lookup in type(contract I).

View File

@ -0,0 +1,10 @@
library L {
event E();
}
contract C {
function f() external pure returns (bytes32) {
return L.E.selector;
}
}
// ----

View File

@ -6,7 +6,6 @@ contract D {
function test1() external pure returns (bytes32) { function test1() external pure returns (bytes32) {
return Y.E.selector; return Y.E.selector;
} }
} }
// ---- // ----
// TypeError 9582: (123-135): Member "selector" not found or not visible after argument-dependent lookup in function (). // TypeError 9582: (123-135): Member "selector" not found or not visible after argument-dependent lookup in function ().

View File

@ -1,43 +1,20 @@
library L { library L {
event E(); event E(bytes32, bool, bytes indexed);
}
library S {
event E(uint);
}
library T {
event E();
}
interface I {
event E();
} }
contract D { contract B {
event F(); event E(bytes32, bool, bytes indexed);
} }
contract C is D { contract C is B {
function test1() external pure returns (bytes32, bytes32, bytes32) { bytes32 public librarySelector = L.E.selector;
assert(L.E.selector == T.E.selector); bytes32 inheritedSelector = E.selector;
assert(I.E.selector == L.E.selector);
assert(L.E.selector != S.E.selector); function f() public {
assert(T.E.selector != S.E.selector); assert(librarySelector == L.E.selector);
assert(I.E.selector != S.E.selector); assert(E.selector == B.E.selector);
return (L.E.selector, S.E.selector, I.E.selector); emit E(E.selector, true, "123");
} emit L.E((B.E.selector), true, "123");
bytes32 s1 = L.E.selector;
bytes32 s2 = S.E.selector;
bytes32 s3 = T.E.selector;
bytes32 s4 = I.E.selector;
function test2() view external returns (bytes32, bytes32, bytes32, bytes32) {
return (s1, s2, s3, s4);
}
function test3() pure external returns (bytes32) {
return (F.selector);
} }
} }
// ----