从Solidity合约向钱包转账ETH触发EVM交易回退是什么原因?
报错原因分析
- 交易
to字段错误:调用合约方法时,交易对象的to参数必须填写合约部署地址,你当前填写的是收款地址dummyAcct,导致交易没有发送到合约,直接触发回滚。 - 权限校验不匹配:合约的
onlyOwner修饰器要求调用者必须等于合约的admin地址,你需要确认发起交易的mainAcct地址是否和部署合约时传入的_admin参数一致,不一致的话require检查失败会触发回滚。 - 可选场景:gas限制不足:如果收款地址是需要消耗gas处理接收ETH逻辑的合约地址,
transfer方法自带的2300gas上限会导致转账失败回滚。
修复方案
- 修正交易参数:将
transaction对象中的to字段替换为你的合约实际部署地址。 - 校验调用权限:使用部署时传入的
admin地址发起交易,或者根据业务需求调整onlyOwner修饰器的校验逻辑。 - 优化ETH转账逻辑(可选):将
transfer改为call方式发送ETH,避免gas限制问题,修改后的合约代码如下:
pragma solidity ^0.8.0; contract Contract { address public owner; address public admin; constructor(address _admin) { owner = msg.sender; admin = _admin; } modifier onlyOwner(address sender) { require( sender == admin, "Only the admin of the contract can perform this operation." );_; } function sendTo (address toAddress) public payable onlyOwner(msg.sender) { (bool success, ) = payable(toAddress).call{value: msg.value}(""); require(success, "ETH transfer failed"); } }
- 修正后的前端调用代码如下:
var contract = new web3.eth.Contract(abi, 你的合约部署地址, null); const transaction = { from: mainAcct, to: 你的合约部署地址, // 替换为实际合约地址 value: '10000000000000000', gas: 30000 }; try { await contract.methods.sendTo(dummyAcct).send( transaction , function(err, hash){ if(!err){ console.log("Transaction hash:", hash); }else{ console.log(err); } }); } catch (e) { console.log(e); }
内容的提问来源于stack exchange,提问作者AKRA
相关产品推荐
相关产品推荐

