编译报错TypeError:调用ERC20 balanceOf函数时语法错误求助
Solidity编译错误:TypeError: Indexed expression has to be a type, mapping or array 解决方法
错误核心原因
你错误地将ERC20接口中的balanceOf当成mapping或数组,用[]索引访问,但实际上balanceOf是外部视图函数,必须使用函数调用语法()传参。同时你的合约还存在逻辑错误:
receive函数接收ETH时试图修改外部ERC20合约的余额,这是不可能的——合约无权直接修改外部合约状态,余额变更必须通过调用ERC20的transfer/transferFrom等函数触发。withdraw函数用msg.sender.transfer()转的是ETH,而非绑定的ERC20代币,逻辑完全不符。
修正后的完整代码
pragma solidity ^0.8.17; interface IERC20 { event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address to, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address from, address to, uint256 amount) external returns (bool); } contract VeloxWrapper { address payable owner; IERC20 public token; event Withdrawal(address indexed to, uint256 amount); event Deposit(address indexed from, uint256 amount); // 本地记录用户存入的代币余额 mapping(address => uint256) public userBalances; constructor(address tokenAddress) payable { token = IERC20(tokenAddress); owner = payable(msg.sender); } // 用户存入ERC20前需先调用ERC20的approve给合约授权 function deposit(uint256 amount) external { require(token.transferFrom(msg.sender, address(this), amount), "Transfer failed"); userBalances[msg.sender] += amount; emit Deposit(msg.sender, amount); } function totalBalance() external view returns (uint256) { return token.balanceOf(address(this)); } function withdraw(uint256 withdrawalAmount) public { require(userBalances[msg.sender] >= withdrawalAmount, "Insufficient balance"); userBalances[msg.sender] -= withdrawalAmount; require(token.transfer(msg.sender, withdrawalAmount), "Withdrawal failed"); emit Withdrawal(msg.sender, withdrawalAmount); } }
关键修正说明
balanceOf调用方式:将所有token.balanceOf[xxx]改为token.balanceOf(xxx),正确调用外部函数获取余额。- 本地余额映射:新增
userBalances记录用户存入的代币数量,因为无法直接修改外部ERC20合约的余额。 - 存币逻辑修正:新增
deposit函数,通过transferFrom将用户授权的代币转入合约,同步更新本地余额。 - 提币逻辑修正:提币时先检查本地余额,再调用
token.transfer将合约中的代币转给用户,而非转ETH。
内容的提问来源于stack exchange,提问作者Paparao Veeragandham
相关产品推荐
相关产品推荐

