<divclass="link title"><ahref="/v5/">Documentation</a></div><divclass="base show link depth-1"><ahref="/v5/getting-started/">Getting Started</a></div><divclass="base ancestor show link depth-1"><ahref="/v5/concepts/">Ethereum Basics</a></div><divclass="myself ancestor ancestor show link depth-2"><ahref="/v5/concepts/events/">Events</a></div><divclass="link show child depth-3"><ahref="#events--logs-and-filtering">Logs and Filtering</a></div><divclass="link show child depth-3"><ahref="#events-solidity">Solidity Topics</a></div><divclass="show link depth-2"><ahref="/v5/concepts/gas/">Gas</a></div><divclass="show link depth-2"><ahref="/v5/concepts/security/">Security</a></div><divclass="show link depth-2"><ahref="/v5/concepts/best-practices/">Best Practices</a></div><divclass="base show link depth-1"><ahref="/v5/api-keys/">Provider API Keys</a></div><divclass="base show link depth-1"><ahref="/v5/api/">Application Programming Interface</a></div><divclass="hide link depth-2"><ahref="/v5/api/providers/">Providers</a></div><divclass="hide link depth-3"><ahref="/v5/api/providers/provider/">Provider</a></div><divclass="hide link depth-3"><ahref="/v5/api/providers/jsonrpc-provider/">JsonRpcProvider</a></div><divclass="hide link depth-3"><ahref="/v5/api/providers/api-providers/">API Providers</a></div><divclass="hide link depth-3"><ahref="/v5/api/providers/other/">Other Providers</a></div><divclass="hide link depth-3"><ahref="/v5/api/providers/types/">Types</a></div><divclass="hide link depth-2"><ahref="/v5/api/signer/">Signers</a></div><divclass="hide link depth-2"><ahref="/v5/api/contract/">Contract Interaction</a></div><divclass="hide link depth-3"><ahref="/v5/api/contract/contract/">Contract</a></div><divclass="hide link depth-3"><ahref="/v5/api/contract/contract-factory/">ContractFactory</a></div><divclass="hide link depth-3"><ahref="/v5/api/contract/example/">Example: ERC-20 Contract</a></div><divclass="hide link depth-2"><ahref="/v5/api/utils/">Utilities</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/abi/">Application Binary Interface</a></div><divclass="hide link depth-4"><ahref="/v5/api/utils/abi/coder/">AbiCoder</a></div><divclass="hide link depth-4"><ahref="/v5/api/utils/abi/formats/">ABI Formats</a></div><divclass="hide link depth-4"><ahref="/v5/api/utils/abi/fragments/">Fragments</a></div><divclass="hide link depth-4"><ahref="/v5/api/utils/abi/interface/">Interface</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/address/">Addresses</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/bignumber/">BigNumber</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/bytes/">Byte Manipulation</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/constants/">Constants</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/display-logic/">Display Logic and Input</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/encoding/">Encoding Utilities</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/fixednumber/">FixedNumber</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/hashing/">Hashing Algorithms</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/hdnode/">HD Wallet</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/logger/">Logging</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/properties/">Property Utilities</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/signing-key/">Signing Key</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/strings/">Strings</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/transactions/">Transactions</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/web/">Web Utilities</a></div><divclass="hide link depth-3"><ahref="/v5/api/utils/wordlists/">Wordlists</a></div><divclass="hide link depth-2"><ahref="/v5/api/other/">Other Libraries</a></div><divclass="hide link depth-3"><ahref="/v5/api/other/assembly/">Assembly</a></div><divclass="hide link depth-4"
<aname="events--logs-and-filtering"></a><h2class="show-anchors"><div>Logs and Filtering<divclass="anchors"><aclass="self"href="/v5/concepts/events/#events--logs-and-filtering"></a></div></div></h2><p>Logs and filtering are used quite often in blockchain applications, since they allow for efficient queries of indexed data and provide lower-cost data storage when the data is not required to be accessed on-chain.</p>
<p>These can be used in conjunction with the <ahref="/v5/api/providers/provider/#Provider--event-methods">Provider Events API</a> and with the <ahref="/v5/api/contract/contract/#Contract--events">Contract Events API</a>.</p>
<p>The Contract Events API also provides <ahref="/v5/api/contract/contract/#Contract--filters">higher-level methods</a> to compute and query this data, which should be preferred over the lower-level filter.</p>
<aname="events--filters"></a><aname="events--logs-and-filtering--events--filters"></a><h3class="show-anchors"><div>Filters<divclass="anchors"><aclass="self"href="/v5/concepts/events/#events--filters"></a></div></div></h3><p>When a Contract creates a log, it can include up to 4 pieces of data to be indexed by. The indexed data is hashed and included in a <ahref="https://en.wikipedia.org/wiki/Bloom_filter">Bloom Filter</a>, which is a data structure that allows for efficient filtering.</p>
<p>So, a filter may correspondingly have up to 4 topic-sets, where each topic-set refers to a condition that must match the indexed log topic in that position (i.e. each condition is <codeclass="inline">AND</code>-ed together).</p>
<p>If a topic-set is an array of topics, a log topic in that position must match <b>any one</b> of the topics (i.e. the topic in this position are <codeclass="inline">OR</code>-ed).</p>
<tableclass="table full"><tr><tdalign="center"width="25%"><b>Topic-Sets</b></td><tdalign="center"colspan="3"width="75%"><b>Matching Logs</b></td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ A ]</td><tdalign="left"colspan="3"rowspan="2"width="75%">topic[0] = A</td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ A, null ]</td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ null, B ]</td><tdalign="left"colspan="3"rowspan="3"width="75%">topic[1] = B</td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ null, [ B ] ]</td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ null, [ B ], null ]</td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ A, B ]</td><tdalign="left"colspan="3"rowspan="3"width="75%">(topic[0] = A) <b>AND</b> (topic[1] = B)</td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ A, [ B ] ]</td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ A, [ B ], null ]</td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ [ A, B ] ]</td><tdalign="left"colspan="3"rowspan="2"width="75%">(topic[0] = A) <b>OR</b> (topic[0] = B)</td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ [ A, B ], null ]</td><tdclass="fix"> </td></tr><tr><tdalign="center"width="25%">[ [ A, B ], [ C, D ] ]</td><tdalign="left"colspan="3"width="75%"><b>[</b> (topic[0] = A) <b>OR</b> (topic[0] = B) <b>]</b><b>AND</b><b>[</b> (topic[1] = C) <b>OR</b> (topic[1] = D) <b>]</b></td><tdclass="fix"> </td></tr><tr><tdclass="table-title"colspan="4">Example Log Matching</td><tdclass="fix"> </td></tr></table><divclass="code-title"><div>ERC-20 Transfer Filter Examples</div></div><divclass="code"><spanclass="comment">// Short example of manually creating filters for an ERC-20
</span><spanclass="comment">// Transfer event.
</span>//
<spanclass="comment">// Most users should generally use the Contract API to
</span><spanclass="comment">// compute filters, as it is much simpler, but this is
</span><spanclass="comment">// provided as an illustration for those curious. See
</span><spanclass="comment">// below for examples of the equivalent Contract API.
</span></div><aname="events-solidity"></a><aname="events--events-solidity"></a><h2class="show-anchors"><div>Solidity Topics<divclass="anchors"><aclass="self"href="/v5/concepts/events/#events-solidity"></a></div></div></h2><p>This is a quick (and non-comprehensive) overview of how events are computed in Solidity.</p>
<p>This is likely out of the scope for most developers, but may be intersting to those who want to learn a bit more about the underlying technology.</p>
<p>Solidity provides two types of events, anonymous and non-anonymous. The default is non-anonymous, and most developers will not need to worry about anonymous events.</p>
<p>For non-anonymous events, up to 3 topics may be indexed (instead of 4), since the first topic is reserved to specify the event signature. This allows non-anonymous events to always be filtered by their event signature.</p>
<p>This topic hash is always in the first slot of the indexed data, and is computed by normalizing the Event signature and taking the keccak256 hash of it.</p>
<p>For anonymous events, up to 4 topics may be indexed, and there is no signature topic hash, so the events cannot be filtered by the event signature.</p>
<p>Each additional indexed property is processed depending on whether its length is fixed or dynamic.</p>
<p>For fixed length types (e.g. <codeclass="inline">uint</code>, <codeclass="inline">bytes5</code>), all of which are internally exactly 32 bytes (shorter types are padded with zeros; numeric values are padded on the left, data values padded on the right), these are included directly by their actual value, 32 bytes of data.</p>
<p>For dynamic types (e.g. <codeclass="inline">string</code>, <codeclass="inline">uint256[]</code>) , the value is hashed using keccak256 and this hash is used.</p>
<p>Because dynamic types are hashed, there are important consequences in parsing events that should be kept in mind. Mainly that the original value is lost in the event. So, it is possible to tell is a topic is equal to a given string, but if they do not match, there is no way to determine what the value was.</p>
<p>If a developer requires that a string value is required to be both able to be filtered and also able to be read, the value must be included in the signature twice, once indexed and once non-indexed (e.g. <codeclass="inline">someEvent(string indexed searchBy, string clearText)</code>).</p>
<p>For a more detailed description, please refer to the <ahref="https://docs.soliditylang.org/en/v0.8.1/abi-spec.html#events">Solidity Event Documentation</a>.</p>
<aname="events--events-solidity--other-things-todo"></a><h3class="show-anchors"><div>Other Things? TODO<divclass="anchors"><aclass="self"href="/v5/concepts/events/#events--events-solidity--other-things-todo"></a></div></div></h3><p>Explain what happens to strings and bytes, how to filter and retain the value</p>
<divclass="copyright">The content of this site is licensed under the <ahref="https://choosealicense.com/licenses/cc-by-4.0/">Creative Commons License</a>. Generated on February 8, 2021, 3:25pm.</div>