摘要
Base NFT API 是一组 RPC 方法和索引数据服务,用于在 Base 网络上读取 NFT 所有权、元数据和转账历史。标准的 JSON-RPC 调用如 eth_call、eth_getLogs 和 eth_getBalance 覆盖链上读取,而索引器风格的 API 则添加预聚合的所有权和集合数据。本文解释了哪种方法适合哪种工作负载,以及如何可靠地连接。
您将了解如何通过 Base RPC 直接查询 ERC-721 和 ERC-1155 合约,何时索引器是更好的工具,以及如何配置生产端点。如果您需要为 NFT 密集型读取流量提供一致的吞吐量,OnFinality 提供 Base RPC API 访问和专用节点基础设施。
如果您搜索 Base NFT API,您可能需要在 Base 上读取 NFT 数据:谁拥有某个代币、某个集合包含什么,或者某个代币如何在钱包之间转移。Base 上没有单一的“NFT API”。相反,您需要将标准的 JSON-RPC 调用与可选的索引器服务结合使用,后者预聚合所有权和元数据。本页展示了每一层的作用、如何连接,以及如何保持生产环境中 NFT 读取流量的稳定。
哪种方法适合您的 NFT 工作负载
在编写代码之前,请确定您需要原始的链上读取还是预索引的数据。正确的选择取决于您希望自己进行多少聚合以及数据需要多新。
| 工作负载 | 最佳选择 | 原因 |
|---|---|---|
| 读取单个代币的所有者或余额 | Base RPC (eth_call) | 直接合约读取,在查询的区块上始终是最新的 |
| 列出钱包拥有的所有代币 | 索引器 API 或您自己的索引器 | 仅靠 RPC 无法在不扫描日志的情况下枚举持有量 |
| 获取集合元数据和图像 | 索引器 API 或 tokenURI + 链下获取 | 元数据通常位于 IPFS 或 HTTP 上,并非完全在链上 |
| 实时跟踪转账 | Base RPC (eth_getLogs 或 WebSocket) | 日志在转账事件发生时提供原始 Transfer 事件 |
| 回填完整的转账历史 | 支持归档的 RPC 或索引器 | 历史日志查询需要归档状态和仔细的分页 |
| 在链上验证铸造或销售 | Base RPC (eth_getTransactionReceipt) | 收据确认实际执行的内容 |
一个实用的模式是使用 Base RPC 进行权威的、时间点读取,并使用索引器进行列表式查询。许多团队同时运行两者:RPC 用于正确性,索引器用于聚合视图的速度。
Base 链设置一览
在将 Base 添加到钱包、后端配置或测试工具时使用这些值。它们与 OnFinality 为 Base 发布的网络配置相匹配。
| 设置 | Base 主网 | Base Sepolia 测试网 |
|---|---|---|
| 链 ID | 8453 | 84532 |
| 原生货币 | ETH(18 位小数) | ETH(18 位小数) |
| 区块浏览器 | https://basescan.org | https://sepolia.basescan.org |
| 公共 RPC (OnFinality) | https://base.api.onfinality.io/public | https://base-sepolia.api.onfinality.io/public |
| 传输 | HTTP | HTTP |
有关托管端点和网络详细信息,请参阅 Base RPC 网络页面 和 Base Sepolia RPC 网络页面。
使用 JSON-RPC 读取 NFT 数据
大多数 ERC-721 和 ERC-1155 读取通过 eth_call 和编码的函数选择器进行。您最常使用的三个调用是 ERC-721 的 ownerOf、balanceOf 和 tokenURI,以及 ERC-1155 的 balanceOf 和 uri。
以下是一个最小的 curl 示例,它在 ERC-721 合约上调用 ownerOf(uint256)。ownerOf 的选择器是 0x6352211e,后面跟着填充到 32 字节的代币 ID。
curl -s https://base.api.onfinality.io/public \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_call",
"params": [
{
"to": "0xYOUR_NFT_CONTRACT",
"data": "0x6352211e0000000000000000000000000000000000000000000000000000000000000001"
},
"latest"
]
}'
响应是 ABI 编码的。将其解码为地址。如果代币不存在,调用会回滚,您会得到一个错误对象而不是值,因此请处理这两种情况。
在 JavaScript 中,viem 和 ethers 会为您处理编码。此示例读取 ERC-721 代币的所有者和代币 URI:
import { createPublicClient, http, parseAbi } from "viem";
import { base } from "viem/chains";
const client = createPublicClient({
chain: base,
transport: http("https://base.api.onfinality.io/public"),
});
const abi = parseAbi([
"function ownerOf(uint256) view returns (address)",
"function tokenURI(uint256) view returns (string)",
]);
const owner = await client.readContract({
address: "0xYOUR_NFT_CONTRACT",
abi,
functionName: "ownerOf",
args: [1n],
});
const uri = await client.readContract({
address: "0xYOUR_NFT_CONTRACT",
abi,
functionName: "tokenURI",
args: [1n],
});
console.log(owner, uri);
tokenURI 通常返回 ipfs:// 或 https:// 链接。解析它是链下获取,而不是 RPC 调用,因此请在那里规划缓存和超时。
使用日志枚举转账和所有权
要查找转账,请查询 eth_getLogs,按 ERC-721 或 ERC-1155 Transfer 事件主题和合约地址过滤。这是大多数索引器构建所有权表的方式。
const logs = await client.getLogs({
address: "0xYOUR_NFT_CONTRACT",
fromBlock: 0n,
toBlock: "latest",
});
两个约束很重要。首先,提供商限制了每个 eth_getLogs 请求的区块范围,因此您必须分块遍历历史。其次,深层历史查询需要归档状态;非归档节点可能会拒绝或失败。如果您正在回填大型集合,请按区块范围分块并持久化进度,这样失败的请求不会强制完全重启。
对于实时转账流,订阅 logs 的 WebSocket 可以避免轮询。并非所有端点都暴露 WebSocket 传输,因此在围绕它设计之前,请确认传输支持。如果您需要持久订阅,专用节点基础设施 通常比共享公共端点更合适。
当原始 RPC 端点不够用时
RPC 为您提供正确性,但不提供便利性。它无法在不扫描日志和重建状态的情况下回答“列出此钱包拥有的每个 NFT”。这是索引器或 NFT 数据 API 的工作。
团队在 Base RPC 之上添加索引器层的常见原因:
- 钱包投资组合视图必须为许多集合快速返回。
- 市场或画廊页面需要集合级元数据和计数。
- 分析聚合跨数千个合约的转账。
- 元数据缓存,这样您就不会在每次页面加载时解析
tokenURI。
您可以针对 Base RPC 端点运行自己的索引器,或使用托管的 NFT 数据服务。无论哪种方式,底层的 RPC 端点仍然需要处理您的索引负载,这通常比单个用户请求重得多。
NFT 读取流量的生产就绪检查清单
NFT 工作负载是读取密集型和突发性的。一次空投或一个新集合可能会在几分钟内使请求量成倍增加。在发布之前,请检查这些项目。
| 检查 | 验证内容 |
|---|---|
| 端点容量 | 您的提供商可以吸收来自钱包、画廊和索引器的突发读取 |
| 归档访问 | 如果您回填,支持历史日志和状态查询 |
| 传输 | 读取使用 HTTP,如果订阅实时日志则使用 WebSocket |
| 故障转移 | 配置了第二个端点或提供商以进行自动重试 |
| 缓存 | 元数据和 tokenURI 响应以合理的 TTL 缓存 |
| 批处理 | 在可能的情况下,使用 JSON-RPC 批处理请求批量处理多个读取 |
| 监控 | 您跟踪错误率、延迟和速率限制响应 |
如果您预计 NFT 读取量稳定或较高,请比较共享公共端点与托管计划和专用节点。OnFinality 提供 Base RPC API 访问和专用节点;请参阅 RPC 定价 和完整的 支持的 RPC 网络 列表来规划容量。
常见故障模式及如何调试
大多数 Base NFT API 问题属于几个可重复的类别。
| 症状 | 可能原因 | 修复 |
|---|---|---|
eth_call 回滚 | 代币不存在或合约错误 | 确认代币 ID 和合约地址 |
| 日志结果为空 | 主题或区块范围错误 | 检查 Transfer 主题哈希并扩大范围 |
| 旧区块上的请求被拒绝 | 非归档节点 | 使用支持归档的端点 |
| 负载下的速率限制错误 | 共享端点限制 | 批处理请求、缓存或迁移到托管计划 |
| 元数据加载失败 | IPFS 网关或 HTTP 超时 | 添加备用网关并缓存结果 |
| 所有权不一致 | 在不同区块读取 | 固定区块号以获得一致的快照 |
一个快速的诊断方法是在已知良好的区块上重放失败的调用并进行比较。如果在那里成功,问题通常是状态深度或范围,而不是您的 ABI 编码。
在 Base Sepolia 上测试
在主网之前,针对 Base Sepolia 构建和测试。链 ID 是 84532,OnFinality 公共端点是 https://base-sepolia.api.onfinality.io/public。部署一个测试 ERC-721,铸造几个代币,并针对它运行您的 ownerOf、balanceOf 和 eth_getLogs 路径。在这里测试您的分页逻辑,因为错误代价低廉,而不是在主网上,糟糕的回填可能代价高昂。
关键要点
- Base NFT API 是 Base JSON-RPC 调用和可选的用于聚合数据的索引器的组合。
- 使用
eth_call进行ownerOf、balanceOf和tokenURI;使用eth_getLogs进行转账。 - RPC 本身无法枚举钱包的持有量;这需要索引器或您自己的索引作业。
- 历史日志查询需要归档状态和区块范围分页。
- 在依赖 WebSocket 订阅之前,确认传输支持。
- 通过缓存、批处理和故障转移来规划突发读取流量。
- 在主网之前,在 Base Sepolia(链 ID 84532)上测试。
常见问题
是否有单一的 Base NFT API?
没有。Base 暴露标准的以太坊 JSON-RPC,因此 NFT 读取使用与任何 EVM 链相同的方法。聚合的 NFT 数据来自索引器或托管数据服务。
我可以仅使用 RPC 列出钱包拥有的所有 NFT 吗?
不能直接列出。您必须扫描 Transfer 日志并自己重建所有权。索引器是投资组合式查询的实用选择。
我需要归档节点来获取 NFT 历史吗?
如果您查询旧区块或回填转账历史,是的。支持归档的端点提供修剪节点无法提供的历史状态。
Base RPC 支持 WebSocket 订阅吗?
传输支持因端点而异。在围绕实时日志订阅进行设计之前,请检查您的提供商的文档。
在回填期间如何避免速率限制?
批处理请求、分块遍历日志、缓存元数据,并考虑使用托管或专用端点来应对持续的索引负载。
在哪里可以找到 Base 端点和链详细信息?
请参阅 Base RPC 网络页面 和 Base Sepolia RPC 网络页面 以获取链设置和端点。