使用Viem在Avalanche上实现Trade Joe交易的ERC20授权问题求助
解决Viem + Avalanche上Trade Joe交易的ERC20授权问题
问题核心
你碰到的ERC20: transfer amount exceeds allowance错误,本质是Trade Joe路由器合约没有获得目标ERC20代币的花费权限。执行swapExactTokensForNATIVE这类涉及ERC20的交易前,必须先调用代币合约的approve方法完成授权。
具体解决方案
1. 准备ERC20合约ABI
ERC20标准的approve方法是通用的,直接用以下ABI片段即可:
const erc20Abi = [ { inputs: [ { name: '_spender', type: 'address' }, { name: '_value', type: 'uint256' } ], name: 'approve', outputs: [{ name: '', type: 'bool' }], stateMutability: 'nonpayable', type: 'function' } ];
2. 调用approve完成授权
用Viem的writeContract方法执行授权操作,参数说明:
address: 目标ERC20代币的合约地址args: 第一个参数是Trade Joe路由器地址,第二个是授权的代币数量(用parseUnits转换为代币最小单位)
示例代码:
import { parseUnits, writeContract } from 'viem'; import { avalanche } from 'viem/chains'; import { walletClient } from './your-wallet-setup'; // 替换为你的钱包客户端实例 // Trade Joe Avalanche主网路由器地址 const routerAddress = '0x60aE616a2155Ee3d9A68541Ba4544862310933d4'; // 示例:USDC代币地址 const tokenAddress = '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E'; // 授权100 USDC(转换为6位小数的最小单位) const approveAmount = parseUnits('100', 6); // 发起授权交易 const approveTxHash = await writeContract(walletClient, { address: tokenAddress, abi: erc20Abi, functionName: 'approve', args: [routerAddress, approveAmount], chain: avalanche, }); // 等待交易上链确认 await walletClient.waitForTransactionReceipt({ hash: approveTxHash });
3. 验证授权状态(可选)
可以调用ERC20的allowance方法确认授权是否生效:
import { readContract } from 'viem'; const allowance = await readContract(walletClient, { address: tokenAddress, abi: [ { inputs: [ { name: '_owner', type: 'address' }, { name: '_spender', type: 'address' } ], name: 'allowance', outputs: [{ name: '', type: 'uint256' }], stateMutability: 'view', type: 'function' } ], functionName: 'allowance', args: [yourWalletAddress, routerAddress], }); console.log('当前授权额度:', allowance.toString());
4. 执行交易
授权完成并确认后,再执行Trade Joe的swapExactTokensForNATIVE交易,就不会再出现授权不足的报错。
注意事项
- 授权数量可以设为覆盖本次交易的金额,也可以设为最大值(
BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'))避免重复授权,但要注意钱包安全。 - 不同代币小数位数不同,使用
parseUnits时要传入对应数值(比如WAVAX是18位小数)。
内容的提问来源于stack exchange,提问作者Juan
相关产品推荐
相关产品推荐

