向Solidity合约发送GoerliETH时遇gas不足及执行回退错误求助
问题描述
我通过Remix IDE部署了如下Solidity智能合约:
//SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.19; contract sendMonetSolidity{ uint public receiveBalance; function sendMoney()public payable{ receiveBalance += msg.value; } function getBalance()public view returns(uint){ return address(this).balance; } function withdrawMoney() public { payable(msg.sender).transfer(this.getBalance()); } function sendMoneyToSpecidicAddress(address payable _to) public{ _to.transfer(this.getBalance()); } }
注入钱包为MetaMask,同一浏览器账户下的收发操作均正常,但使用另一账户向合约发送Goerli ETH时,交易失败:起初提示"out of gas"错误,提高gas费用后,又返回"execution reverted"错误。合约地址为0x44433868cc8b2726ca98ebe9bb5339b7a7c8d945。
问题排查与解决
- 直接转账触发的revert问题:你的合约未实现
receive()或fallback()函数,当外部账户直接向合约地址转账(而非调用sendMoney函数)时,Solidity会拒绝这类交易并触发revert。如果另一账户是直接转ETH到合约地址,就会出现你遇到的错误。一开始的"out of gas"是MetaMask的gas估算偏差,提高gas后交易能执行,但因无接收函数导致revert。
修复方法:在合约中添加receive()函数,支持直接转账:
若需兼容其他未匹配的调用,可同时添加// 处理直接向合约转账的情况 receive() external payable { receiveBalance += msg.value; }fallback()函数:fallback() external payable { receiveBalance += msg.value; } receive() external payable { receiveBalance += msg.value; } - 操作纠正:确保另一账户通过调用
sendMoney函数完成转账,而非直接打款到合约地址。 - 严重安全漏洞修复:合约的
withdrawMoney和sendMoneyToSpecidicAddress函数无权限控制,任何地址都能转走合约内所有资金。建议添加仅部署者可调用的权限控制:address public owner; constructor() { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "仅部署者可调用"); _; } function withdrawMoney() public onlyOwner { payable(msg.sender).transfer(this.getBalance()); } function sendMoneyToSpecidicAddress(address payable _to) public onlyOwner { _to.transfer(this.getBalance()); }
内容的提问来源于stack exchange,提问作者bing0
相关产品推荐
相关产品推荐

