docs: Mention reference types and 4 indexed slots for anonymous events

This commit is contained in:
Kamil Śliwak 2021-05-25 18:05:45 +02:00
parent caa833909d
commit 11731f6091
2 changed files with 22 additions and 9 deletions

View File

@ -465,17 +465,20 @@ address, a series of up to four topics and some arbitrary length binary data. Ev
ABI in order to interpret this (together with an interface spec) as a properly typed structure. ABI in order to interpret this (together with an interface spec) as a properly typed structure.
Given an event name and series of event parameters, we split them into two sub-series: those which are indexed and Given an event name and series of event parameters, we split them into two sub-series: those which are indexed and
those which are not. Those which are indexed, which may number up to 3, are used alongside the Keccak hash of the those which are not.
event signature to form the topics of the log entry. Those which are not indexed form the byte array of the event. Those which are indexed, which may number up to 3 (for non-anonymous events) or 4 (for anonymous ones), are used
alongside the Keccak hash of the event signature to form the topics of the log entry.
Those which are not indexed form the byte array of the event.
In effect, a log entry using this ABI is described as: In effect, a log entry using this ABI is described as:
- ``address``: the address of the contract (intrinsically provided by Ethereum); - ``address``: the address of the contract (intrinsically provided by Ethereum);
- ``topics[0]``: ``keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")")`` (``canonical_type_of`` - ``topics[0]``: ``keccak(EVENT_NAME+"("+EVENT_ARGS.map(canonical_type_of).join(",")+")")`` (``canonical_type_of``
is a function that simply returns the canonical type of a given argument, e.g. for ``uint indexed foo``, it would is a function that simply returns the canonical type of a given argument, e.g. for ``uint indexed foo``, it would
return ``uint256``). If the event is declared as ``anonymous`` the ``topics[0]`` is not generated; return ``uint256``). This value is only present in ``topics[0]`` if the event is not declared as ``anonymous``;
- ``topics[n]``: ``abi_encode(EVENT_INDEXED_ARGS[n - 1])`` (``EVENT_INDEXED_ARGS`` is the series of ``EVENT_ARGS`` - ``topics[n]``: ``abi_encode(EVENT_INDEXED_ARGS[n - 1])`` if the event is not declared as ``anonymous``
that are indexed); or ``abi_encode(EVENT_INDEXED_ARGS[n])`` if it is (``EVENT_INDEXED_ARGS`` is the series of ``EVENT_ARGS`` that
are indexed);
- ``data``: ABI encoding of ``EVENT_NON_INDEXED_ARGS`` (``EVENT_NON_INDEXED_ARGS`` is the series of ``EVENT_ARGS`` - ``data``: ABI encoding of ``EVENT_NON_INDEXED_ARGS`` (``EVENT_NON_INDEXED_ARGS`` is the series of ``EVENT_ARGS``
that are not indexed, ``abi_encode`` is the ABI encoding function used for returning a series of typed values that are not indexed, ``abi_encode`` is the ABI encoding function used for returning a series of typed values
from a function, as described above). from a function, as described above).

View File

@ -24,9 +24,10 @@ because the contract can only see the last 256 block hashes.
You can add the attribute ``indexed`` to up to three parameters which adds them You can add the attribute ``indexed`` to up to three parameters which adds them
to a special data structure known as :ref:`"topics" <abi_events>` instead of to a special data structure known as :ref:`"topics" <abi_events>` instead of
the data part of the log. If you use arrays (including ``string`` and ``bytes``) the data part of the log.
as indexed arguments, its Keccak-256 hash is stored as a topic instead, this is A topic can only hold a single word (32 bytes) so if you use a :ref:`reference type
because a topic can only hold a single word (32 bytes). <reference-types>` for an indexed argument, the Keccak-256 hash of the value is stored
as a topic instead.
All parameters without the ``indexed`` attribute are :ref:`ABI-encoded <ABI>` All parameters without the ``indexed`` attribute are :ref:`ABI-encoded <ABI>`
into the data part of the log. into the data part of the log.
@ -61,7 +62,16 @@ The hash of the signature of the event is one of the topics, except if you
declared the event with the ``anonymous`` specifier. This means that it is declared the event with the ``anonymous`` specifier. This means that it is
not possible to filter for specific anonymous events by name, you can not possible to filter for specific anonymous events by name, you can
only filter by the contract address. The advantage of anonymous events only filter by the contract address. The advantage of anonymous events
is that they are cheaper to deploy and call. is that they are cheaper to deploy and call. It also allows you to declare
four indexed arguments rather than three.
.. note::
Since the transaction log only stores the event data and not the type,
you have to know the type of the event, including which parameter is
indexed and if the event is anonymous in order to correctly interpret
the data.
In particular, it is possible to "fake" the signature of another event
using an anonymous event.
:: ::