主页 > imtokenapp > 了解以太坊上的事件日志

了解以太坊上的事件日志

imtokenapp 2023-01-18 09:48:02

大多数事务都有事件日志,但这些事件日志可能难以阅读。通过这篇文章,我们可以了解事件是如何存储的。

前言:首先阅读以太坊虚拟机可能会有所帮助,在本文中我将跳过基础知识直接进入。

在传统编程中,应用程序通常使用日志来捕获和描述特定时刻发生的事情。这些日志通常用于调试应用程序、检测特定事件或通知查看者日志中发生的事情。事实证明,在编写智能合约或与智能合约交互时,日志也非常有用!那么以太坊是如何做到的呢?

登录以太坊

EVM 目前有 5 个操作码用于触发事件日志:LOG0、LOG1、LOG2、LOG3 和 LOG4。

这些操作码可用于创建“日志记录”。日志用于描述智能合约中的事件,例如代币转移、所有权变更等。

Image for post

以太坊黄皮书-拜占庭版 69351d5(2018-12-10)

每条日志记录都包含“主题”和“数据”。主题是描述事件中发生的事情的 32 字节(256 位)“单词”。不同的操作码(LOG0...LOG4) 来描述需要在日志记录中包含的主题数量。例如,“LOG1”包含“一个主题”,“LOG4”包含“四个主题”。因此,单个日志记录中最多可以包含四个主题。

以太坊日志主题

日志记录的第一部分由一组主题组成。这些主题用于描述事件。第一个主题通常是事件名称及其参数类型 *( uint256, string 等) *signature (keccak256 hash)。一个例外是触发“匿名事件”没有事件签名。由于主题只能保存32字节的数据,所以没有办法转换数组或字符串等(可能超过32字节)作为主题。相反,它应该作为数据包含在日志记录中,而不是作为主题。如果您尝试包含大于 32 字节的主题,则需要对该主题进行哈希处理。因此,只有知道原始输入,才能知道这个hash代表什么。

一般来说,主题应该只用于需要(压缩)(例如:地址)数据的搜索查询。主题可以被认为是事件的索引键,它们都映射到相同的值,接下来讨论。

以太坊日志中的数据

日志 记录的第二部分包含附加数据。主体和数据共同构成日志记录,主体和数据各有优缺点。例如,主题是可搜索的,但数据不是。并且数据比主题更“便宜”。此外以太坊哈希值进度查询,虽然主题最多有 4 个(限制为 *4 32 字节),但数据没有限制,这意味着它可以包含大型或复杂数据*,例如作为数组或字符串。因此,事件数据(如果有)可以被视为一个值*。

让我们看一些如何使用主题、数据和日志记录的示例。

触发事件

以下实现 ERC20 的代币合约使用 Transfer 事件:

Image for post

由于这不是匿名事件,所以第一个主题将包含事件签名:

Image for post

现在,让我们看看这个 Solidity 事件的参数(from , to , value):

Image for post

由于前两个参数被声明为 index ed,所以它被认为是主题。最后一个参数没有 indexed ,它将被视为数据(而不是单独的主题)。这意味着我们可以进行如下搜索:查找从地址 0x0000...(搜索条件)到地址 0x0000...(搜索条件)的所有传输日志,或者“所有到地址 0x0000...(搜索条件)的传输) ”,但无法搜索“转账金额为x的转账(搜索条件)。我们知道这个事件会有 3 个主题,这意味着这个日志记录操作将使用 LOG3 操作码。

Image for post

现在,我们只需要了解如何包含数据(即最后一个参数)。LOG3需要5个参数:

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

通过以下方式从内存中读取事件数据:

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

幸运的是,Solidity、Vyper 或 Bamboo 等高级工具智能合约编程语言会为我们处理将事件数据写入内存,我们可以在触发日志时直接将数据作为参数传递。

检索事件日志

通过使用可用于与本地或远程以太坊节点交互的 web3 JavaScript 库,我们能够订阅新的事件日志:

Image for post

每当发生新的 SAI 代时以太坊哈希值进度查询,此代码会在硬币转移时通知我们,接收事件通知,这对许多应用程序很有用。例如,一旦您在以太坊地址收到硬币,钱包界面就会提醒您。

日志的gas成本

Image for post

根据黄皮书,日志的基本成本是 375 gas。此外,每个主题需要额外支付 375 gas。最后,每个字节的数据需要8个gas。

Image for post

这真的很便宜!一个 ERC-20 代币转移事件可以计算成本。首先,基本成本是 375 gas。其次,“transfer”事件包含3个topic,即另外375 3 = 1125 gas。最后,我们为每个包含的数据字节添加 8 个气体。由于数据仅包括 ERC-20 传输的次数,最大为 32 字节,因此记录日志数据所需的最大 gas 量为 8 32 = 256 gas 。这加起来总共花费了 1756 个 gas。作为参考,标准的 Ether(非代币)转账需要 21,000 gas,是事件成本的十倍以上!

如果我们假设 gas 价格为 1 gwei,那么操作的总成本将为 1756 gwei,相当于 0.000001756 ETH。如果以太坊的当前价格在 200 美元左右,那么总价是 $0.0003512。请记住,这是在全球范围内永久存储数据的成本。

免责声明:这只是日志记录操作本身的成本。任何以太坊交易至少需要 21,000 个 gas,而交易的输入数据成本高达每字节 16 个 gas。通常,转移和记录 ERC-20 代币的成本是 40,000–60,000 gas。

结论

日志是一种以低廉的价格在以太坊区块链上存储少量数据的优雅方式。具体来说,事件日志有助于让其他人知道发生了什么,而不必单独查询合同。

参考文献

此翻译由 Cell Network 赞助。

本文参与Chainlink社区写作激励计划,好文好收入,有阅读的欢迎加入。