Solidity ERC-20调用transferFrom报授权不足错误排查
问题原因
报错的核心是两个逻辑错误:
- 授权对象完全错误
ERC20的transferFrom执行时,会校验「调用transferFrom的地址」是否获得了代币持有人的对应额度授权。你在myMethod里是由Item合约调用token.transferFrom(),因此需要获得授权的spender(消费方)是Item合约地址,不是你的个人owner地址。
你原来写的await Token.approve(owner.address, 额度)相当于授权你自己花自己的钱,Item合约没有拿到任何授权,自然会抛出 allowance 不足的错误。 - 授权时机错误
你把approve操作写在了Item合约部署之前,此时根本拿不到Item合约的链上地址,就算想给Item授权也无法指定正确目标。
另外还有两个非报错类的隐患需要注意:
- 你写的基础Token合约中
mint函数是完全公开的,没有任何权限校验,任何地址都可以无限制铸币,上线会有严重安全风险,建议加onlyOwner修饰器限制仅合约管理员可调用。 - 你之前尝试给transferFrom传参数
1是错误的,对于18位小数的ERC20代币,1是最小单位,仅对应10^-18枚Token,用1 ether或者parseUnits("1",18)才是1枚完整Token的正确数值,这部分你后面写的是对的。
修复方案
调整测试代码的授权对象和执行顺序即可:
const TokenFactory = await ethers.getContractFactory("Token"); Token = await Token.deploy(); await Token.mint(owner.address, ethers.utils.parseUnits("1", 18)); const ItemFactory = await ethers.getContractFactory("Item"); Item = await ItemFactory.deploy(Token.address); // 先部署Item拿到地址,再给Item合约授权1枚Token的消费额度 await Token.approve(Item.address, ethers.utils.parseUnits("1", 18)); await Item.myMethod(); // 可正常执行
内容的提问来源于stack exchange,提问作者Joshua Ohana
相关产品推荐
相关产品推荐

