Q17 · 前端与链交互
前端和合约交互为何要先 approve?
⚡ 速记答案(30 秒)
- ERC20 标准:合约不能随意划走用户 Token,只能划走用户事先授权(approve)给它的额度
- 流程:用户先
approve(DEX合约, amount)→ 再调用swap/stake等函数;合约内部用transferFrom扣用户额度 - 好处:提升安全性、可精细控制每个合约的最大可用额度
📖 详细讲解
为什么需要 Approve
ERC20 设计原则:用户资产由用户控制
合约无法直接 transfer 用户的代币,必须:
1. 用户先调用 approve(spender, amount) 授权额度
2. 合约再调用 transferFrom(user, to, amount) 转账
完整交互流程
1. 检查 allowance (已授权额度)
2. 如果额度不足,调用 approve
3. 等待 approve 交易确认
4. 调用目标函数 (swap/stake/...)
5. 合约内部执行 transferFrom授权安全
• 无限授权风险:approve(MAX_UINT256) 方便但有风险
• 建议:只授权需要的额度,或使用 Permit2
💻 代码示例
Approve 流程示例
import { ethers } from 'ethers';
const ERC20_ABI = [
'function approve(address spender, uint256 amount) returns (bool)',
'function allowance(address owner, address spender) view returns (uint256)',
];
async function approveAndSwap(
tokenAddress: string,
spenderAddress: string,
amount: bigint,
signer: ethers.Signer
) {
const token = new ethers.Contract(tokenAddress, ERC20_ABI, signer);
const userAddress = await signer.getAddress();
// 1. 检查当前授权额度
const currentAllowance = await token.allowance(userAddress, spenderAddress);
// 2. 如果额度不足,先授权
if (currentAllowance < amount) {
console.log('授权额度不足,正在授权...');
const approveTx = await token.approve(spenderAddress, amount);
await approveTx.wait();
console.log('授权成功');
}
// 3. 执行 swap(示例)
// const swapTx = await dex.swap(...);
}面试技巧:回答时先给出核心结论,再展开细节。如果有实际项目经验,一定要结合具体案例说明。