使用IERC20.sol实现ERC20转账时授权不足问题排查
问题根源与解决方案
核心错误解释
你合约里的approveTKN函数完全搞错了授权主体:
当合约执行IERC20(TokenAddress).approve(address(this), _amount)时,调用者是合约自身,所以这是让代币合约记录「合约地址允许自己花合约地址的代币」,但你实际需要的是「用户允许合约花用户的代币」——这必须由用户主动调用代币合约的approve函数来完成,合约替用户做不了这件事。
修正后的合约代码
直接删掉无用的approveTKN函数,保留核心存提逻辑即可:
// SPDX-License-Identifier: Me pragma solidity ^0.8.9; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract Staking { mapping(address => uint) TKNbalance; address immutable TokenAddress = 0x1234567891234567891234567891234567891234; function depositTKN(uint256 _amount) external { IERC20(TokenAddress).transferFrom(msg.sender, address(this), _amount); TKNbalance[msg.sender] += _amount; } function withdrawTKN(uint256 _amount) external { require(_amount <= TKNbalance[msg.sender], "!!! Not enough funds deposited !!!"); IERC20(TokenAddress).transfer(msg.sender, _amount); TKNbalance[msg.sender] -= _amount; } function getTKNbalance() public view returns(uint) { return TKNbalance[msg.sender]; } }
正确测试流程
- 在Remix中加载目标ERC20代币的合约,调用
approve函数:- 参数
spender填写你的Staking合约地址 - 参数
value填写你要存入的代币数量
- 参数
- 再调用Staking合约的
depositTKN函数,传入相同数量,此时就能正常执行,不会再触发insufficient allowance错误。
内容的提问来源于stack exchange,提问作者C.I.And
相关产品推荐
相关产品推荐

