mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
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:
commit
dccc06cc29
@ -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:
|
||||||
|
@ -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
|
||||||
======
|
======
|
||||||
|
@ -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
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
@ -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.
|
||||||
|
@ -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>`_
|
||||||
|
@ -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
|
||||||
==============================================
|
==============================================
|
||||||
|
@ -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
|
||||||
============================
|
============================
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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.
|
|
||||||
|
@ -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).
|
@ -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).
|
@ -0,0 +1,10 @@
|
|||||||
|
library L {
|
||||||
|
event E();
|
||||||
|
}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
function f() external pure returns (bytes32) {
|
||||||
|
return L.E.selector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
@ -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 ().
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
|
||||||
|
Loading…
Reference in New Issue
Block a user