You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity ERC-20调用transferFrom报授权不足错误排查

问题原因

报错的核心是两个逻辑错误:

  1. 授权对象完全错误
    ERC20的transferFrom执行时,会校验「调用transferFrom的地址」是否获得了代币持有人的对应额度授权。你在myMethod里是由Item合约调用token.transferFrom(),因此需要获得授权的spender(消费方)是Item合约地址,不是你的个人owner地址。
    你原来写的await Token.approve(owner.address, 额度)相当于授权你自己花自己的钱,Item合约没有拿到任何授权,自然会抛出 allowance 不足的错误。
  2. 授权时机错误
    你把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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 23:54:18