You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Web3.js 1.9.0无法获取失败交易Revert原因求助

问题:Web3.js 1.9.0无法获取失败交易的Revert原因

我使用Web3.js 1.9.0调用投票合约的addVote函数时,交易失败但无法获取具体的Revert原因。已设置web3.eth.handleRevert = true,也尝试过getTransactionReceipt,均无效。

合约核心代码

function addVote(string memory voteName, string memory candidate, address addr) public returns(string memory){
    require(candidateVote[voteName].length > 0, "Vote does not exist.");
    // require(voteCount[voteName][candidate] == 0, "You have already voted for this candidate.");
    require(!voters[voteName][addr], "Address has already voted!");

    voteCount[voteName][candidate]++;
    voters[voteName][addr] = true;
    
    return "Vote successful casted!";
}

Web3.js调用代码

export function addVote(web3:any, contract:any, abi: any,contractAddress:any,voteName:string, candidate:any, fromAccount:any){
  
    return new Promise((resolve, reject) => {
            
            contract.methods.addVote(voteName, candidate, fromAccount).send({from:fromAccount,gas:3000000})
            
            .on('confirmation', function(confirmationNumber, receipt){
            
                    if(receipt.status){
                            resolve(receipt)
                        }else{

                           reject(receipt)
                            
                        }

            }).on('error', function(error, receipt) {
                    
                    reject(error)

            })
    })
}

错误输出

E:\Docker-project\dvote\node_modules\web3-utils\lib\index.js:49
        error = new Error(error);
                ^
Error: Transaction has been reverted by the EVM:
{
  "transactionHash": "0xd3dc4740bb91d16b94b7214914347531e494c46582dcb69c12bc488133e49d06",
  "transactionIndex": 0,
  "blockNumber": 20,
  "blockHash": "0x3a50b40559ac7e6ae7dad11fe73ec36e8c9be536fa8e5e6b1353cbf7ca3a96fd",
  "from": "0x5d256d7b2238958831d55d9d6e0d08e51e3dd1d8",
  "to": "0x25fde715c938ac5a27cd06aa3887981d0457f330",
  "cumulativeGasUsed": 29872,
  "gasUsed": 29872,
  "contractAddress": null,
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "status": false,
  "effectiveGasPrice": 2570615365,
  "type": "0x2",
  "events": {}
}
    at Object._fireError (E:\Docker-project\dvote\node_modules\web3-utils\lib\index.js:49:17)
    at E:\Docker-project\dvote\node_modules\web3-core-method\lib\index.js:396:39 

解决方案

核心原因

send()方法在交易上链后无法直接返回Revert原因,需要通过预执行模拟或节点debug接口获取;同时需确保handleRevert设置时机正确。

方案1:预执行call()捕获Revert原因

在发送交易前用call()模拟执行,直接捕获require的错误信息:

export function addVote(web3:any, contract:any, abi: any,contractAddress:any,voteName:string, candidate:any, fromAccount:any){
    return new Promise(async (resolve, reject) => {
        try {
            // 预执行call,提前捕获revert原因
            await contract.methods.addVote(voteName, candidate, fromAccount).call({from: fromAccount});
            
            // 预执行通过再发送交易
            contract.methods.addVote(voteName, candidate, fromAccount)
                .send({from: fromAccount, gas: 3000000})
                .on('confirmation', (confirmationNumber, receipt) => {
                    receipt.status ? resolve(receipt) : reject("Transaction failed without revert reason");
                })
                .on('error', (error) => {
                    reject(error);
                });
        } catch (callError) {
            // 这里直接拿到具体的revert提示,比如"Vote does not exist."
            reject(callError);
        }
    });
}

方案2:优化send()的错误监听

Web3.js 1.9.0的error事件包含revert原因,需正确解析:

.on('error', function(error, receipt) {
    if (error.message.includes('reverted:')) {
        // 提取具体的revert原因
        const revertReason = error.message.split('reverted: ')[1];
        reject(new Error(revertReason));
    } else {
        reject(error);
    }
})

方案3:确保handleRevert设置正确

必须在创建合约实例前设置handleRevert,否则不生效:

const web3 = new Web3('http://localhost:8545');
web3.eth.handleRevert = true; // 关键:先设置再创建合约
const contract = new web3.eth.Contract(abi, contractAddress);

方案4:通过节点debug接口获取已上链交易的Revert原因

如果交易已上链且失败,可调用节点的debug_traceTransaction接口获取详情(需节点开启debug功能):

web3.currentProvider.send({
    jsonrpc: "2.0",
    method: "debug_traceTransaction",
    params: ["0xd3dc4740bb91d16b94b7214914347531e494c46582dcb69c12bc488133e49d06", {tracer: "callTracer"}],
    id: Date.now()
}, (err, result) => {
    if (err) console.error(err);
    else console.log("Revert reason:", result.result.error);
});

内容的提问来源于stack exchange,提问作者xmrrabbitx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 14:22:02