Ethers.js v5调用USDC合约approve预估Gas失败排查
我使用Ethers.js v5调用USDC智能合约的ERC20 approve方法预估Gas,这套实现对其他ERC20合约在主网和Sepolia测试网均能正常运行,但针对USDC合约时调用失败。
原实现代码
const erc20Contract = new ethers.Contract(contractAddress, ERC20_ABI, this.provider); return erc20Contract.estimateGas.approve(address, amount);
参数说明:
contractAddress:合约地址this.provider:Infura提供的节点address:授权目标地址amount:按正确小数位数计算的BigNumber类型数值
错误信息
Error: cannot estimate gas; transaction may fail or may require manual gas limit (reason="execution reverted: ERC20: approve from the zero address", method="estimateGas", transaction={"to":"0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238","data":"0x095ea7b3000000000000000000000000000000000000000000000000000000000000dead0000000000000000000000000000000000000000000000000de0b6b3a7640000","accessList":null}, error={"reason":"processing response error","code":"SERVER_ERROR","body":"{"jsonrpc":"2.0","id":56,"error":{"code":3,"data":"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002445524332303a20617070726f76652066726f6d20746865207a65726f206164647265737300000000000000000000000000000000000000000000000000000000","message":"execution reverted: ERC20: approve from the zero address"}}","error":{"code":3,"data":"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002445524332303a20617070726f76652066726f6d20746865207a65726f206164647265737300000000000000000000000000000000000000000000000000000000"},"requestBody":"{"method":"eth_estimateGas","params":[{"to":"0x1c7d4b196cb0c7b01d743fbc6116a902379c7238","data":"0x095ea7b30000000000000000000000000000000000000000000000000000000000000dead0000000000000000000000000000000000000000000000000de0b6b3a7640000"}],"id":56,"jsonrpc":"2.0"}","requestMethod":"POST","url":"https://sepolia.infura.io/v3/d5ca672c9aa246ff9df442b72d89bc4a"}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.7.2)
尝试过的无效方法
针对错误提示"approve from the zero address",我尝试将目标地址硬编码为0x000000000000000000000000000000000000dead或0x000000000000000000000000000000000000dEaD,但问题仍未解决。
解决方案
USDC智能合约在调用Gas预估时需要指定交易发起地址(from),通过Ethers.js v5的overrides参数传入该地址即可解决问题。修改后的代码如下:
export const ERC20_ABI = [ 'function approve(address _spender, uint256 _value) public returns (bool success)', ]; class InfuraProvider { private readonly provider: InfuraProvider; constructor(private readonly network: Networkish) { this.provider = new InfuraProvider(this.network, API_KEY); } getFeeData = ({ contract: { address: contractAddress }, to, from, amount }: { contract: {address: string}; from: string; to: string; amount: BigNumber; }): Promise<BigNumber> => { const erc20Contract = new ethers.Contract(contractAddress, ERC20_ABI, this.provider); return erc20Contract.estimateGas.approve(to, amount, { from }); }; }
内容的提问来源于stack exchange,提问作者David Dal Busco

