从 sendSignedTransaction 获取恢复原因

Get revert reason from sendSignedTransaction

我是 运行 Hyperledger Besu 私有链,正在从 Express 服务器调用 sendSignedTransaction。

        try {
            let tx = {
                from: fromAccount,
                to: this.contract.options.address,
                gas: 2000000,
                gasPrice: "0",
                value: 0,
                data: await this.contract.methods
                    .method().encodeABI()
            };
    
            console.log(tx);
            console.log("signing transaction");
            let signedTx = await this.web3.eth.accounts.signTransaction(tx, privateKey);
            console.log("transaction signed");
            let result = await this.web3.eth.sendSignedTransaction(signedTx.rawTransaction)
            console.log(result);
        }
        catch (e) {
            console.log(e);
        }

交易正在还原并被捕获,但我不确定如何获得还原原因。我试过设置 contract.handleRevert 以及来自搜索引擎的其他解决方案,但所有其他解决方案都假设您使用的是前端的 sendTransactioncallsend .根据 web3.js 文档,handleRevert 不适用于 sendSignedTransaction (https://web3js.readthedocs.io/en/v1.2.11/web3-eth.html#handlerevert) 并且错误 returns 作为一个长字符串:

Error: Transaction has been reverted by the EVM:
{
  "blockHash": "0xcb93d98a8d6f7c329dfd0cdb7d2fc421147ae077765e63263c794eb43aaa6263",
  "blockNumber": 560179,
  "contractAddress": null,
  "cumulativeGasUsed": 35348,
  "from": fromAddress,
  "gasUsed": 35348,
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "status": false,
  "to": contractAddress,
  "transactionHash": "0xfbd9b755aa71d823640c0f719d358ef9c7d81362a901ec2901fba5f188a4a310",
  "transactionIndex": 0,
  "revertReason": "0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000204552433737373a2073656e6420746f20746865207a65726f2061646472657373"
}
    at Object.TransactionError (/home/blockchain-dev/Documents/blockchain-app/server/node_modules/web3-core-helpers/src/errors.js:96:21)
    at Object.TransactionRevertedWithoutReasonError (/home/blockchain-dev/Documents/blockchain-app/server/node_modules/web3-core-helpers/src/errors.js:108:21)
    at /home/blockchain-dev/Documents/blockchain-app/server/node_modules/web3-core-method/src/index.js:482:48
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  receipt: {
    blockHash: '0xcb93d98a8d6f7c329dfd0cdb7d2fc421147ae077765e63263c794eb43aaa6263',
    blockNumber: 560179,
    contractAddress: null,
    cumulativeGasUsed: 35348,
    from: fromAccount,
    gasUsed: 35348,
    logs: [],
    logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
    status: false,
    to: contractAddress,
    transactionHash: '0xfbd9b755aa71d823640c0f719d358ef9c7d81362a901ec2901fba5f188a4a310',
    transactionIndex: 0,
    revertReason: '0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000204552433737373a2073656e6420746f20746865207a65726f2061646472657373'
  }
}

我还尝试了 运行 revertReason 十六进制代码上的十六进制到 ascii 转换器,但该值不可读。

我希望能够获得 sendSignedTransaction 调用的恢复原因。

您可以使用 web3.utils.hexToAscii() 解码 revertReason

const reason = web3.utils.hexToAscii('0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000204552433737373a2073656e6420746f20746865207a65726f2061646472657373');

Returns

Ãy   ERC777: send to the zero address

注意:前两个字符看起来像 UTF BOM,但 hexToUtf8() 无法解码字符串(字符串的其余部分实际上是 ASCII,而不是 UTF)。

这是一个解决方法,因为 revertReason 似乎还不能与 sendSignedTransaction 一起使用(至少从我使用 Alchemy 的节点服务的经验来看)。

try {
    let tx = {
        from: fromAccount,
        to: this.contract.options.address,
        gas: 2000000,
        gasPrice: "0",
        value: 0,
        data: await this.contract.methods
            .method().encodeABI()
    };
    
    console.log(tx);
    console.log("signing transaction");
    let signedTx = await this.web3.eth.accounts.signTransaction(tx, privateKey);
    console.log("transaction signed");
    let result = await this.web3.eth.sendSignedTransaction(signedTx.rawTransaction)
    console.log(result);
}
catch (e) {
    this.contract.methods.method()
        .call({'from': fromAccount}).then(() => {
        throw Error ('reverted tx')})
        .catch(revertReason => console.log({revertReason})
}