铸造 API 是一种服务接口,它将单个 HTTP 请求转化为一个或多个链上代币创建,并代表你处理 nonce、批处理、gas 和状态跟踪。本指南解释了托管铸造背后的思维模型,演示了一个可运行的集成模式,展示了如何通过 RPC 端点独立验证铸造,并给出了一种可复现的吞吐量和失败率测量方法。它将提供商的文档化行为与建议以及你必须自行测量的数字区分开来。用它来设计一个可运营而不仅仅是演示的铸造流水线。
铸造 API 实际抽象了什么
铸造 API 是一种 REST 或 RPC 风格的接口,它通过单个请求创建新代币——NFT、半同质化代币、同质化代币或签名凭证。重要的区别在于原始合约调用和托管铸造服务之间。使用原始调用时,你需要自己签名交易、管理 nonce、估算 gas、等待打包并索引结果。托管铸造 API 封装了该生命周期:它排队请求、将它们批处理为 gas 高效的交易、跟踪状态,并且通常立即索引元数据。
这个术语含义过载。在 NFT 和代币化领域,它意味着创建链上资产。在身份系统中,代币铸造 API 在认证和策略检查后签发签名安全令牌。两者共享一个设计属性:API 是一个控制点,正确性取决于策略评估、签名以及对范围、受众和过期时间的严格处理。本文聚焦于链上代币化场景,但验证和可靠性模式适用于两者。
- 托管铸造:提供商处理 nonce、批处理、gas 和状态。
- 直接铸造:你的服务签名交易并提交到 RPC 端点。
- 混合模式:提供商铸造,你通过自己的 RPC 访问独立验证。
集成前的先决条件和假设
在编写代码之前,确认四件事。第一,合约标准以及提供商是否支持它——一些铸造 API 仅适用于预设或预先审计的合约,并且明确不支持自定义合约。第二,认证:大多数服务使用必须保持在服务器端的秘密 API 密钥。第三,合约上的铸造角色或权限模型。第四,你的幂等性策略,通常是客户端生成的参考 ID。
你还需要一种独立读取链状态的方式。即使铸造 API 报告成功,验证也应来自你控制或信任的 RPC 端点。OnFinality 的网络目录列出了支持的链,RPC 服务页面解释了端点选项;对于具体的提供商选择,RPC Assistant 是提问的正确场所。
- 合约已部署并为提供商的密钥启用了铸造。
- 秘密 API 密钥存储在服务器端秘密管理器中。
- 每个逻辑铸造唯一的参考 ID 方案。
- 用于独立验证的 RPC_URL。
思维模型:请求、队列、批处理、交易、状态
托管铸造请求会经历多个阶段。你的 HTTP 请求被验证并分配一个参考 ID。它进入队列,在那里应用速率限制。服务将多个请求批处理为一个或多个交易,用其托管钱包签名并提交。每个交易都有一个生命周期:待处理、已打包、已确认或失败。状态通过状态端点或 webhook 暴露。
由此产生两个后果。第一,成功的 HTTP 响应意味着请求被接受,而不是代币已存在。第二,只有在请求幂等时重试才是安全的——重新提交相同的参考 ID 应返回相同的逻辑结果,而不是铸造两次。围绕状态轮询或 webhook 设计你的客户端,而不是围绕初始响应代码。
可运行的集成:提交铸造并轮询状态
以下示例使用占位值和通用请求结构。根据提供商文档化的模式调整字段名称。模式——使用幂等键提交,然后轮询状态——才是关键。
curl -X POST "$MINTING_API_URL/v1/mints" \
-H "Authorization: Bearer $MINTING_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contract_address": "0xYOUR_CONTRACT",
"reference_id": "order-2024-0001",
"recipient": "0xRECIPIENT_WALLET",
"metadata": {
"name": "Example Token #1",
"image": "https://example.com/token-1.png"
}
}'
# Then poll status by reference ID
curl "$MINTING_API_URL/v1/mints/order-2024-0001" \
-H "Authorization: Bearer $MINTING_API_KEY"通过 RPC 独立验证铸造
永远不要将铸造 API 自身的状态视为唯一真相来源。直接读取合约。对于 ERC-721,使用代币 ID 调用 ownerOf;对于 ERC-1155,调用 balanceOf。下面的 JavaScript 示例使用通用 JSON-RPC 调用,适用于任何 EVM 兼容的 RPC_URL。
const RPC_URL = process.env.RPC_URL;
const CONTRACT = "0xYOUR_CONTRACT";
const TOKEN_ID = "1";
// ownerOf(uint256) selector = 0x6352211e
const data = "0x6352211e" + BigInt(TOKEN_ID).toString(16).padStart(64, "0");
const res = await fetch(RPC_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "eth_call",
params: [{ to: CONTRACT, data }, "latest"]
})
});
const json = await res.json();
if (json.error) throw new Error(json.error.message);
const owner = "0x" + json.result.slice(-40);
console.log("Owner:", owner);预期验证结果及需要记录的内容
成功的验证会从 ownerOf 返回接收者地址,或从 balanceOf 返回非零余额。记录交易哈希、区块号、代币 ID、参考 ID 以及首次确认读取的时间戳。如果铸造 API 报告成功但 RPC 读取返回零地址或回滚,则将铸造视为未确认,并在重试前进行调查。
为每次铸造保留验证日志。它将成为你的审计追踪和下面测量程序的输入。
- 来自状态端点的交易哈希和区块号。
- 来自你的 RPC_URL 的独立 ownerOf 或 balanceOf 结果。
- 从提交到首次确认链上读取的延迟。
- 任何状态转换及其时间戳。
可复现地测量吞吐量和失败率
不要依赖供应商的营销数字。在你自己的工作负载上测量。程序:固定批处理大小和元数据负载,以受控速率提交 N 个具有唯一参考 ID 的请求,轮询状态直到终止,并通过 RPC 验证每次铸造。在多个提交速率下重复,以找出延迟和失败率下降的位置。
将结果记录在如下表格中。在运行测试之前,将单元格留作占位符;不要用假设值填充它们。
- | 提交速率 (请求/分钟) | 已接受 | 已确认 | 失败 | p50 确认延迟 | p95 确认延迟 |
- | --- | --- | --- | --- | --- | --- |
- | 10 | 待定 | 待定 | 待定 | 待定 | 待定 |
- | 50 | 待定 | 待定 | 待定 | 待定 | 待定 |
- | 100 | 待定 | 待定 | 待定 | 待定 | 待定 |
- 每行至少运行三次并报告中位数。注明链、合约标准和一天中的时间。
排查常见的铸造 API 故障
大多数故障分为四类。请求错误发生在任何区块链事件之前:负载格式错误、不支持的合约类型或缺少权限。速率限制错误在响应头中返回重试指导;遵守它而不是猛击端点。交易错误发生在提交之后,必须通过状态端点检查,而不是初始响应。验证不匹配意味着 API 和链不一致——通常是时序问题,偶尔是真正的失败。
对于每个类别,记录参考 ID、HTTP 状态、响应体和最新状态。使用相同参考 ID 的幂等重试是安全的;在重试时使用新的参考 ID 是重复铸造发生的方式。
- 请求错误:修复负载或合约配置;不要盲目重试。
- 速率限制:使用响应中的 retry-after 值进行退避。
- 交易错误:轮询状态,然后在重新提交前在链上验证。
- 验证不匹配:等待确认深度,然后重新读取。
托管铸造的局限性和权衡
托管铸造以控制权换取便利。你继承提供商的合约支持、速率限制、批处理策略和费用模型。预设合约要求可能会阻止自定义逻辑。排队平滑峰值但增加延迟。批处理减少每个代币的 gas,但将不相关的铸造耦合到一个交易中,因此单个失败可能影响一批。
替代方案——通过你自己的 RPC 端点直接铸造——提供对合约、nonce 和 gas 策略的完全控制,代价是你自己构建和运营交易生命周期。许多团队两者都用:托管铸造用于规模,直接 RPC 读取用于验证和监控。如果你需要专用吞吐量或可预测的延迟,值得在托管端点之外评估专用节点。
后续步骤:加固流水线
一旦基本流程工作,在支持的地方添加 webhook 而不是轮询,在数据库层强制幂等性,并对验证不匹配发出警报。如果你在高容量下验证,请查看 RPC 使用定价,并在扩展到其他链之前检查网络目录。对于端点和提供商选择,请询问 RPC Assistant,而不是将假设硬编码到你的架构中。
- 添加带签名验证的 webhook 处理。
- 使用唯一约束存储参考 ID。
- 当铸造被 API 确认但在阈值内未被 RPC 确认时发出警报。
- 在任何提供商或链更改后重新运行测量表。