调用Ballot合约函数时交易执行回退,求助排查及gas优化
投票合约执行回退报错及Gas浪费问题
报错信息
"Warning! Error encountered during contract execution [execution reverted]"
场景说明
部署了一个投票(Ballot)合约,运行在以太坊Goerli测试网,无代币依赖,用户仅需支付Gas费。调用合约投票函数时触发交易执行回退错误,同时担心写入区块链的操作会造成不必要的Gas浪费。
相关信息
合约地址
Goerli测试网合约地址:0xa46dc78595315b94904182013888adb439c6009f
合约代码
/** * @title 投票合约 * @dev 实现投票流程及委托投票功能 */ contract Ballot is IHelper, Guard, Logging { Confirmed[6] private _确认票数; Abstention private _弃权票数; uint[6] private _候选人列表; uint private _总有效票数; mapping(address => bool) private _选民是否已投票; constructor() { _注册候选人(); emit LogStartElection("选举期开始,投票箱已启用!", getResult()); } /** @dev 注册候选人 **/ function _注册候选人() private { for (uint i = 0; i < _候选人列表.length; i++) { _候选人列表[i] = i; _确认票数[i].candidate = i; } } /** * @dev 查询当前调用者是否已投票 * @return '_选民是否已投票'对应的值 */ function getElectorHasAlreadyVoted() public view returns (bool) { return _选民是否已投票[msg.sender]; } /** * @dev 获取选举结果 * @return 'ElectionResult'类型的选举结果 */ function getResult() public view returns (ElectionResult memory) { return ElectionResult({ candidates: _候选人列表, totalConfirmedVotes: _总有效票数, confirmedVotes: _确认票数, abstentionVotes: _弃权票数 }); } /** * @dev 选民确认投票 * @param candidateID 要投票的候选人ID */ function confirmVote( uint candidateID ) public onlyCandidateRegistered(candidateID, _候选人列表.length) onlyElectorWhoDidNotVote(_选民是否已投票[msg.sender]) { _确认票数[candidateID].totalVotes++; _确认票数[candidateID].elector.push(msg.sender); _确认票数[candidateID].candidate = candidateID; _选民是否已投票[msg.sender] = true; _总有效票数++; emit LogElectorVote("投票已确认并计入!", getResult()); } /** @dev 选民弃权 **/ function abstainVote() public onlyElectorWhoDidNotVote(_选民是否已投票[msg.sender]) { _弃权票数.totalVotes++; _弃权票数.elector.push(msg.sender); _选民是否已投票[msg.sender] = true; emit LogElectorVote("已登记弃权!", getResult()); } }
DApp Ethers代码
const PROVIDER = ethers.providers.InfuraProvider.getWebSocketProvider({ chainId: 5, name: 'goerli' }); const PRIVATE_WALLET = new ethers.Wallet(process.env.REACT_APP_WALLET_PRIVATE_KEY || '', PROVIDER); const CONTRACT = new ethers.Contract( process.env.REACT_APP_SOLIDITY_CONTRACT_ADDRESS || '', BallotContract.abi, PRIVATE_WALLET ) const ELECTOR_SIGNER = CONTRACT.connect(ELECTOR_WALLET); const CONTRACT_ADDRESS = await infura.contract.resolvedAddress; const GAS_LIMIT = await ELECTOR_SIGNER.estimateGas.confirmVote(1); const TRANSACTION_HASH = await window.ethereum?.request({ method: 'eth_sendTransaction', params: [ { from: ELECTOR_SIGNER, to: CONTRACT_ADDRESS, gas: estimateGas._hex, value: 0, }, ], }) const TRANSACTION_RECEIPT = await PROVIDER.waitForTransaction(TRANSACTION_HASH); const RESPONSE = await ELECTOR_SIGNER.confirmVote(1);
交易报错截图

内容的提问来源于stack exchange,提问作者THIAGO DE BONIS
相关产品推荐
相关产品推荐

