交易中有什么?如果你曾经在以太坊(或任何支持智能合约的区块链)上进行过交易,那么你可能在像 etherscan.io 这样的区块浏览器上查询过它,并看到过这些大量的信息:
交易概览选项卡
如果你尝试查看日志或追踪(内部交易),你可能会看到这些令人困惑的页面:
日志选项卡(如果它们像这样被很好地解码,那你很幸运)
追踪选项卡(是的,看起来像一堆乱七八糟的东西)
学习如何阅读区块浏览器上交易的详细信息将成为你进行所有以太坊数据分析和知识学习的基础,所以让我们来介绍所有的组成部分以及如何用 SQL 来处理它们。
我只会从一个高层次来讲解这些概念;如果你想学习如何手动解码这些数据,那么你需要熟悉数据是如何编码的(交易、追踪和日志的编码方式是一样的)以及如何使用 Dune 的字节数组/十六进制函数在不同类型之间转换。
在本指南结束时,你将能够使用以下交易表查找查询来理解和浏览任何合约的数据表:
查询链接(插入任何交易哈希、链和区块号)
在学习完本指南中的概念后,你还应该学习使用我的 EVM 快速入门仪表板来开始任何合约分析。
如何在五分钟内分析任何以太坊协议或产品Andrew Hong
·
2022年12月30日
阅读全文
交易交易只是数据冰山的一角,所有的追踪和日志都是在初始输入数据启动顶级函数后被调用的。首先,让我们标记你在区块浏览器的交易页面上会看到的所有字段:
这些字段与在 Dune 上查询“ethereum.transactions”时看到的字段相同。这里需要学习的关键项目是如何识别“to”字段是否是一个合约。通常,合约会被清楚地标记出来。如果是合约,“输入数据”应该包含一个函数调用。
交易链接
在所有这些概念中,首先要学好的是 EOA(外部拥有账户)与合约地址的区别。合约是由 EOAs 部署的,并可以在交易的“to”字段中被调用。如果你点击一个地址,区块浏览器会在左上角显示它是合约还是账户。在 Dune 上,你可以通过连接到 ethereum.creation_traces 表来检查是否是合约。请注意,只有 EOAs 可以作为交易的“from”签名者。
重要的是要了解哪些数据是直接来自链上的,哪些是浏览器/前端添加的。区块链上的所有数据都以十六进制表示(有时称为二进制或字节),所以 1inch 交换调用会有这样的输入数据字符串:
交易示例
前4字节(8个字符)是“函数签名”,它是函数名称和输入类型的 keccak 哈希。Etherscan 为一些合约提供了一个方便的“解码”按钮,能为你提供这种可读的形式:
交易示例
正如你所看到的,之前的长十六进制字符串中包含了许多变量。它们的编码方式遵循了智能合约的应用程序二进制接口(ABI)规范。ABI 就像智能合约的 API 文档(例如 OpenAPI 规范),你可以在这里了解更多技术细节。大多数开发者会验证他们的 ABI 是否与合约匹配,并上传 ABI 供其他人解码参考。许多合约可能与 MEV/交易相关,开发者可能希望保持闭源和私密——因此我们无法从这些合约中获得解码信息。
在 Dune 上,我们有基于提交到合约表(即 ethereum.contracts)的合约 ABI 解码的表。函数和事件被转换为字节签名(ethereum.signatures),然后与追踪和日志匹配,从而生成解码后的表,如 uniswap_v2_ethereum.Pair_evt_Swap,它存储了 Uniswap v2 对等厂商创建的所有对等合约的交换信息。你可以通过查看 contract_address 表来过滤特定对等合约的交换事件。
在 Dune 上,你会想要查询此函数调用的表 oneinch_ethereum.AggregationRouterV6_call_swap。你会看到这个表名在查询结果的顶部,位于指南开始时的表查找器中。
在接下来的追踪和日志部分,我们将使用相同的 1inch 聚合器交换交易。这是一个很好的例子,因为路由器会在多个 DEX 合约之间交换代币,所以我们会得到多样的追踪和日志进行调查。
日志接下来我们来讨论事件日志。日志可以在函数调用的任何点被触发。开发者通常会在函数的末尾触发日志,即在所有转账/逻辑完成且没有错误之后。让我们来看一下之前交易中发出的 Uniswap V3 交换事件:
交易示例
你会看到有 topic0、topic1、topic2 和 data 字段。topic0 类似于函数签名,但它是 32 字节,而不是 4 字节(仍然以相同的方式哈希)。事件可以有“indexed”字段,用于更快的数据过滤,这些字段可能出现在 topic1、topic2 或 topic3 中。所有其他字段则一起编码在 data 对象中。它们遵循与交易和追踪相同的编码规则。28 是事件在整个区块中的索引。在你想要在交易中查找第一次交换或转账时,这个索引有时会很有用。
要找到事件发出的逻辑,我需要深入了解 Solidity 代码。我会点击事件的链接地址,进入合约选项卡,并搜索“emit swap”,因为我知道所有事件在代码中被调用之前都会有“emit”。
这是uniswapv3pool合约 这是每个对等合约的工厂合约创建的事件。
我可以看到它是在合约的第 786 行发出的,作为“swap”函数的一部分。
能够在合约之间导航函数和事件的传承将是准确理解你查询的数据传承的关键技能。你不需要深入学习 Solidity,只需了解如何理解合约接口以及函数/事件何时被调用(“function”和“emit”是你的关键字)。
对于深入的函数和事件代码追踪示例,可以查看对 Sudoswap 合约和数据的详细解析。
使用之前的表查找查询,我可以看到我应该查询的表是 uniswap_v3_ethereum.Pair_evt_Swap,并且它是在调用 swap() 函数后发出的。
痕迹(ethereum.traces)当然,我会重新表述一下: 追踪(traces)可能会变得非常复杂,因为不同合约之间的调用可能会非常嵌套。让我们首先了解追踪的类型:
CREATE:这是在部署新合约时发出的追踪。你可以在交易的最顶部直接部署合约,这意味着交易数据中没有“to”地址。你也可以在函数调用中部署合约,这就是合约工厂的存在。查看 ethereum.creation_traces 表可以获得更简单的视图。 DELEGATECALL:在查看交易时,这种追踪通常可以忽略。可以把它看作是从一个服务器转发请求到下一个服务器,而不改变任何逻辑。这与代理和存储相关,更多细节可以查看相关文档。 CALL:这是最常见和通用的追踪。一个调用可以只是 ETH 值的转移,而没有涉及合约。它也可以是对任何合约的函数调用。 STATICCALL:这是一个不会修改任何状态的函数调用,纯粹用于计算。像预言机价格馈送、AMM 价格计算、清算比例检查、余额检查等都发生在 staticcall 中。
在 Solidity 中,常见的函数类型是“view”或“pure”。 你还需要理解 trace_address 列/索引。这是你经常看到的 [0,1,1,1,1] 模式。可以把它想象成项目符号,其中数组中的数字数量表示函数调用的深度和顺序。
(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)
正如我们之前的内部交易(追踪)截图所示,Etherscan 对于查看追踪并不友好。我更喜欢使用 Phalcon Blocksec,它可以这样展开交易:
链接到资源管理器
这可能看起来令人不知所措,但实际上这是探索交易中所有函数、事件和参数的非常简单的方法。一旦你能够理解这一点,你就可以自信地说你理解了交易中的所有数据。请注意,我的表查找查询几乎是这个布局的精确副本,这对我有很大的启发!
需要注意的是,在 Dune 上,我们会自动解码同一函数名称的交易调用和追踪到相同的表中。你可能会想知道是否可以像在 Phalcon 中那样以良好的排序来轻松连接事件和追踪/交易。在 Dune 上,你可以通过交易哈希来连接数据,但不能通过任何索引来重建交互的确切排序。目前这是一个不幸的限制,需要自定义索引器。
继续深入加密货币的黑暗森林如果你理解了本指南中阐述的概念,那么你就准备好深入挖掘并编写更复杂的查询了。使用多种不同工具导航交易数据将是你在这个领域取得成功的关键技能之一。
我每周使用的区块浏览器可能有 10 种,而工具的数量是这些工具的 10 倍。我编写了一份年度指南,涵盖了数据工具栈如何不断演变,以及你应该如何使用每个工具。
指南链接
声明:
本文转载自[cryptodatabytes],所有版权归原作者所有[安德鲁·洪]。若对本次转载有异议,请联系Gate Learn团队,他们会及时处理。免责声明:本文所表达的观点和意见仅代表作者个人观点,不构成任何投资建议。Gate Learn 团队将文章翻译成其他语言。除非另有说明,否则禁止复制、分发或抄袭翻译文章。