3.1 API调用案例实操

📢 投研手册共建招募中 我们正在组团打造一份超实用、还不无聊的研究手册📘

📩 发邮件到:zey9991@gmail.com 邮件标题写:【投研手册协作申请】+ 你的名字

✍️ 内容包括:想参与的方向、过往经验和每周可投入时间

🧠 你会收获什么?新朋友、写作技巧、项目视角、署名机会,还有可能是下一段旅程的开始!

🧱前置要求

在开始本节内容之前,你需要具备以下基础条件:

  1. 具备科学上网能力:大多数链上数据API服务托管在海外服务器,访问需保证网络畅通。

  2. 具备基础Python环境(推荐):本节将提供可实操的代码示例,建议你已在本地安装好 Python(3.8+ 版本)并配置好开发环境(如 VSCode、Jupyter Lab)。不过,即便未安装,课程内容也可作为原理学习,无妨理解。

🎯学习目标

基础目标:

  • 理解什么是API(Application Programming Interface);

  • 掌握调用API的一般流程及关键概念。

进阶目标:

  • 理解API与ABI合约接口)、RPC远程调用协议) 的区别;

  • 能够自主调试并成功调用Dune Analytics 的官方 API,用于获取链上数据结果。

❓为什么要用 API,而不是直接看图表或导出 Excel?

在DeFiLlama、Token Terminal、Dune 等数据平台上,很多指标已经被做成了图表,甚至有些平台提供原始数据下载选项。那么问题来了:“我直接用这些图表或者导出Excel不就好了吗?为什么还要专门学 API 调用?”

这是一个好问题,以下是本节提出学习 API 的几个关键理由:

✅ 1. 数据获取权限差异:有时“导出”功能是会员专属,而“API”反而是免费的!

比如,Dune Analytics 除非开通会员,否则不能导出图表数据。但Dune 官方提供了免费额度的 API 调用服务,普通用户只需获取 API Key,便可以以编程方式访问数据,这比截图或手动复制更专业、可控、自动化。

📌 本文后续重点将以 Dune 的 API 为案例,手把手教你如何完成一次数据拉取。

✅ 2. 数据分析自由度更高:跳出图表“限定”,灵活组合你自己的数据处理逻辑

平台提供的图表通常已预设好统计维度(如TVL趋势、用户增长),但你可能有自己的需求,例如:

  • 合并多个项目的TVL数据进行横向对比;

  • 计算某类协议的平均杠杆率或净收益率;

  • 拉取某钱包地址过去三个月的交互次数、Gas消耗等指标。

这些灵活处理逻辑,只能通过拿到原始数据并用自己熟悉的工具(Python、Excel、SQL等)进一步加工来实现。

✅ 3. 自动化数据更新:为动态仪表盘或定期报告提供“活数据”

API调用最大的好处之一是可以周期性地自动请求和更新数据。例如,你可以写一个脚本每天抓取 Token 解锁数据、每日交易量或TVL变化,并将其自动更新到一个可视化仪表盘中(比如Notion、Google Sheet或本地网页)——这样你的研究报告就能持续保持“鲜活”,不用每次都手动刷新。

虽然本节不会深入讲自动化流程,但掌握 API 是走向数据自动化的第一步。

✅ 4. 数据集成能力:将链上数据“嵌入”到你的前端产品、爬虫脚本、看板工具中

想象你正在构建一个投资策略工具,你希望它能实时显示某个池子的年化收益率变化图。通过 API,你就可以将数据“嵌入”到你的产品中,而不是依赖别人做好的嵌套图表。

本节课程不涉及前端集成内容,但你可以把 API 理解为数据和产品之间的“数据运输管道”,掌握它就像掌握了 Web3 数据的第一道“水源”。

🌉什么是 API?

🧠 从抽象思维说起

抽象思维使得我们能分别从逻辑视角和物理视角来看待问题及其解决方案。举一个常见的例子:

试想大家每天开车上学或上班。作为司机——车的使用者,我们在驾驶时会通过与车的一系列交互到达目的地:坐进车里,插入钥匙,启动发动机,换挡,刹车,加速以及操作方向盘。从抽象的角度来看,这是从逻辑视角来看待这辆车。我们使用汽车设计者提供的功能进行通勤。这些功能也被称作接口

而修车工看待车辆的视角与司机截然不同。他不仅需要知道如何驾驶,而且需要知道实现汽车功能的所有细节:发动机如何工作,变速器如何换挡,如何控制温度,等等。这就是所谓的物理视角,即看到表面之下的具体实现细节

使用计算机也是同理。大多数人不需要了解计算机的实现细节就能写文档、收发邮件、浏览网页、听音乐、存储图像以及打游戏。大家都是从逻辑视角或者使用者的角度来看待计算机。 计算机科学家、程序员、技术支持人员以及系统管理员则从另一个角度来看待计算机。他们必须知道操作系统的原理、网络协议的配置,以及如何编写各种脚本来控制计算机。他们必须能够控制用户不需要了解的底层细节。

上面两个例子的共同点在于,用户(或称客户)只需要知道接口是如何工作的,而并不需要知道实现细节。这些接口是用户用于与底层复杂的实现进行交互的方式。这一思想在编程中被广泛采纳,称为抽象化设计原则

让我们再看一个软件中的例子:Python 的 math 模块。

import math
math.sqrt(16)

在这段代码中,我们调用了 sqrt 函数来求 16 的平方根。你无需了解平方根的计算细节或背后的数学实现过程。你只需要知道:这个函数的名字是 sqrt,它接受一个数字作为输入,并返回该数字的平方根。

这是一个过程抽象(procedural abstraction)的例子。我们并不需要知道平方根究竟是如何计算出来的,而只需要知道计算平方根的函数名是什么以及如何使用它。只要正确地导入模块,便可以认为这个函数会返回正确的结果。由于其他人已经实现了平方根问题的解决方案,因此我们只需要知道如何使用该函数即可。这有时候也被称为过程的“黑盒”视角。我们仅需要描述接口:函数名、所需参数,以及返回内容。所有的计算细节都被隐藏了起来。

这一过程也可以类比成日常生活中使用家电——比如我们只需要按下洗衣机的“启动”按钮,而不需要了解它的水泵、滚筒和电路系统如何运作。

💻 什么是应用程序接口(API)?

从软件开发的角度来看,应用程序接口(API,Application Programming Interface)是程序之间通信的一种机制。它不是为“人”设计的操作界面,而是专门为“程序”之间的交互所设定的一组规则和标准。

简单来说,API 是一个程序对外公开的“使用说明书”:其他程序可以通过它来请求服务或访问数据,而不需要知道这些服务或数据是如何被组织、存储或计算的。

虽然“接口”一词在不同上下文中有多种含义,但“应用程序接口”这个概念特指软件与软件之间的数据交换机制。相比“人-机交互”的界面(如图形界面 GUI),API 更像是“机-机交互”的协议语言。

📬 一个API调用的完整流程(以天气数据为例)

想象你正在开发一款天气应用,目标是显示某个城市当前的气温、湿度和天气状况。你有两种方案可以选择:

  • 方案一:自己搭建一个天气数据采集网络,在各个地区部署气象传感器,收集温度、湿度、风速等原始数据,并自行处理。这不仅成本高、技术难度大,而且维护成本极高。

  • 方案二:调用已有的天气API,比如 OpenWeather API。它已经在全球部署了传感器、气象模型与数据处理系统,并为开发者提供统一的接口来访问这些数据。

方案二显然更加高效,也体现了API的巨大价值。下面是典型的API调用流程:

  1. 向API发送请求:你的天气应用可以向OpenWeather API发送一个HTTP请求,指定要查询的城市。例如,如果用户在北京,应用会向以下URL发送请求:

    https://api.openweathermap.org/data/2.5/weather?q=Beijing&appid=YOUR_API_KEY

    这条请求的意思是:“你好,请告诉我北京市当前的天气。” 其中:

    • q=Beijing 指定查询城市;

    • appid=YOUR_API_KEY 是你的访问密钥,用于身份验证。

  2. API响应数据:服务器收到请求后,会查询后台数据库,然后返回一段 JSON 格式的数据。比如:

    {
      "weather": [
        { "description": "clear sky" }
      ],
      "main": {
        "temp": 15.0,
        "humidity": 72
      }
    }

    这表示当前天气为“晴空”,温度为15°C,湿度为72%。

  3. 处理并展示数据:应用接收到数据后,就可以提取其中的字段。比如,“weather[0].description”描述了天气状况为“clear sky”(晴空),main.temp给出温度为15摄氏度,main.humidity显示湿度为72%。然后,你的应用会将这些信息显示在用户界面上。用户看到的只是数据结果,而无需了解这些数据的来源或处理过程。

📦 类比理解:API 就像外卖平台

将 API 想象成一个外卖系统:

  • 你(应用程序)通过菜单(API 文档)选择想要的餐品(数据或功能);

  • 外卖平台(API 提供方)负责联系餐厅(后台服务)、打包配送(数据处理与响应);

  • 你只需“下单”并接收结果,完全不需要知道背后的流

顺带解释几个关键术语

在上面天气 API 的例子中,我们已经了解了接口如何连接应用与服务。但在这个过程中,你可能还注意到了一些看起来“技术味儿十足”的词汇。别担心,接下来我们将逐一拆解它们,帮你厘清每一个概念背后的含义。

什么是URL?

URL(Uniform Resource Locator,统一资源定位符)是我们在互联网上查找和访问资源(如网页、图像、视频或API)的地址。它就像是每个网站或服务的“家地址”,告诉浏览器或应用在哪里找到特定的信息。

URL由几个部分组成:

  1. 协议(如HTTP、HTTPS):指示如何访问资源。

  2. 主机名(如www.example.com):网站的服务器地址。

  3. 路径(如/contacts):资源在服务器上的位置。

  4. 查询字符串(如?q=search):用来传递额外参数。

例如,https://api.openweathermap.org/data/2.5/weather?q=Beijing&appid=YOUR_API_KEY是一个访问天气数据的URL,其中包含了查询城市和API密钥的参数。

什么是HTTP请求?

在使用天气API获取数据时,API通过一种叫做HTTP请求的方式接收和发送数据。这种请求就像一封信,里面包含了你希望API完成的指令。

HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上用来发送和接收数据的主要协议。可以把它想象成一种“网络语言”,让不同的计算机可以相互交流。在API场景中,HTTP请求常用于发送特定指令并接收数据,比如获取天气信息。

在我们的天气应用中,当我们需要查询某个城市的天气时,应用会发送一个HTTP GET请求。GET请求是一种特定类型的HTTP请求,用于向API“索取”数据。就像在餐厅点菜一样,你说出你想要的菜品,服务员就会去帮你准备。通过HTTP GET请求,我们可以向API“索取”一个城市的天气信息,而API会根据请求内容返回相应的数据。

在我们的例子中,请求的格式可能是这样的:

https://api.openweathermap.org/data/2.5/weather?q=Beijing&appid=YOUR_API_KEY

其中的https://api.openweathermap.org 是API的基本地址,类似于邮寄地址。

什么是JSON格式?

当API收到我们的请求并处理完毕后,会将结果“打包”成一种称为JSON(JavaScript Object Notation,JavaScript对象表示法)的格式发送回来。可以将JSON想象成一个井井有条的包裹,里面放着我们点的菜品:温度、湿度、天气描述等。JSON格式的结构简单,易于人和机器理解,因而广泛用于Web开发和API数据传输。

在天气应用中,API可能返回以下的JSON数据:

{
  "weather": [
    { "description": "clear sky" }
  ],
  "main": {
    "temp": 15.0,
    "humidity": 72
  }
}

这里的JSON数据包含多个键值对(key-value pairs),每个键表示数据的名称(比如"temp"表示温度),每个值对应实际数据(比如15.0摄氏度)。这些数据会由天气应用解析和展示。

JSON的语法格式也是非常简单的,可以简单了解一下:

  • 数据在名称/值对中

  • 数据由逗号 , 分隔

  • 使用斜杆 \ 来转义字符

  • 大括号 {} 保存对象

  • 中括号 [] 保存数组,数组可以包含多个对象

🛠️ 如何调用 API?

🔄 什么是 JSON API?

在实际开发中,我们最常接触到的 API 类型之一就是 JSON API。这是一种专门使用 JSON(JavaScript Object Notation)格式传输数据的 API 规范,广泛应用于 Web 服务中,具有以下几个显著特点:

  • 统一的 JSON 数据结构:JSON API 定义了数据本体、关系、元信息的标准表示方法,使响应格式更加统一,方便前端解析。

  • 规范的响应格式:规定了数据应如何组织,例如使用 data 字段封装主体信息,使用 errors 表示错误信息,使用 meta 包含元数据等。

  • 自动化处理友好:由于响应结构固定且标准化,开发者可以编写更少的自定义代码来解析和处理数据,提高开发效率并减少出错概率。

📊 案例:DeFilama

DeFiLlama 是当前 DeFi 领域最权威的 总锁仓价值(TVL)聚合平台。其数据完全开源,并由一群来自不同协议的贡献者共同维护,覆盖了市面上大部分主流链和项目。

你可以点击下方按钮查看其官方 API 文档:

DeFilama的API文档

现在我们以获取 Pendle 协议在所有链上的历史 TVL 数据(单位:USD) 为例,演示如何调用这个 API。

🧭 第一步:选择接口

首先,我们需要在文档中找到对应的接口。浏览文档后,可以定位到下图中的接口用于获取指定协议的历史 TVL 数据:

点击右上角的 “Try it out” 按钮,在 Protocol 一栏输入 Pendle,然后点击 “Execute”,将会看到如下界面:

可以看到Responses(响应)下面多了很多信息,让我们来逐个看看:

  • Curl:一种命令行工具,用于模拟 API 请求。虽然对了解请求结构有帮助,但本文暂不使用它。

  • Request URL(请求地址):即向 API 发送请求的地址,此例中为: https://api.llama.fi/protocol/pendle

  • Server Response(服务器响应)

    • 状态码 200 表示请求成功。

    • Response body 是实际返回的数据,格式为 JSON。

    • Response headers 包含响应格式和缓存策略等元信息。

🔍 第二步:定位数据字段

接下来,我们要分析 Response Body,确定 TVL 数据在 JSON 结构中的具体位置。

你也可以直接访问该链接查看原始响应数据:

不过这个 JSON 文件内容非常庞大(超过 34 万行),用肉眼浏览极不现实。建议使用可视化工具辅助查看,比如这个在线 JSON 查看器:

将完整的 JSON 内容粘贴进去,在 “Viewer” 标签页中即可查看其结构化格式。可以发现我们需要的历史 TVL 数据位于 tvl 这个数组下,如下图所示:

📥 第三步:提取并导出数据

现在我们知道了目标字段的位置,就可以使用代码将其提取并导出为表格(如 Excel)。以下是用 Python 实现的完整流程,当然你也可以选择 JavaScript、R 或其他你熟悉的语言:

📌 提示:代码无需死记硬背,有 AI 模型帮你写就行 😉

import requests # 用于发送 HTTP 请求,可选择其他库
import pandas as pd # 数据处理和存储库

# 设置 API URL
url = 'https://api.llama.fi/protocol/pendle'
# 发起 GET 请求
response = requests.get(url)
# 检查响应状态
if response.status_code == 200:
    # 将 response 的内容转换成 JSON 格式的 Python 字典。
    data = response.json() 
else:
    # 如果请求失败,打印出状态码以便于调试。
    print(f"Error: {response.status_code}")   
# 提取 tvl 部分数据
chain_data = data['tvl']
   
# 使用Pandas库进行数据类型的转换
# 将提取的数据加载到 DataFrame 中
df = pd.DataFrame(chain_data)
# 将日期转换为可读格式(可选)
df['date'] = pd.to_datetime(df['date'], unit='s')    
# 导出为 Excel 文件
df.to_excel('pendle_tvl_data.xlsx', index=False)  # index=False 可以不保存行索引
print("数据已成功保存为 pendle_tvl_data.xlsx")

如果一切顺利,你将在当前工作目录中看到一个名为 pendle_tvl_data.xlsx 的文件,其中包含 Pendle 的历史 TVL 数据。

[!TIP]

如果出现报错PermissionError: [Errno 13] Permission denied: 'pendle_tvl_data.xlsx',请确认是否 Excel 文件仍在打开状态。关闭该文件后重新运行代码即可。

📈 案例:Dune

Dune Analytics 是一个开源的数据分析平台,允许任何人使用 SQL 编写查询、构建可视化仪表板,并公开发布或私密保存。这使得区块链数据的提取与分析变得前所未有的高效与灵活。Dune 提供了丰富的数据接口,让开发者能够通过 API 自动获取分析结果,并将其用于数据展示、研究或其他自动化任务中。

🔐 获取 API Key

与 DeFiLlama 不同,Dune 的 API 是受限访问的,你必须先申请并配置 API Key 才能使用其服务。API Key 的作用包括:

  • 用户身份识别:平台可根据 Key 判断你是否为付费用户,控制访问权限与调用频率;

  • 用量追踪与配额管理:防止滥用,确保平台稳定运行;

  • 数据访问保障:部分数据接口可能仅对付费用户开放。

若你是首次使用,请访问以下链接以生成 API Key:

选择新建一个Key:

自行输入API Key名字后点击生成

复制并妥善保存 API Token(密钥):

⚠️ 安全提醒:虽然 API Key 不直接控制链上资产,但一旦泄露,可能会导致数据滥用、配额耗尽、甚至付费账户被盗刷等严重后果。因此建议:

  1. 切勿将 API Key 写死在代码中上传至 GitHub 等平台;

  2. 可使用 .env 文件或系统环境变量管理;

  3. 一旦怀疑密钥泄露,应立即吊销并重新生成。

🎯 选择查询接口

接下来,我们选取一个你已经构建好的仪表盘作为演示案例:

我们希望获取如下图所示的图表数据(例如:gTrade 月活用户数):

点击图表后会弹出一个提示,说明你可以通过 API 获取该查询结果:

📦 安装客户端并定位数据

Dune 提供了官方的 Python SDK dune-client,可以通过 pip 安装:

pip install dune-client

不同的是,这次我们无法直接预览Response body,也无法确定其到底是不是一个JSON文件。为此,我们可以尝试:

from dune_client.client import DuneClient

# 设置 API 密钥
api_key = "<此处替换成你的API Key>"  
dune = DuneClient(api_key)
# 设置要执行的查询 ID
query_id = 4208661  # 替换为你的查询 ID
# 获取最新的查询结果
query_result = dune.get_latest_result(query_id)
if query_result:
    print(type(query_result))
else:
    print("No results returned.")

输出显示 query_result 是一个自定义类 ResultsResponse 的实例,而非普通的 Python 字典或 JSON 对象。因此,我们需要借助工具如 jsonpickle 对其进行序列化:

from dune_client.client import DuneClient
import jsonpickle  # 用于序列化非 JSON 格式的对象

# 设置 API 密钥
api_key = "<此处替换成你的API Key>"  
dune = DuneClient(api_key)
# 设置要执行的查询 ID
query_id = 4208661  # 替换为你的查询 ID
# 获取最新的查询结果
query_result = dune.get_latest_result(query_id)
# 检查结果并保存为 JSON 文件
if query_result:
    # 使用 jsonpickle 进行序列化
    json_data = jsonpickle.encode(query_result, unpicklable=False)
    # 将结果写入 JSON 文件
    with open("dune_query_result4208661.json", "w") as file:
        file.write(json_data)
    print("Data saved to dune_query_result4208661.json")
else:
    print("No results returned.")

然后你可以将文件粘贴至 JSON Viewer 等可视化工具中查看结构:

可以发现我们需要的数据存放在result键下面的rows子键的值(数组)里面:

{
  "result": {
    "rows": [...]
  }
}

🧪 提取和导出数据

接下来我们直接提取 rows 中的内容,并导出为 CSV 表格:

from dune_client.client import DuneClient
import jsonpickle  # 用于序列化非 JSON 格式的对象
import pandas as pd 

# 设置 API 密钥
api_key = "<此处替换成你的API Key>"
dune = DuneClient(api_key)
# 设置要执行的查询 ID
query_id = 4208661  # 替换为你的查询 ID
# 获取最新的查询结果
query_result = dune.get_latest_result(query_id)
# 检查结果并保存为 JSON 文件
if query_result:
    # 提取 rows 数据
    user_data = query_result.result.rows  # 直接从 'result' 中提取 'rows'
    # 转换为 DataFrame
    df = pd.DataFrame(user_data)
    # 保存为 CSV 文件
    df.to_csv("gTrade_monthly_users.csv", index=False)
    print("Data saved to gTrade_monthly_users.csv")
else:
    print("No results returned.")

最终你应能在文件夹中看到下图所示的数据文件:

🧠 Dune API免费限额说明与优化建议

Dune API 的调用存在配额限制。根据官方说明:

  • 免费账户每月有 2,500 个 Credits

  • 1,000 个数据点消耗 1 个 Credit

  • 即每月最多可处理 2,500,000 条数据

✅ 避免重复请求

如前文所示,如果你在同一个脚本中多次使用了相同的查询 ID,最好将结果缓存下来:

from dune_client.client import DuneClient
import jsonpickle  # 用于序列化非 JSON 格式的对象
import pandas as pd 

# 1.定位数据
# 设置 API 密钥
api_key = "<此处替换成你的API Key>"  
dune = DuneClient(api_key)
# 设置要执行的查询 ID
query_id = 4208661  # 替换为你的查询 ID
# 获取最新的查询结果
query_result = dune.get_latest_result(query_id)
# 检查结果并保存为 JSON 文件
if query_result:
    # 使用 jsonpickle 进行序列化
    json_data = jsonpickle.encode(query_result, unpicklable=False)    
    # 将结果写入 JSON 文件
    with open("dune_query_result4208661.json", "w") as file:
        file.write(json_data)
    print("Data saved to dune_query_result4208661.json")
else:
    print("No results returned.")
  
# 2.提取数据
user_data = query_result.result.rows  # 直接从 'result' 中提取 'rows'
# 转换为 DataFrame
df = pd.DataFrame(user_data)
# 保存为 CSV 文件
df.to_csv("gTrade_monthly_users.csv", index=False)
print("Data saved to gTrade_monthly_users.csv")

✅ 避免频繁调试阶段浪费 Credits

在开发过程中,每次运行脚本都可能重新消耗 Credits。建议先手动将 JSON 文件保存至本地,开发阶段使用本地文件调试,确认逻辑正确后再连接 API。

此外,根据笔者经验,大部分情况下所需要的数据都存储在query_result.result.rows中,因此很多情况下我们可以跳过分析响应体结构定位数据这一步,直接针对性提取所需数据即可:

#实操中只要微调这部分的代码即可
from dune_client.client import DuneClient
import jsonpickle  # 用于序列化非 JSON 格式的对象
import pandas as pd 
# 设置 API 密钥
api_key = "<此处替换成你的API Key>"
dune = DuneClient(api_key)
# 设置要执行的查询 ID
query_id = 4208661  # 替换为你的查询 ID
# 获取最新的查询结果
query_result = dune.get_latest_result(query_id)
# 检查结果并保存为 JSON 文件
if query_result:
    # 提取 rows 数据
    user_data = query_result.result.rows  # 直接从 'result' 中提取 'rows'
    # 转换为 DataFrame
    df = pd.DataFrame(user_data)
    # 保存为 CSV 文件
    df.to_csv("gTrade_monthly_users.csv", index=False)
    print("Data saved to gTrade_monthly_users.csv")
else:
    print("No results returned.")

✅ 总结:调用 Web3 数据 API 的标准流程

结合我们在 DeFiLlama 和 Dune 两个案例中的实战,可以总结出一套标准化的调用流程(SOP):

步骤
操作内容
工具或建议

1️⃣ 获取 API Key

若平台需要身份验证,先申请密钥

通过平台设置页获取

2️⃣ 选择接口

根据目标数据选择合适接口或查询 ID

浏览文档或使用 Dashboard 图表

3️⃣ 定位数据

分析 JSON 或响应结构,找到目标字段

推荐使用 JSON Viewer

4️⃣ 提取数据

编写代码提取所需数据

Python、Pandas、dune-client

5️⃣ 导出与应用

保存为表格并用于后续分析或展示

支持 CSV、Excel 等格式

🔁 附加优化

避免重复调用,节省配额

推荐缓存结果或定时调用

📚 提示:很多 API 平台(如 Covalent、Nansen、Footprint 等)也提供类似服务。你可以基于本节方法类比学习、快速上手。

本课总结

在 Web3 项目投研中,“如何把握实时、结构化的数据”,是一道从初学者迈向专业研究者的分水岭。本节课程围绕链上数据的核心入口——API(应用程序接口),带你从概念理解走向动手实操,完成了一次真正“能产出、有输出”的数据调用流程。

我们从“为什么要用 API 而不是图表或导出 Excel”出发,明确了 API 在权限获取、分析自由度、自动化能力与产品集成等维度的独特优势;接着,结合天气 API 的通俗类比,帮助你建立起对 API 本质的认知——它是程序与程序之间的数据对话协议,而非仅供程序员使用的“高冷工具”;最后,通过 DeFiLlama 与 Dune 两个真实平台的调用案例,我们一步步拆解了 API 使用的五个关键步骤:获取密钥、选择接口、定位数据、提取结果、导出文件

更重要的是,我们不仅教会你“如何调用”,更引导你思考“如何用得专业”:例如,如何避免重复调用浪费配额、如何在调用中保护 API 密钥安全、如何将结果作为结构化资产,融入你的数据分析或研究报告。

你将发现,API 不只是工程师的玩具,更是投研人员的工具。它帮助你越过平台图表的“数据围墙”,进入数据背后的逻辑工厂;它让你的研究从“看别人给的图”变为“做自己要的图”;它让你真正掌握 Web3 的“源头活水”。

从本节开始,你已迈出了研究者工程化素养的关键一步。在接下来的课程中,我们将继续探索如何基于这些数据源,构建更加系统的指标框架与商业分析体系。唯有掌握获取真数据的能力,才有资格发出真观点的声音。

课后思考

  1. 理解“调用”的本质 回顾本节课程中你接触到的 API 示例(如 DeFilama ),请思考:

    • 你调用的是一段“程序”还是“数据”?

    • 请求中携带的 URL、参数、Header 等,分别起到了什么作用?

    • 如果接口失效了,你认为可能的原因有哪些?你会如何排查?

  2. 从“复制调用”到“理解接口” 许多开发者或研究者习惯直接复用别人写好的 API 请求代码。请反思你自己以往的实践:

    • 你是否了解自己调用的接口具体返回了哪些字段?它们之间是什么结构关系?

    • 请你挑选一个你曾使用过的 API(不限于 Web3),试着用“类 JSON 树状结构”画出它的返回内容结构图,并解释每一层的意义。

  3. 对比不同接口设计思路 DeFilama的数据无需授权即可获取,而一些链上 API(如 Dune )则需要提供 API Key。

    • 你认为这背后的技术和商业逻辑是什么?

    • 如果你是一家数据服务商,你会选择哪种模式来开放接口?为什么?

  4. 实操路径演练 假设你现在要研究一个刚上线的 DeFi 项目,请设计一套基础的 API 调用方案,用以获取以下三类数据:

    • 项目的代币价格与市值;

    • 当前锁仓资产总量(TVL);

    • 最近 7 天的活跃地址数。 请你分别写出你会优先尝试的接口来源、预期字段和可能遇到的难点。

  5. 从调用到信任:数据质量判断 本课提到一个重要理念:“我们不只是为了找到数据,而是为了理解数据与信任数据”。

    • 如果某一数据来源与你手工计算的结果出现偏差,你会采取哪些方法进行验证?

    • 除了查看接口文档,你还可以通过哪些方式理解数据背后的计算逻辑?

附录:API、ABI 与 RPC 全景梳理

API

ABI

RPC

主要用途

应用程序之间的通信接口

低级别二进制格式的规范

远程调用其他计算机上的程序

适用场景

软件功能的调用(如天气API、支付API)

程序、操作系统、编译器的兼容性、以太坊智能合约的交互

分布式系统的远程交互(如区块链节点)

示例

提供一组函数供应用调用,例如天气API接口

定义智能合约的函数格式,方便DApp交互

客户端通过RPC向区块链节点发送请求

✅ ABI:应用二进制接口

ABI(Application Binary Interface,应用二进制接口) 是一套用于描述程序之间在底层如何交换数据的规范。它不仅规定了参数的类型和顺序,还定义了如何将数据编码为二进制格式,以及如何解码返回值。

在以太坊中,ABI 是智能合约交互的“通用语言”。每一个 DApp 想与合约对话,必须遵循这个标准,以确保发出的请求和合约能“听得懂”。它不仅用于外部账户与合约的交互,也用于合约之间的调用

为什么重要?

设想每个合约都有自己一套编码方式——调用者必须为每个合约定制自己的解析规则,工程量巨大。而以太坊通过统一 ABI 编码格式(32 字节填充标准)解决了这个问题,使钱包、前端、脚本等工具能够与任意合约进行标准化交互。

类比理解:

ABI 就像“集装箱运输标准”——只要所有港口、船只和卡车都使用同一尺寸规格的集装箱,货物运输就高效无误。而 ABI 就是为“智能合约之间的数据”制定的这种“统一尺寸”。

应用场景:

  • 在合约开发中,配合 call 实现底层函数调用;

  • ethers.js 中,导入 ABI 即可调用合约函数;

  • 分析未开源合约时,通过 ABI 编码可构造调用数据。

直观演示:

我们可以通过在线ABI编码器网站直观地感受一下ABI编码标准:

例如,在Argument Types(参数类型)部分输入uint(无符号整数),然后在Argument values(参数值)部分输入10,我们会得到如下返回:

000000000000000000000000000000000000000000000000000000000000000a

参数类型填写address,参数值写0x7A58c0Be72BE218B41C608b7Fe7C5bB630736C71,得到返回的编码数据如下:

0000000000000000000000007a58c0be72be218b41c608b7fe7c5bb630736c71

参数类型填写address,uint,参数值写0x7A58c0Be72BE218B41C608b7Fe7C5bB630736C71,10,得到返回的编码数据如下:

0000000000000000000000007a58c0be72be218b41c608b7fe7c5bb630736c71000000000000000000000000000000000000000000000000000000000000000a

每个数据类型都会填充为 32 字节(64 位十六进制),未用完部分由 0 补齐。深入内容可参考 Solidity 文档或 EVM 规范。

✅ RPC:远程过程调用

RPC(Remote Procedure Call,远程过程调用) 是一种通信协议,允许一个程序像调用本地函数一样,调用远程服务器上的函数。它是分布式系统的核心机制,在区块链中广泛用于节点之间的数据交换

在 Web3 中,开发者通过 RPC 与区块链节点交互,例如:

  • 查询账户余额;

  • 获取区块高度;

  • 广播一笔交易等。

RPC 的“远程透明性”让我们无需关心节点具体实现,只需发出正确的请求,即可获得链上数据。

与 API 的关系:

  • API 是一个通用术语,代表程序之间交换信息的规则集合;

  • RPC 是一种特定类型的 API 调用形式,专注于“远程调用函数”;

  • 所有 RPC 都是 API,但并非所有 API 都是 RPC。

类比理解:

你使用 Siri 询问天气,Siri 背后会调用远程天气 API 获取数据;如果这个调用结构是通过 RPC 实现的,它就像远程执行了一个“getWeather()”函数——对你来说,它和调用手机本地函数没有区别。在这里,RPC使得远程任务感觉像是本地的,但这只是因为API结构管理了这种交互。

总结来说,API是用于交互的一般结构,而RPC是实现API以执行特定远程函数的一种方式。不是每个API都是RPC,但RPC是实现API驱动的远程通信的一种方式。因此,通常可以认为RPC包含了API的指令。

区块链开发中的 RPC:

在区块链上,开发者通常使用RPC与节点交互,查询链上数据或广播交易。例如,通过RPC接口,客户端可以请求链上账户余额,甚至发送交易到区块链网络。

C端用户其实不需要理解RPC到底是什么或者RPC怎么样工作,他们直接接触的是RPC提供商。RPC提供商允许开发者和应用程序无需自行运行完整节点即可访问区块链网络。像Infura、Alchemy和QuickNode这样受欢迎的RPC提供商负责处理复杂的基础设施,因此用户能够可靠且快速地连接到区块链节点。这种设置使开发者能够轻松地与智能合约交互、提交交易和查询数据。

当应用程序需要从区块链获取数据(例如钱包余额或交易详情)时,它会向RPC提供商发送一个RPC请求。提供商的节点会响应这个请求,通过检索并发送所需数据或执行所需功能(如将交易广播到网络)来回应。通过这种方式,RPC提供商提供了一个与区块链节点通信的直观接口,从而消除了每个开发者都需要管理自己节点的需求。

通过RPC提供商,开发者获得了可扩展且成本效益高的区块链访问方式,使他们能够专注于构建应用程序,而无需担心节点的维护工作。

你可以在 Chainlist 查看各链的 RPC 地址:

我们可以看到非常多区块链网络,让我们点击Ethereum Mainnet:

下拉可以看到非常多RPC URL,这些就是RPC请求的地址:

以太坊主网的RPC URL

另可访问 RPCList 查看主流 RPC 提供商的质量评分:

RPCList网站前端

读者可以访问Uniswap的前端:

然后按F12,选择Network,可以发现前端做了非常多的请求,其中一些就是RPC请求。比如下图选中的这个请求,其请求的地址(RPC URL)就是infura的地址,infura就是一个RPC提供商。

Uniswap前端的RPC请求

再另外随机点选一个类似的RPC请求,选中Payload(请求载体)可以看到这实际上请求获取的是以太坊的区块高度。

Uniswap前端的RPC请求

你看到的就是以太坊 JSON-RPC 的典型应用之一。

参考文献

内容声明

  1. AI 协助声明 本书部分内容由人工智能工具(如 ChatGPT)协助整理和润色,具体包括:内容草拟、语言优化、结构调整等。所有输出均经作者人工审校,力求表达准确、逻辑清晰。 若您对 AI 参与创作有所顾虑,建议谨慎阅读与参考。

  2. 署名与许可协议 除特别说明外,本书由 Peyton 撰写,隶属于 LYS Lab 研究团队原创发布,收录于项目 Web3-research-handbook(Web3 投研手册)。全文采用 Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International(CC BY-NC-ND 4.0) 协议共享。

    您可以在不修改内容、仅用于非商业用途的前提下自由转载和分享本书,但必须注明原作者与来源严禁擅自改编、删改或用于任何商业用途。作者及 LYS Lab 保留未来以其他方式授权或商用的全部权利。

    推荐署名格式示例:

    本文原载于《Web3-research-handbook(Web3 投研手册)》,由 Peyton 编写,隶属 LYS Lab,遵循 CC BY-NC-ND 4.0 协议发布。协议链接:https://creativecommons.org/licenses/by-nc-nd/4.0/deed.zh
  3. 免责声明 所有内容仅供学习交流使用,不构成任何投资、法律或其他实务建议。如书中引用第三方数据或接口,请以其官方文档为准。

最后更新于