本文深入探讨了加密数据的来源以及如何将原始链上数据转化为有意义的指标。内容涵盖了从客户节点数据请求、请求管道的角色、原始数据解码,到复杂的数据转换引擎和指标聚合。同时,文章还强调了区块链数据流管理的重要性,适合开发者、数据分析师和研究人员,以增强对加密数据生态的理解。
理解加密数据的来源对于任何涉及区块链领域的人员来说都是至关重要的。这份综合性解读将指导你完成整个过程的每个步骤,从最初的数据请求到将数据最终转化为有意义的指标。
在本系列的第一篇文章中,我们将探讨客户端节点如何启动数据检索、请求管道的作用以及原始链上数据的性质。你还将了解到解码原始数据、将其转换为人类可读格式的关键过程,以及为了各种用例进行数据聚合的后续步骤。我们还将涉及如何整合链外数据源和更复杂的链上模式,以便提供数据转换的整体视图。
我们不会对与区块链交互所能检索的所有不同信息深入探讨。与其详尽描述从区块链上可获取的每一个可能的数据点和模式,不如提供一个关于获取生态系统级数据所需基本业务逻辑的广泛概述,比如 DEX 的总体交易量。无论你是开发者、数据分析师还是研究人员,这份详细指南都将增强你对加密数据领域及其应用的理解。
并非每个数据转换管道都遵循上述明确的步骤。更精简的过程或拥有明确目标的过程通常会跳过、模糊或合并某些步骤,以适应任务的独特需求。本文将探讨一个专为数据提供商量身定制的过程,该过程能够在任何协议或网络上生成数据,类似于 Dune 等平台。
从区块链获取数据的过程始于对客户端节点的请求。“节点”和“客户端”是用于描述核心软件基础设施的术语,允许你同时读取(请求数据)和写入(提交交易)。为此,每个客户端实现了 JSON-RPC 规范,提供一组统一的方法,供应用程序依据,无论具体的节点或客户端实现如何。
每个链都有自己的客户端规范,如果你希望获取多个链的数据,就必须运行多个客户端,为每个网络运行一个。你不必运行自己的节点。但如果不这样做,你将需要与为你运行节点的人建立通信通道,比如节点即服务提供商。
节点示例:Geth、Lighthouse、Prism、Erigon 和 Bitcoin Core。
节点即服务示例:Alchemy、Infura、Akr、Quicknode、Helius、Tenderly
通过接口(如 JSON RPC 请求)检索区块、交易或事件是访问链上数据的常见需求。节点可以提供历史和当前的网络状态。然而,与节点 API 交互是一项复杂的工作,需要结构化的方法来管理信息流。必须建立一个强大的请求管道,以处理传入的请求,并有效地将原始数据转化为有组织的表格。
有效的请求管道对优化数据检索和确保多个来源的数据一致性至关重要。它们涉及一系列阶段,包括请求验证、数据提取和索引,这些阶段必须仔细协调,以最小化延迟并避免数据重复。此外,这些管道通常会结合缓存机制和错误处理程序,以提高性能和可靠性。通过实施精心设计的请求管道,你可以确保检索到的数据是准确的、及时的,并准备好进行后续分析或集成到应用中。
为了简化与请求管道相关的挑战,数据提取工具作为区块链数据管理中的宝贵资产应运而生。诸如 Cryo 的工具,为提取区块链数据(如区块、交易、日志和追踪)提供了高效的接口,利用 JSON-RPC 协议,并以 Parquet 和 CSV 等格式输出,供进一步分析。同样, EVM 查询语言(EQL)提供类似 SQL 的语法,用于查询以太坊和 EVM 兼容的区块链,使开发者和分析师在使用关系数据库的常用概念时更容易提取数据,同时支持多种文件格式的提取。这些工具简化了与节点的通信,减少了构建复杂自定义管道的需求,能够无缝融入到 ELT 工作流中,提高整体数据转换过程的效率。
什么是它?原始链上数据包括你通过节点的 RPC 调用能够提取的任何内容。虽然可用数据的完整列表很广泛,但在本文中,我们将其缩小到遵循标准模式的最常见类型,使后续转换更容易。
注意:在此上下文中,原始仅意味着与解码相对,具体如下。
示例:区块、交易、账户、原始追踪、原始日志
用例:
通过转换原始链上数据获得的指标:
如果你探索原始链上数据,你会注意到函数输入、输出和日志中的数据看起来与在 Etherscan 上看到的内容差别很大。主要挑战在于缺乏上下文——每个字段或值的意义——以及所有内容都以字节(十六进制格式)存储。
原始交易收据的示例。
解码是将原始事件和追踪中的数据翻译为人类可读格式(包含函数和参数名称)的过程,使用合约 ABI。只有在你能够访问合约 ABI或原始 Solidity 代码的情况下,这一过程才能得以实现。
上述交易日志,翻译为可读事件。它是将 4.10^17 wad 存入 WETH 的存款,目标账户为 0x82273BFbAcF1C07c4EEa6b1460F8A36479dE648c。
进行这种转换的原因是,智能合约以操作码的形式存储在链上——这是一组低级的 EVM 可读指令——而不是以 Solidity 语言存储。Solidity 是一种高级语言,编译成操作码,这些操作码被节点执行。节点并不知道生成操作码的原始 Solidity 代码,因此缺乏有关函数名称、参数名称和输出含义的信息。
要访问合约代码,必须通过某人公开已部署的代码,通常是通过将其提交到数据库或像 Etherscan 这样的服务。拥有 Solidity 代码后,你可以编译它,将其与链上的操作码进行比较,并验证其真实性。或者,你可以使用从 Solidity 编译步骤生成的 合约 ABI。ABI 将函数和事件的签名映射到其实际名称,并包含参数的编码细节,如字大小和变量类型。然而,值得注意的是,并非所有合约代码和 ABI 都是公开可用的,这意味着并非所有合约和交易都可以被解码。
什么是它? - 解码数据包括已翻译为人类可读参数的日志、追踪、转移和视图函数。在数据流中,几乎总是会对某种形式的解码进行处理,即使对于不太常见的数据类型也是如此。
示例:解码的追踪、解码的日志、ERC20转移事件
用例:
通过转换解码数据获得的指标:
将所有解码的追踪、日志和 ERC20 转移事件提取并加载到表格中,是建立 ELT(提取、加载、转换)过程的最方便方法,允许衍生出广泛的协议数据。
现在你可以使用所有这些数据了,转换基础设施需要处理这些数据并将其转换为有意义的指标。转换引擎在不同公司之间可能有很大的不同;它们可以从简单的 Python 笔记本到复杂的数据仓库基础设施(如 Dagster/Airflow、DBT、Snowflake/Databricks)不等。
转换过程可以接受原始或解码数据,以及其他链上来源,并结合价格或其他链外数据以生成指标输出。在流图中,你会注意到多条箭头将数据导入转换引擎。在数据转化后,输出可以保存并部分或全部重新用于进一步的转化。数据处理本质上是一个无尽的循环,将先前的输出重新塑造和精炼,以提取新的见解。
什么是它? - 转换数据由从所有可用来源(包括原始和解码)派生的业务级指标或聚合数据构成。在收集了所有原始和解码信息后,下一步是操作并组合这些信息以创建有意义的指标。转换数据是任何数据转换过程的输出,常常存储以备将来使用,以避免重新计算。通过一次转换数据并在必要时重复使用,可以优化效率和性能。
示例:Uniswap 交易、Aave TVL、DEX 交易
用例:
用户通常寻求生态系统级数据,例如“DEX 产生了多少交易量?”、“DeFi 中锁定的总价值(TVL)是多少?”或“加密社交平台有多少用户?”这类问题很少有捷径;相反,它们通常需要一步一步的“穷举”方法来生成有意义的答案。这涉及为单一协议(例如 Uniswap)创建指标,随后聚合多个协议的指标(例如以太坊 DEX)的指标,最终跨多个链聚合这些指标以反映更广泛的市场(例如整个 DEX 生态系统)。
示例指标:
什么是它?链外数据是指任何不源自区块链节点的数据。通过整合不可链上获取的数据,可以显著增强区块链指标,这些数据通常来源于外部数据提供商。中心化交易所(CEX)是最常见的来源,尤其是在将指标转换为美元时,因为它们在特定时间提供所需的代币价格信息。此外,一些数据可能存在于更中心化或半去中心化的数据库中。直接将这些数据导入系统可以作为提取-翻译-转换过程的捷径。
示例:
示例指标:
价格在加密数据流中扮演着如此关键的角色,以至于值得专门解释。在加密世界中,没有单一的、明确的价格真相来源。每个交易所和区块链可以在任何给定时刻对同一交易对有不同的价格。为了解决这个问题,价格表旨在从多个来源(包括中心化交易所(CEX)和去中心化交易所(DEX))聚合并加权平均(TWAP)这些价格,以得出某一时间的单一代表性价值。
这一过程并不简单;它涉及输入已知价格、计算成交量、删除异常值以及过滤延迟或不那么具有代表性的市场。通过仔细处理这些步骤,这一过程中确保获得更准确可靠的价格指标,从而反映更广泛的市场动态。
什么是它? - 这指的是提取自区块链的预索引数据,这些数据较少标准化且更为特定。区块链不仅存储区块、交易和日志;它们还包含多种其他类型的数据,这些数据可能需要额外的步骤来提取,并且通常更难标准化为表格格式。虽然 EVM 兼容链通常有明确的标准,但一些更特殊的链(例如 Beacon chain)也生成和存储独特的数据。根据你的应用,数据需求可能完全集中于这些特定和不太常规的数据类型,而该过程可能并不像上述步骤那样明确。
示例包括:
以下是一些有限的示例,尤其与网络和协议指标相关:
示例 | 它是什么? | 复杂性 | 这对 ELT 过程有何复杂性? | 用例 |
---|---|---|---|---|
代币元数据 | 代币的名称、符号和小数;通过视图调用提取。 | 简单 | 识别代币合约;处理可变值。 | 将代币地址翻译为名称和符号;计算实际金额。 |
ERC20 视图函数 | 从 ERC20 提取的 BalanceOf 和 SupplyOf;通过视图调用提取。 | 中等 | 何时触发用于索引的调用?捕捉所有值变化(如,重基、合约构造)? | 随时间跟踪钱包余额;监控代币供应变化。 |
合约特定视图函数 | 视图函数访问状态并输出相关合约的数据。 | 难 | 何时触发用于索引的调用?人们关心哪些功能? | 创建在日志或追踪中没有出现的协议指标。 |
状态变化 | 每个交易的状态差异。 | 难 | 解码状态变化;确定哪些内存地址需要索引。 | 创建在日志或追踪中没有出现的协议指标。 |
合约内部变量 | 执行期间保存但未存储的变量。 | 难 | 需要运行时执行访问;识别相关变量进行索引。 | 创建在日志或追踪中没有出现的协议指标。 |
影子/幽灵日志 | 修改合约代码产生的附加日志。 | 难 | 确定哪些是用户所需的影子日志;重写适当的代码。 | 访问内部状态和变量,格式化为日志。 |
在 EVM 兼容的区块链中,许多被分类为“其他链上数据”的数据可以通过“视图函数”的输出进行访问。视图函数 是一种 Solidity 函数,它不修改区块链状态;相反,它们仅读取和转换现有状态数据。这种编程方法允许你读取网络状态并将数据返回给代码中的其他函数。由于视图函数不改变状态,因此它们可以在不产生Gas费用的情况下执行。
你也可以向节点进行外部视图函数调用(在 Etherscan 中,读取合约选项卡),因为客户端节点实现了 API 以执行这些调用并返回结果。然而,存在一个限制:常规客户端节点不存储历史状态数据,因此视图函数只能返回调用时的最新状态。
一个天真的管道设计用于索引视图函数输出,只会捕获在请求时的当前状态的数据。为了收集历史数据,你需要从创世块启动节点,并每次需要索引时同步请求,或者使用能够返回历史状态的历史节点。
第二个挑战是视图函数的输出并不总是对状态的直接表示——它也可能涉及转换。例如,BalanceOf
函数返回账户的代币余额。对于标准代币,余额被存储为状态映射,但对于重基代币,余额计算为 amount_scale
* rebase_index
,其中 rebase_index
是一个全局变量,可以同时调整所有账户余额。当每个块有几千个账户重基时,索引此数据可能快速导致数十亿行。如果将 amount_scale
和 rebase_index
进行索引,则可以在每次需要时计算用户余额,从而表示的数据量要少得多。
这导致了第三个挑战:确定何时索引。你需要定义索引触发条件,例如每个块、每个转移事件,或每当特定调用追踪发生时。由于每个应用的需求各不相同,因此通常需要自定义管道。
总之,与视图函数的工作可能非常复杂,为存储视图函数输出设计有效的 ELT 过程需要深思熟虑的规划和战略性的方法。
理解加密数据流对任何在区块链领域工作的人都至关重要。本文探讨了数据流动过程中的关键步骤——从获取原始链上数据到使用客户端节点、请求管道和转换引擎将其转变为可操作的指标。我们探讨了解码数据的重要性、处理视图函数调用以及整合链外信息(如价格),强调了每个过程中的复杂性和细致需求。
有效管理加密数据流是生成有价值见解和指标的基础,推动更好的决策和创新。随着区块链生态系统的不断发展,掌握这些数据流将是保持领先、充分利用区块链潜力的关键。
也发在 这里
- 原文链接: research.2077.xyz/explor...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!