如何阅读区块浏览器并理解以太坊(EVM)上的交易、trace 和日志
学习如何阅读像 Etherscan 这样的浏览器,并在这三个关键数据结构中导航数据,以及如何找到你需要查询的表。
如果你曾在以太坊(或任何启用智能合约的区块链)上进行过交易,那么你可能在像 etherscan.io 这样的区块浏览器上查找过,并看到这堆信息:
如果你尝试查看日志或Traces(内部交易),你可能会看到这些令人困惑的页面:
日志标签(如果它们像这样被很好地解码,那是很幸运的了)
Traces标签(是的,它看起来像一堆无意义的东西)
学习如何在区块浏览器上阅读交易的详细信息将是你所有以太坊数据分析和知识的基础,因此让我们覆盖所有部分以及如何在 SQL 中使用它们。
我只会讲解如何在高层次上理解这些概念;如果你想学习如何手动解码这些内容,那么你需要熟悉 数据是如何编码的(交易/Traces/日志都是一样的)以及如何使用 Dune 的字节数组/十六进制函数 在不同类型之间转换。
在本指南结束时,你将能够理解并导航任何合约的数据表,使用此交易表查找查询:
上图 查询链接(插入任何交易哈希、链和区块号)
在你学习了本指南中的概念后,你还应该学习使用我的 EVM 快速入门仪表板 开始任何合约分析, 如何在五分钟内分析任何以太坊协议或产品
交易只是数据冰山的一角,所有Traces和日志都是在初始输入数据启动顶层函数后调用的。让我们首先标记你在区块浏览器的交易页面上看到的所有字段:
这些是你在 Dune 上查询“ethereum.transactions”时看到的字段相同。这里要学习识别的关键项是“to”是否是合约。通常,合约会被清楚地标记。如果它是合约,则应该有“输入数据”,其中包含一个函数调用。
上图交易链接
在所有这些概念中,第一个要学好的就是 EOA 与合约地址。合约是由 EOA 部署的,并可以在交易的“to”字段中被调用。如果你点击一个地址,浏览器会在左上角显示它是合约还是账户。在 Dune 上,你可以加入 ethereum.creation_traces 表来检查它是否是合约。请注意,只有 EOA 可以作为交易的“from” 签名者。
了解直接来自链上的数据与浏览器/前端显示的数据之间的区别是很重要的。区块链中的所有内容都表示为十六进制(有时称为二进制或字节),因此 1inch 兑换调用将具有此输入数据字符串:
上图 示例交易
前 4 个字节(8 个字符)是“函数签名”,它是函数名称和输入类型的 keccak 哈希。Etherscan 为某些合约提供了一个不错的“解码”按钮,使你可以获得这种可读形式:
上图 示例交易
如你所见,许多变量被打包在之前的那个长十六进制字符串中。它们的编码方式遵循智能合约的应用程序二进制接口(ABI)规范。
ABI 就像智能合约的 API 文档(如 OpenAPI 规范),你可以在 这里阅读更多技术细节。大多数开发人员会验证他们的 ABI 是否与合约匹配,并上传 ABI 供其他人参考以进行解码。许多合约可能与 MEV/交易相关,开发人员希望保持闭源和私密 - 因此我们无法从他们那里获得任何解码。
在 Dune 中,我们有基于提交的合约 ABI 的解码表 到合约表(即 ethereum.contracts
),函数和事件被转换为字节签名(ethereum.signatures
),然后与 traces
和 logs
匹配,以提供解码表,例如 uniswap_v2_ethereum.Pair_evt_Swap
,它存储由 Uniswap v2 对交易所工厂创建的所有对合约的所有兑换。你可以通过查看事件的 contract_address
表来过滤特定对的兑换。
在 Dune 上,你将希望查询此表以进行此函数调用 oneinch_ethereum.AggregationRouterV6_call_swap. 你会看到此表名称位于本指南开头的查询结果的表查找顶部。在接下来的关于Traces和日志的部分,我们将使用相同的 1inch 聚合器兑换交易 。这是一个很好的例子,因为路由器将在多个 DEX 合约之间兑换代币,因此我们将获得多样的Traces和日志进行调查。
接下来我们来谈谈事件日志。日志可以在函数调用的任何时刻被发出。开发者通常会在函数结束时发出日志,在所有转账/逻辑完成且没有错误后。让我们看看之前交易中发出的 uniswap v3 兑换事件:
上图 示例交易
你会看到有 topic0、topic1、topic2 和 data 字段。topic0 类似于函数签名,但它是 32 字节而不是仅仅 4 字节(仍然以相同的方式哈希)。事件可以有“索引”字段以便于数据过滤,这些字段可以出现在 topic1、topic2 或 topic3 中。所有其他字段都编码在“data”对象中。同样,它们遵循与交易和Traces相同的编码规则。“28”是事件在整个区块中的索引。当你想要在交易中找到第一次兑换或转账时,这有时会很有用。
要找到这个事件被发出的逻辑,我需要深入 solidity 代码。我会点击事件的链接地址,转到合约标签,并搜索emit Swap
,因为我知道所有事件在代码中被调用之前都有“emit”。
这是 uniswapv3pool 合约,为每对创建的工厂合约。
我可以看到这是在合约的第 786 行发出的,作为“swap”函数的一部分。
能够在跨合约之间导航到函数和事件将是你需要掌握的一项关键技能,以准确理解你查询的数据。你不需要深入学习 solidity 来浏览这些文件,只需知道如何理解合约接口以及何时调用函数/事件(function 和 emit 是你的关键词)。
要深入了解如何侦查函数和事件的代码, 请查看这个关于 Sudoswap 合约和数据的分析 。
使用之前的表查找查询,我可以看到我应该查询的表是uniswap_v3_ethereum.Pair_evt_Swap,并且它是在调用 swap()函数后发出的。
Traces可能会迅速变得非常难以导航,因为不同合约之间的嵌套调用会变得复杂。让我们首先了解Traces的类型:
你还需要理解trace_address列/索引。这是你经常看到的[0,1,1,1,1]模式。想象一下它就像项目符号,其中数组中的数字数量表示函数调用的深度和顺序。
A (null) --交易的第一个输入的 trace_address 为[]
CALLs B (0)
CALLs C (0,0)
CALLs D (1)
CALLs E (1,0)
CALLs F (1,0,0)
CALLs G (1,1)
CALLs H (2)
从我们之前的内部交易(Traces)截图中可以看出,etherscan 并不是查看Traces的友好地方。我更喜欢使用 phalcon blocksec,它以这样的方式展开交易:
这可能看起来令人不知所措,但实际上这是探索交易流中所有函数、事件和参数的超级简单方法。一旦你能够理解这一点,那么你就可以安全地说你理解了交易中的所有数据。注意我的表查找查询几乎是这个布局的精确复制,我在很大程度上受到了它们的启发!
请注意,在 Dune 上,我们自动将同一函数名称的交易调用和Traces解码到同一表中。你可能会想知道是否可以轻松地在 phalcon 中显示的良好顺序中连接事件和Traces/交易。在 Dune 上,你可以通过交易哈希来连接数据,在浏览器上做不到这一点。
如果你理解我在本指南中阐述的概念,那么你就准备好深入挖掘并编写更复杂的查询。使用多种不同工具在交易中导航数据将是你在这个领域中脱颖而出的关键技能之一。
下面是涉及到各种不同的浏览器和工具表,涵盖数据工具栈也是不断演变的,你应该了解使用每个工具的目的:
你学习使用的数据工具越多,你就能在这个庞大的生态系统中更灵活地构建和沟通!一如既往,如果你有反馈或问题, 我的推特私信是开放的 。
其他初学者资源:
与社区一起构建更容易、更有趣,加入 Bytexplorers 在你的数据旅程中学习和赚取。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!