Ethereum API:一次 REST 调用完成 ERC-20 转账
用一次 REST 调用发送 ETH 和 ERC-20 代币,取代 web3.js 和原始 JSON-RPC。钱包、转账与存款 Webhook,无需运维节点。
Chaingateway 的 Ethereum API 用一次经过认证的 REST 调用发送 ETH 和 ERC-20 代币,取代了手动集成所需的原始 JSON-RPC 步骤序列:针对合约 ABI 编码转账、估算 gas、管理 nonce 并签名交易——这些都要在错误处理之前完成。像 web3.js 和 ethers.js 这样的库把这些步骤包装了起来,但它们仍然运行在你的技术栈内部,背后依然需要一个节点端点。
Chaingateway 把这项工作搬到了服务器端。Webhook 会在存款到账时告诉你。无需安装任何 SDK,也无需运行节点。7 天免费试用无需 KYC 即可开始。
快速入门:三步完成第一笔转账
创建账户并复制你的 API 密钥。在这里注册——试用无需 KYC,这一步大约只需一分钟——然后把仪表盘中的密钥复制到每个请求的 Authorization: Bearer 请求头中。只保存在服务器端;出现在前端代码中的密钥就是公开的。
发出 hello-world 调用。GET /api/account 会返回你的账户详情,证明密钥有效。
先在测试网发送一笔测试转账,再上线。添加 X-Network: testnet,通过 POST /api/v2/ethereum/addresses/import 导入一个临时密钥,用公共水龙头为它充值,并发送下方展示的 ERC-20 转账。注册一个 Webhook,让存款事件回传给你,然后移除测试网请求头——同样的代码就能运行在主网上。
用 REST 代替 JSON-RPC 和 web3.js
JSON-RPC 是每个以太坊节点的原生协议,对某些工作(共识相关工具、自定义索引)而言,你确实需要这种层级的访问权限。我们关于通过 JSON-RPC 与节点交互的指南展示了这在 PHP、Python 和 JavaScript 中的样子。
数一数往返次数就能说明问题。通过原始 JSON-RPC 完成一笔代币转账,至少要涉及四个方法——eth_gasPrice、eth_estimateGas、eth_getTransactionCount 和 eth_sendRawTransaction——中间还夹着 ABI 编码和交易签名。
对支付而言,这种抽象是值得的。在 Chaingateway 的交易请求中,gas limit、gas price 和 nonce 都是可选字段——省略它们,API 在构建并广播交易时会自动填充;需要控制权时可以显式传入。你这一侧的交互,只是一次可以用任何语言、借助标准库编写的 HTTP 请求。
在 Ethereum 上构建所需的一切
Webhook(IPN)
面向传入交易的实时通知,在匹配的转账在链上结算后立即发送。在你的资料中设置一个私密密钥后,每条通知都会携带一个可由你服务器验证的 X-Signature 请求头。失败的投递会由 API 列出,一次调用即可重新发送。
简单的交易
发送 ETH 和 ERC-20 代币而无需接触手续费市场:gas limit、gas price 和 nonce 都是由 API 替你填充的可选请求字段。你只需提供收款方、代币和金额。
安全的地址处理
每个请求都做地址格式校验——格式错误的地址在构建任何内容之前就会以 422 失败——并采用非托管架构。已有密钥通过 POST /api/v2/ethereum/addresses/import 导入。
解码后的查询
交易通过 GET /api/v2/ethereum/transactions/{txid}/decoded 以可读 JSON 形式返回,其格式让你的应用无需额外解析即可读取和存储。
以太坊接口一览
| 路由 | 方法 | 作用 |
|---|---|---|
/api/account | GET | 账户详情;标准的密钥检查 |
/api/v2/ethereum/addresses/import | POST | 把一个已有私钥纳入 API 管理 |
/api/v2/ethereum/transactions/erc20 | POST | 发送一笔 ERC-20 代币转账 |
/api/v2/ethereum/webhooks/notifications | GET | 列出已收到的存款通知 |
四个路由覆盖了支付循环:验证密钥、加载钱包、发送代币、审计到账内容。确切的请求和响应结构见 API 参考文档,同样的布局也重复出现在 Polygon、Arbitrum,以及——用 bep20 替换 erc20——BNB Smart Chain 上。
核心示例:发送一笔 ERC-20 代币
第一步:导入你想要用来发送的地址。
curl -X POST https://app.chaingateway.io/api/v2/ethereum/addresses/import \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"address": "0xYourWallet...", "privatekey": "0x...", "password": "strong-wallet-password"}'curl -X POST https://app.chaingateway.io/api/v2/ethereum/transactions/erc20 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contractaddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"from": "0xYourWallet...",
"to": "0xRecipient...",
"amount": 25.50,
"password": "strong-wallet-password"
}'curl https://app.chaingateway.io/api/v2/ethereum/webhooks/notifications \
-H "Authorization: Bearer YOUR_API_KEY"这就是完整的转账流程,包含 gas 字段——创建账户,先在 Sepolia 上发送一次。
从 web3.js 迁移过来:同一笔转账,两种写法
如果你目前维护着一套 web3.js 集成,这里给出一个诚实的对比。通过该库完成一笔 ERC-20 转账大致是这样的:
// web3.js 面向你自己的 RPC 端点
const { Web3 } = require("web3");
const web3 = new Web3("https://your-rpc-endpoint");
const token = new web3.eth.Contract(ERC20_ABI, "0xdAC17F958D2ee523a2206206994597C13D831ec7");
const data = token.methods.transfer(recipient, amountInBaseUnits).encodeABI();
const tx = {
from: sender,
to: token.options.address,
data,
gas: await web3.eth.estimateGas({ from: sender, to: token.options.address, data }),
gasPrice: await web3.eth.getGasPrice(),
nonce: await web3.eth.getTransactionCount(sender),
};
const signed = await web3.eth.accounts.signTransaction(tx, PRIVATE_KEY);
await web3.eth.sendSignedTransaction(signed.rawTransaction);
除了代码片段本身之外,这段代码还要维护一个 ABI 文件,手动把人类可读的金额换算成最小单位(小数位算错,你可能发送出预期金额的百万分之一,或是它的一百万倍),并把一个原始私钥保存在应用内存中。REST 版本就是上面那一次 POST:金额是一个十进制字符串,小数位在服务端处理,密钥用密码加密静态存储。
这次迁移不需要一整个周末来重写。两种写法都是普通调用,可以并行运行:把新的支付流程改走 REST,保留自定义合约交互继续用 web3.js,在库不再值得维护其复杂度的地方逐步淘汰它。仅把 web3.js 用于转账和余额查询的团队,通常会彻底移除这个依赖。
谁支付 gas——以及它是如何运作的
每一笔以太坊交易都会消耗 gas,由发送地址以 ETH 支付,永远不是接收方。一个持有数千 USDT 但零 ETH 的钱包无法发送哪怕一个代币,因为 ERC-20 合约没有办法支付自身的执行成本。接收代币对收款方来说不花任何成本。
这个细节绊倒的 ERC-20 集成比其他任何问题都多。如果你通过 API 发起的转账来自一个资金库钱包,这个钱包除了代币之外还需要 ETH 余额,为它充值应该和证书续期一样,被列入运维检查清单。
Gas 要花多少钱
一笔普通的 ETH 转账正好消耗 21,000 gas——这是一个协议常量。一笔 ERC-20 转账要运行合约代码,成本是它的若干倍,具体数字因代币合约而异。单位价格随需求浮动:自 2021 年伦敦升级以来,手续费拆分为网络燃烧的基础费和支付给出块者的优先小费,两者都会在拥堵时上涨。实际后果是:同一笔 USDT 转账,在清淡的周日只需几美分,在热门铸造活动期间则明显更贵。
API 替你处理了什么
gas limit、gas price 以及 EIP-1559 的上限(maxFeePerGas、maxPriorityFeePerGas)都是可选请求字段——省略它们,API 会在构建你的交易时自动填充;或者在需要控制权时按请求固定它们。仍需要你自己负责的有两件事:在发送钱包上维持 ETH 余额,以及决定小额转账在哪里才有经济意义——当主网手续费接近转账金额时,同样的调用只需换一个路径就能用在 Polygon 或 Arbitrum 上。
接收是免费的
一个存款地址接收代币不需要任何 ETH。只有当资金离开时,gas 才会成为你的问题——包括当你把客户存款清扫进资金库钱包时,因为这本身就是每个存款地址发出的一笔转出交易。
以太坊上的出块时间与最终确定
自转向权益证明以来,以太坊的时间节奏是固定的,而不是统计性的。区块以 12 秒为一个 slot 到达,32 个 slot 组成一个 6.4 分钟的 epoch,一个区块在大约两个 epoch 后(大致 13 分钟)被最终确定——前提是三分之二的质押 ETH 已对其进行了证明(截至 2026 年年中的协议参数)。「最终确定」意味着网络无法在不销毁大部分质押 ETH 的情况下回滚该区块,这使它与比特币的概率性结算处于不同的类别。
对支付逻辑而言,时间线是这样的:一笔转账通常在几秒到一分钟内被打包进区块;此后每多经过一个 slot,确定性就增加一分;大约 13 分钟后,它在严格意义上是最终确定的。大多数应用会在远早于最终确定之前就为存款入账——打包加上少数几个区块就足以覆盖日常金额——而交易所通常会将大额提现保留到最终确定之后。存款 Webhook 会给你链上事件;入账门槛设在哪里,是你配置中的一条策略,而不是我们的。
以太坊上的任意代币,包括你自己的代币
USDT、USDC、DAI 等成熟代币开箱即用,金额以代币单位而非原始最小单位表示。要发行自己的 ERC-20 代币?传入合约地址,同一个接口就能发送它。没有上架流程,也不用等待。关于该标准本身的背景知识见我们的 ERC-20 代币标准指南。
为什么开发者选择 Ethereum
一套集成,四条 EVM 链
ERC-20 的路由模式在各 EVM 网络之间重复出现:/api/v2/polygon/transactions/erc20、/api/v2/arbitrum/transactions/erc20,以及 BNB Smart Chain 上的 /api/v2/bsc/transactions/bep20。为以太坊编写的代码,只需修改路径就能移植。当主网 gas 对小额转账来说变得太贵时,把它们迁移到 Polygon 只是一行改动。完整链列表见 blockchain API 总览。
为真实用例而生
上面的构建模块覆盖了我们见到的大多数生产模式:接受 USDT 或 USDC 的收银流程、大规模为存款入账并处理提现的交易所、通过空投或归属计划分发代币的项目,以及每月以稳定币计费的订阅业务。它们最终都归结为同样两次调用:发送一笔交易,接收一条 Webhook。
两个完整案例
面向网店的稳定币收银
客户选择「用 USDT 支付」,你的后端为该订单分配一个存款地址——每张发票一个地址,因此归属永远不依赖金额匹配。展示地址和金额,然后等待 Webhook。通知到达后,把订单切换为「已检测到付款」,让买家能迅速看到反应;等交易达到你策略要求的深度后再入账(上面的最终确定部分给出了具体数字)。有一个边界情形应该从第一天起就写进代码:从输入金额中扣除手续费的钱包会造成轻微少付,你对此的容忍度应该是一个配置值,而不是一张支持工单。
面向交易平台的提现
用户请求付款;你的任务是可靠地发送大量 ERC-20 转账。把每笔提现连同一个状态列一起放进数据库队列,然后通过 POST /api/v2/ethereum/transactions/erc20 逐条处理队列——每行数据一次请求,在处理下一条之前先记录响应。让审计员满意的规则是:一次超时的 HTTP 调用不等于一笔失败的交易。在重新发送任何内容之前,先对照你自己的记录和 GET /api/v2/ethereum/transactions(它列出了通过 API 创建的每一笔交易)进行核实,否则你可能会给同一个人付两次钱。同时监控资金库钱包的 ETH 余额,因为每一笔转出都会消耗 gas,要在余额耗尽之前提前告警,而不是等到队列卡住才发现。
错误处理
这里存在两层失败:来自 API 的 HTTP 错误,以及你的逻辑必须吸收的链上状况。
HTTP 一侧遵循惯例。401 意味着密钥缺失或无效——这是配置问题,不是重试的候选对象。其他 4xx 响应说明请求本身有误:地址格式错误、未知合约、字段缺失。记录响应体并修正调用方。带退避的重试只适用于 5xx 响应和网络超时。
链上这一侧才是支付代码真正体现价值的地方。一笔来自没有足够 ETH 支付 gas 的钱包的转账会失败,即便代币余额充足——主动监控 gas 余额,而不是在错误信息中才发现它已经耗尽。拥堵可能延迟打包;这是延迟,不是失败,你的界面应该区分两者。提现部分提到的规则值得再强调一次,因为它防范的是这个领域中代价最高的错误:绝不要仅仅因为 HTTP 响应没有到达就重新发送一笔转账。先确认它确实没有发生。
对于存款,养成对账的习惯。GET /api/v2/ethereum/webhooks/notifications 列出了已经投递的内容;每晚与你的账本做一次差异比对,能在修复成本仍然很低的时候,抓住任何被 bug 或故障吞掉的部分。
Testnet:同一个 API,只是代币没有价值
为任意请求添加 X-Network: testnet,它就会在测试网络上执行。路由、请求体和响应格式与主网完全相同,这意味着你的集成测试走的是真实代码路径,而不是模拟。用公共水龙头为测试钱包充值,运行转账,接收 Webhook——整个循环不花一分钱。
把这个请求头放在配置里:staging 设置它,生产环境不设置,两者之间没有代码差异。同样给 staging 一个单独的回调 URL,否则测试存款会落进你的生产 Webhook 处理程序。上线因此只是移除一个请求头,刻意做到毫无波澜。
四步完成集成
获取你的 API 密钥。注册免费,试用无需 KYC。
发出你的第一个请求。用 GET /api/account 验证密钥,然后导入或创建地址。
设置 Webhook。把通知指向你的接口并验证 HMAC 签名。
上线。移除 X-Network: testnet 请求头;同样的代码就能运行在主网上。
各条链支持哪些功能
以太坊设定了 ERC-20 的请求模式,BSC、Polygon 和 Arbitrum 都遵循这一模式,只是路径段有所变化。下表将它与该 API 覆盖的其他六条链并列展示。
| 链 | 地址 | 代币转账 | 存款 Webhook |
|---|---|---|---|
| Bitcoin | POST /api/v2/bitcoin/wallets/{wallet}/addresses | —(无代币标准) | GET /api/v2/bitcoin/webhooks/notifications |
| Ethereum | POST /api/v2/ethereum/addresses/import | ERC-20:POST /api/v2/ethereum/transactions/erc20 | GET /api/v2/ethereum/webhooks/notifications |
| TRON | POST /api/v2/tron/addresses/import | TRC-20 和 TRC-10:POST /api/v2/tron/transactions/trc20 和 .../trc10 | GET /api/v2/tron/webhooks/notifications |
| Solana | POST /api/v2/solana/addresses | SPL:POST /api/v2/solana/transactions/SPL | — |
| BNB Smart Chain | POST /api/v2/bsc/addresses/import | BEP-20:POST /api/v2/bsc/transactions/bep20 | GET /api/v2/bsc/webhooks/notifications |
| Polygon | POST /api/v2/polygon/addresses/import | ERC-20:POST /api/v2/polygon/transactions/erc20 | GET /api/v2/polygon/webhooks/notifications |
| Arbitrum | POST /api/v2/arbitrum/addresses/import | ERC-20:POST /api/v2/arbitrum/transactions/erc20 | GET /api/v2/arbitrum/webhooks/notifications |
正确理解此表需要两点说明。第一:TRON 是平台上集成最深的链。除上述路由外,参考文档还记录了质押(POST /api/v2/tron/freeze 和 /delegate)、链参数,以及一对自签名接口——/transactions/trc20/build 用于构建交易,/transactions/broadcast 用于提交本地签名后的交易。如果你的合规团队坚持要求私钥永远不离开你的服务器,这种 build-and-broadcast 模式就是你的方案。
第二:表格中的破折号表示当前参考文档尚未记录该单元格对应的 v2 路由,并不意味着该网络是二等公民。Bitcoin 没有代币标准,因此代币列为空——原生 BTC 通过自己的钱包模型运行:使用 POST /api/v2/bitcoin/wallets 创建密码加密的钱包,在其下派生存款地址,并通过 POST /api/v2/bitcoin/transactions 发送。Solana 的参考文档涵盖地址创建、SOL 和 SPL 转账,以及余额和区块查询,但尚无 Webhook。此处未列出的内容,请参阅 API 参考文档 获取当前状态。
常见问题
准备好接入 Ethereum 了吗?
在 app.chaingateway.io/register 创建账户,导入一个测试网钱包并发送一笔 Sepolia ERC-20 转账。完整接口参考见 文档,套餐和速率限制在单独的页面上。