← 博客
10 分钟阅读
|
2026年10月21日

如何发送 ERC-20 代币:钱包、代码和 API 方法

从钱包发送 ERC-20 代币,使用 ethers.js,或通过 REST API。涵盖 Gas、精度、合约地址风险和安全转账模式。

章节
C
Chaingateway Team
区块链专家

Three routes converge at a token contract

您可以通过三种方式发送 ERC-20 代币:从钱包应用发送、使用 ethers.js 等库在自己的代码中发送,或通过为您签名并广播交易的 REST API 发送。这三种方式在底层做的是同一件事。它们调用代币智能合约上的 transfer 函数,发送方以 ETH(而非代币)支付网络费用。本指南涵盖每种方法、会导致资金损失的错误,以及当您从单次手动转账扩展到数千次自动化转账时会发生什么变化。

TL;DR

  • ERC-20 转账是对代币合约的调用,而非像 ETH 那样的普通价值转移。接收地址和金额包含在调用数据中。
  • 发送钱包需要 ETH 作为 Gas 费,即使它持有大量代币。如果 ETH 为零,交易将失败。
  • 切勿将代币直接 transfer 到没有处理代币代码的合约中。请对合约交互使用 approve 和 transferFrom。
  • 在代码中,处理代币精度和不返回标准布尔值的代币。使用安全库封装调用。
  • 如果您构建的应用代表用户发送代币,REST API 可免去节点、Nonce 和 Gas 的工作。我们将在下文介绍。

目录

What actually happens when you send an ERC-20 token

发送 ETH 会在两个账户之间转移原生价值。发送 ERC-20 代币则会更改存储在代币合约内部的账本余额。您的钱包创建一笔以代币合约为目标的交易,该合约随后更新发送方和接收方的余额。

ERC-20 标准定义了每个合规代币暴露的方法:totalSupply、balanceOf、transfer、transferFrom、approve 和 allowance。这种共享接口是一个钱包或一段代码能够处理成千上万种不同代币的原因。原始规范是 EIP-20,发布于 2015 年 11 月。

这种设计带来了以下几个后果:

  • 交易的 to 字段是代币合约,而非您要支付的对象。真实接收者编码在调用数据中。
  • 调用数据以函数选择器 0xa9059cbb(transfer 签名)开头,随后是接收者地址和金额,详见 ethereum.org 的 ERC-20 文档。
  • ERC-20 是一种代币标准,并不等同于以太坊。ETH 是网络的原生货币。USDT 等代币是运行在其上的合约。若想了解 Gas 和 ETH 的全貌,请参阅我们的 以太坊概览。

其他 EVM 链上也存在相同格式。我们关于 ERC20 代币标准 的文章深入讲解了其工作原理,ERC20 地址指南 则解释了地址格式和余额查询。

发送前:简短核对清单

大多数转账丢失源于准备不足,而非技术故障。请先核对以下事项。

  1. 您持有该代币且数量正确。 使用 balanceOf 或在钱包中确认余额。
  2. 您持有 ETH 用于支付 Gas。 手续费以网络原生货币支付,而非从您发送的代币中扣除。Polygon 或 BNB Chain 同理,使用该链的原生币。只有代币而无 ETH 的钱包无法发送任何内容。
  3. 您拥有确切的接收地址。 请复制粘贴而非手动输入。MetaMask 帮助中心 警告地址投毒攻击,攻击者会在您的历史记录中植入相似地址。
  4. 您知晓目标网络。 相同的地址格式适用于多条 EVM 链。在错误网络发送的代币不会到达接收者预期的位置。
  5. 接收方能够接收。 向交易所充值地址发送错误网络的代币,或发送给无法处理代币的合约,可能导致永久丢失。
  6. 先用小额测试。 对于新接收者或新集成,先发送小额并确认到账,再发送全额。

方法 1:从钱包发送

对于一次性转账,钱包是最简单的途径。Etherscan 发送 ETH 或代币指南 描述了大多数钱包遵循的相同流程:

  1. 打开钱包并选择发送选项。
  2. 选择要发送的代币。若钱包未列出,请粘贴代币合约地址添加。
  3. 粘贴接收地址。
  4. 输入金额。
  5. 核对网络手续费。钱包会为您估算。
  6. 确认,然后在区块浏览器上通过交易哈希追踪直到确认。

有两个细节容易让人出错。首先,添加自定义代币时粘贴的合约地址必须是真实的,因为假冒代币使用相同的名称和符号。请从项目官方网站核实。其次,显示的手续费以 ETH 计价,因此钱包的 ETH 余额除您打算发送的 ETH 外,还必须覆盖该手续费。

方法 2:使用代码发送 (ethers.js)

需要自动化转账的开发者可以直接调用合约。ethereum.org 关于使用 ethers.js 发送代币的教程展示了基本模式。一份单独的 ethers.js 演练解释了与 ETH 的关键区别:该交易不发送价值,而是使用目标地址和金额调用代币的 transfer 函数。

步骤如下:

  1. 创建一个连接到以太坊节点的提供者(您自己的或托管端点)。
  2. 从私钥或您控制的钱包创建一个签名者。
  3. 使用代币地址和包含 transfer、balanceOf 和 decimals 的最小 ABI 实例化代币合约。
  4. 使用代币的精度将人类可读金额转换为基本单位。
  5. 调用 transfer(recipient, amount) 并等待收据。

该 ethers.js 教程指出,该库可以在无需手动设置 Gas 的情况下发送 EIP-1559 交易,自动选取 Gas 限制和默认优先费。当您使用签名者时,它还可以管理 nonce。

正确处理精度

代币以整数形式存储金额。精度为 18 的代币将 1.0 个代币表示为 1000000000000000000 个基本单位。decimals 字段是标准的一部分,但不同代币设置的值不同,且 EIP-20 文本 将其视为可选元数据。请始终从合约读取 decimals,而不要假设为 18。硬编码错误的值会导致发送金额相差数个数量级。

不要盲目信任返回值

标准规定 transfer 返回布尔值。但实际部署的代币并非都遵循此行为。有些不返回任何内容,有些则以意想不到的方式失败。OpenZeppelin IERC20 接口 是标准的参考实现,而 OpenZeppelin 的 SafeERC20 库旨在包装调用,以防异常代币破坏您的逻辑。如果您的智能合约移动代币,请使用它。如果您的后端发送代币,请检查交易收据状态和触发的 Transfer 事件,而不要假设成功。

Gas 限制

根据 MetaMask 的指南,普通 ETH 转账使用 21,000 的 Gas 限制。代币转账是合约调用,因此需要更多 Gas。请在每次发送前使用库的估算调用来估算 Gas,而不是硬编码数字,因为成本取决于代币的合约代码和涉及余额的状态。

方法 3:通过 REST API 发送

上述代码路径适用于脚本。但在产品中,它会变成一系列琐事:运营或租用节点访问权限、管理密钥、跟踪 nonce 以防并发发送冲突、估算 Gas、重试卡住的交易、解码日志以确认付款是否到账,并针对每条链重复所有这些工作。

统一 API 将这一层从您的团队中剥离。使用 Chaingateway,您可以通过简单的 REST 调用创建钱包、发送代币并读取解码后的交易数据。您的技术栈中不需要 web3.js 或 ethers.js,也不需要运行节点。我们的 以太坊 API 页面 展示了 ERC-20 发送如何通过 REST 实现。请求经过 HMAC 签名,Gas 会自动估算。

方法 3:通过 REST API 发送 — 概览图

同样的方法也适用于 Bitcoin、Tron、Solana、Polygon、BNB Chain 和 Arbitrum,因此增加第二条链并不意味着需要进行第二次集成。如果您稍后添加 Tron USDT,请阅读我们关于 TRC10 与 TRC20 的解释。关于 BNB Chain 地址,请参阅 BEP20 地址指南。

各方法的适用场景

场景钱包您自己的代码REST API
一次性个人转账最佳大材小用大材小用
单链上的偶尔脚本慢好好
应用内的付款或提现不切实际可行,需自行维护最佳选择
多条链和多种代币标准每条链手动操作每条链一个客户端统一接口
到账检测手动自行构建日志监听器Webhooks

ERC-20 转账常见的失败方式

将代币发送给合约

transfer 函数并非为向智能合约存款而设计。如果合约没有处理接收代币的逻辑,代币将停留在其余额中且无法取出。ethereum.org ERC-20 页面 描述了这一风险,包括发送到代币自身合约的情况,并报告截至 2024 年 6 月已有数百万美元因此损失。如果您编写合约,请添加一个函数以便找回误发的代币。如果您需要合约接收用户的代币,标准模式是:用户对合约调用 approve,然后合约调用 transferFrom。

零 ETH 无法支付 Gas

如果发送方没有原生货币,交易就会失败,无论钱包里有多少代币。产品团队往往发现得太晚:用户收到代币,尝试转移,却无法操作。解决办法是给钱包充入少量 ETH,或通过签名授权来绕过此限制。

网络错误或地址错误

区块链不支持撤销交易。在确认前请核实网络和地址,对于任何新操作,请先进行小额测试转账。

混淆代币与网络

例如 USDT 存在于多条链上。当有人声称持有 USDT 时,请询问是在哪个网络上。地址在各链上可能看起来完全相同,但资金仅存在于其中一条链上。

无 Gas 转账与元交易

一种日益普及的引导新用户的方式是:让用户签名一条消息,由他人提交交易并支付 Gas。EIP-3009,带授权的转账 定义了相关函数,允许持有者委托 Gas 支付,并通过 EIP-712 签名执行转账。仅支持实现了该标准的代币合约才支持此功能,因此在围绕它设计流程前请务必确认。对于初创公司,这可以消除用户首次转账前获取 ETH 的障碍。

我们的观点:将转账视为工作流,而非单次调用

我们的观点:将转账视为工作流,而非单次调用 — 概览图

我们在首次集成代币发送功能的团队中看到了同样的模式。transfer 调用本身只需一个下午。数周时间都花在了周边工作上:确认付款何时真正到账、处理失败或卡住的交易、估算费用以及保障密钥安全。

我们的观点是,发送和接收应当一体化。没有确认事件的付款流迫使你轮询,没有解码数据的充值流迫使你解析原始日志。这就是为什么我们将钱包创建、代币转账、Gas 估算、解码交易数据和 Webhook 通知集成在一个 API 后端,并采用 HMAC 签名。你只需与基础设施签署一份合约,而非每条链一份,且无需自行运行节点。

我们的实用建议:在测试环境中先进行小额转账,验证精度和收据,订阅事件以获取确认,随后再扩大交易量。

— Bitblade

使用 Chaingateway 自动化转账

如果你正在应用中构建付款、提款或充值功能,可以尝试我们的 区块链 API 并搭配 Chaingateway Webhooks 以便在付款到账时收到通知。我们 定价页面 上的套餐起步价为 Plus 版每月 49 欧元,Pro 版每月 99 欧元,Premium 版每月 249 欧元,Enterprise 版每月 499 欧元。按年计费分别为 Plus 版 490 欧元,Pro 版 990 欧元,Premium 版 2490 欧元,Enterprise 版 4990 欧元。付费访问前提供免费试用。

确认转账是否成功

提交交易不等于完成付款。发送后:

  1. 立即存储交易哈希。
  2. 检查收据状态。已挖出的交易仍可能失败。
  3. 在代币合约的 Transfer 事件中查找预期的发送方、接收方和金额。该事件属于 ERC-20 接口 的一部分。
  4. 根据你的风险策略等待足够的确认数,然后再发货或入账。
  5. 定期通过 balanceOf 进行对账,以捕获监听器可能遗漏的任何情况。

轮询适用于小型脚本。对于生产环境,订阅通知意味着你的系统对事件做出反应,而非反复请求。

常见问题

发送 ERC-20 代币是否需要 ETH?

是的。网络费用以 ETH 支付,而非你发送的代币。如果发送钱包没有 ETH,交易将失败。在其他 EVM 链上,你需要该链的原生代币。

USDT 是 ERC-20 代币吗?

USDT 在以太坊上存在 ERC-20 版本,是基于该标准最广泛使用的代币之一。它也存在于其他网络上,因此请务必确认你发送所在的网络以及接收方期望的网络。

ERC-20 与以太坊是一回事吗?

不是。以太坊是区块链,ETH 是其原生货币。ERC-20 是以太坊上代币合约遵循的标准接口,使钱包和应用能以统一方式处理不同代币。

如果将 ERC-20 代币发送到合约地址会怎样?

如果接收合约没有处理接收代币的逻辑,代币通常会卡住,能否恢复取决于该合约是否包含救援功能。发送前请检查接收方。对于合约交互,请使用 approve 后跟 transferFrom。

我可以在不运行节点的情况下发送 ERC-20 代币吗?

可以。您可以使用钱包进行手动发送,或者如果您正在构建应用程序,可以使用 REST API。使用 API 时,提供商负责处理节点访问、签名流程和 Gas 估算,而您的代码只需发起普通的 HTTP 请求。

来源

推荐

准备好自己动手构建了吗? 获取你的 API key — 7 天试用,无需信用卡 — 或查看 区块链 API 获取完整的 endpoint 参考。

C
Chaingateway Team
区块链专家

Chaingateway 团队致力于为全球开发者简化区块链集成。