如何检测将在 web3js 中失败的事务

Posted

技术标签:

【中文标题】如何检测将在 web3js 中失败的事务【英文标题】:How to detect a transaction that will fail in web3js 【发布时间】:2018-07-29 10:14:11 【问题描述】:

我最近刚刚完成了与 Remix IDE 的一项相当复杂的合同。我现在将 web3 附加到前端,但是当我调用应该失败的函数时,它们仍然会通过 Metamask。

在 Remix 中测试我的合约时,我经常单击并调用某些需要语句的函数,我知道这些语句将无法确认合约状态被正确记录。 Remix 没有将事务发送到 metamask 而是输出错误消息,我也想自己处理事务错误。

我如何检查我的合约调用以查看它是否会失败。我必须使用预测气体的方法并以这种方式检测它吗?如果是,如何?我当前的代码如下:

contract.callFunction(function(error, result) 
    if (!error) alert(result);
    else alert(error);

上面的代码将拒绝元掩码确认视为错误,但应该失败的交易会通过设置异常高的气体限制的元掩码。函数 callFunction 在合约中,不带参数,但对区块链有影响,因此需要交易。函数的第一行是“require(state == 1);”我目前将合同设置为状态 2,所以我预计交易会失败,我只是想检测到它失败。

【问题讨论】:

【参考方案1】:

我很抱歉发布一个问题然后很快找到答案,但我希望它对未来的人有所帮助。

为了确定交易是否会失败,我们必须调用estimateGas() 并附加一个回调函数。我假设我们必须检查返回的气体估计值以预测它是否会失败,但这个过程相当容易。这是我最终成功运行函数并捕获两个最常见错误情况的完整代码。

    contract.nextState.estimateGas(function(error, result) 
        if (!error) 
            contract.nextState(function(error, result) 
                if (!error) 
                    alert("This is my value: " + result);
                 else 
                    if (error.message.indexOf("User denied") != -1) 
                        alert("You rejected the transaction on Metamask!");
                     else 
                        alert(error);
                    
                
            );
         else 
            alert("This function cannot be run at this time.");
        
    );

[编辑] 事后我会回来帮助有类似问题的人清理信息。下面讨论的所有信息都引用了以下link。

创建合约对象后,您可以通过其名称访问任何变量或函数。您还可以通过数组表示法访问这些成员,这在编写代码时变量或函数的名称未知时很有用。

contract.foobar == contract["foobar"]

一旦你有了一个函数对象 (contract.foobar),你就可以使用 call、send 或estimateGas。在首先给函数提供它需要的参数之后(像任何其他函数一样调用它),然后在返回的对象上使用调用、发送或估计气体,同时提供 options回调函数强>。

这个回调函数有 2 个参数。第一个是没有错误时未定义的错误,第二个是调用、发送或估计气体的结果。 Call 和 Send 都会返回函数的结果,而 estimateGas 总是返回一个数字,显示估计需要多少 gas。

【讨论】:

如果您能多描述一下代码的作用,那就太好了。 error !== undefined是否表示交易会出错? @NicSzer 我希望您找到解决问题的方法,如果您不希望我对答案的编辑有所帮助。我喜欢(很可能)谷歌把你带到我的问题,我个人讨厌在谷歌上找到一个不能彻底回答我的问题的问题,所以我为缺乏信息道歉。您是正确的,错误未定义意味着没有错误。如果 error 不是未定义的,那么它就是包含错误信息的对象。 感谢您编辑您的答案并添加更多详细信息! @MatthewLudwig 我使用的是 web3 2.x(因为 Metamask 默认会注入这个)。它似乎没有 .methods 。知道如何预测呼叫是否会失败吗? 感谢@MatthewLudwig。感谢您的回答。刚刚添加了我的解决方案。投票不理想,但对我有用:)

以上是关于如何检测将在 web3js 中失败的事务的主要内容,如果未能解决你的问题,请参考以下文章

Web3j如何获得交易状态

Web3JS 发送事务

如何在 web3js 中进行多笔交易

重复事务挂起 - web3js,本地 geth

如何将 BSC wesocket 提供程序与 Web3J 或 Web3js 连接

web3js 调用因缺少合约地址而失败