# Ethereum的event logs

By [web3技术废柴](https://paragraph.com/@web3-15) · 2022-04-27

---

ethereum的日志可以用来做什么？
-------------------

In the traditional world, applications often use logs to capture and describe what’s going on at a specific moment. These logs are often used to

*   debug applications, detect specific events
    
*   notify the viewer of the logs that something happened
    
*   interacting with smart contracts!
    

So how does Ethereum do it?

Logging in Ethereum
-------------------

The EVM currently has **5 opcodes** （创建log record）for emitting event logs: _LOG0_, _LOG1_, _LOG2_, _LOG3_, and _LOG4_.

A log record can be used to describe an event within a smart contract, like a token transfer or a change of ownership.

Each log record consists of both **topics** and **data**.

*   Topic：32-byte (256 bit) “words” that are used to describe what’s going on in an event. LOG\*\*x：\*\*x代表可以最多包含的topic数量
    
*   Data：携带data比topic应廉价。没有size限制。所以可以携带大量结构复杂的数据
    

Topics in Ethereum Log Records
------------------------------

The first part of a log record consists of an array of topics. These topics are used to describe the event. The first topic usually consists of the **_signature_** (a [keccak256](https://en.wikipedia.org/wiki/SHA-3) hash) of the name of the event that occurred, including the types _(uint256, string, etc.)_ of its parameters. One exception where this signature is not included as the first topic is when emitting **anonymous events**. Since topics can only hold a maximum of 32 bytes of data, things like arrays or strings cannot be used as topics reliably. Instead, it should be included as data in the log record, not as a topic. If you were to try including a topic that’s larger than 32 bytes, the topic will be hashed instead. As a result, this hash can only be reversed if you know the original input. In conclusion, topics should **only** reliably be used for data that strongly narrows down search queries (like addresses). In conclusion, topics can be seen as indexed _keys_ of the event that all map to the same value, which we will talk about next.

Emitting events
---------------

The following contract implements the **Transfer event,** used by ERC20-compliant token contracts:

![](https://storage.googleapis.com/papyrus_images/4737f95e831a194fce629c421b83862493da86a617e18a0ce31997e8cb4f06b8.png)

Since this is not an anonymous event, the first topic will consist of the event signature:

![](https://storage.googleapis.com/papyrus_images/8fe58ad049f4c7a2c4e247c2af27424a1f37e0d517e96cef553127837c385213.png)

Now, let’s take a look at the arguments (_from_, _to_, _value_) of this Solidity event:

![](https://storage.googleapis.com/papyrus_images/2d4791c40affa97343cca5b2a7e563b8844160cc1b88200995e8cafb5b65652c.png)

Since the first 2 arguments are declared as **_indexed_**, they are treated like additional topics. Our final argument will not be indexed, which means it will be attached as data (instead of a separate topic). This means we are able to search for things like “\*find all **Transfer** logs from address **0x0000…** to address \***_0x0000…_**” or even “find all logs to address **0x0000…**”, but not for things like “find all **Transfer** logs with value **x**”. We know this event will have **3 topics**, which means this logging operation will use the **LOG3** opcode.

![](https://storage.googleapis.com/papyrus_images/fcc413d2105f8daba7dc72fdc69c71d79145b19e5f6505d939f3282dc105cf76.png)

Now, we just need to understand how data (like our final argument) can be included. **LOG3** requires 5 arguments:

`LOG3(memoryStart, memoryLength, topic1, topic2, topic3)`

Event data is read from memory in the following fashion:

`memory[memoryStart...(memoryStart + memoryLength)]`

Luckily, higher-level smart contract programming languages like [Solidity](https://github.com/ethereum/solidity), [Vyper](https://github.com/ethereum/vyper), or [Bamboo](https://github.com/cornellblockchain/bamboo) will handle writing event data to memory for us, which means you can usually pass data directly as a parameter when emitting logs.

订阅固定地址的event
------------

Using [web3](https://web3js.readthedocs.io/en/1.0/), a popular JavaScript library used to interact with a local or remote Ethereum node, we are able to subscribe to new event logs:

![](https://storage.googleapis.com/papyrus_images/6a5973277ffae7dff7a2e78c8f8da591600b1d359de1adb787daf95e1152f6c8.png)

This code will alert us whenever a new SAI token transfer has occurred, which can be useful for various applications. For example, a wallet interface could alert you whenever you receive tokens on your Ethereum address.

Log操作要消耗多少gas
-------------

![](https://storage.googleapis.com/papyrus_images/0aa19a6e3c76fb645c67ecda169601528ff85bfdce9f5f96f480fc8299a638d5.png)

The base cost of logging operations is **375 gas**. On top of that, every included topic costs an additional **375 gas**. Finally, each byte of data costs **8 gas**.

![](https://storage.googleapis.com/papyrus_images/0187f434ccdccb1b6ec4a455b4d02d0a6dd5140fd41d99c18adc2938358b3d44.png)

That’s actually pretty cheap! Let’s imagine an ERC-20 token transfer. First, we have a base cost of **375 gas**. Second, the **Transfer** event contains **3 topics**, which is an additional 375 \* 3 = **1125 gas**. Finally, we add **8 gas for each byte of data** included. Since the data only contains the value of the ERC-20 transfer, which can be a maximum of **32 bytes** (²²⁵⁶), the maximum amount of gas needed to account for the data of the logging operation would be 8 \* 32 = **256 gas**. This adds up to a total gas cost of **1756 gas**. For reference, a standard ether (non-token) transfer costs 21000 gas, or more than 10x that!

If we assume a gas price of **1 gwei**, the total cost of the operation would be **1756 gwei**, the equivalent of **0.000001756 ETH**. If the current price of ETH is around $200, this would only add up to **$.0003512**. Keep in mind that this is the price of storing data on the blockchain worldwide, likely forever.

_Disclaimer: This is just the cost of a logging operation itself. Any Ethereum transaction starts at 21000 gas, and the transaction’s input data costs up to 16 gas per byte. Typically, to transfer & log an ERC-20 token, it costs between_ **_40,000–60,000 gas_**_._

Conclusion
----------

Logs 是一个比较好的办法长期的存储一些数据在blockchain上，同时价格低廉。同时也是让其他contract监听者接收到事件的一种方式。这样就没必要让其他应用程序反复来查询该contract的状态。

---

*Originally published on [web3技术废柴](https://paragraph.com/@web3-15/ethereum-event-logs-3)*
