【问题标题】:web3.eth.contracts.method await function never returnsweb3.eth.contracts.method 等待函数永远不会返回
【发布时间】:2021-11-10 03:34:58
【问题描述】:

我正在开发一个与以太坊中的智能合约进行交互的项目。一切工作正常,事务工作正常等等......但我意识到,当我尝试在一个专门的等待函数之后运行一些代码时,该代码从未运行过,我真的不知道为什么。我调用的其他合约方法运行良好,代码执行正常。

代码:

onSubmit = async (event) => {
  event.preventDefault()
  console.log("Submitting the form...")
  var day = new Date(Date.now()).getDate()
  var month = new Date(Date.now()).getMonth() + 1
  var year = new Date(Date.now()).getFullYear()
  var today = new Date(year, month -1, 1)
  var todayTime = today.getTime()

  const ipfsadded = await ipfs.add({path:this.state.fileName, content:this.state.buffer})
  var ipfsHash = ipfsadded.cid.toString()
  this.setState({ipfsHash: ipfsHash})
  console.log('hash:', ipfsHash, " / name =", this.state.fileName )

  console.log("inserindo na blockchain..")

  const accounts = await web3.eth.getAccounts()
  //ERROR HERE!!
  //THIS FUNCTION IS EXECUTED, THE TRANSACTION IS CONFIRMED IN METAMASK BUT AFTER THAT NOTHING HAPPENS
  var result = await contract.methods.add(ipfsHash, this.state.fileName, this.state.fileType, todayTime).send({from:accounts[0], gas:300000});
  console.log("resultado =", result) //IS NEVER EXECUTED EVEN WITH TRANSACTION OK
  console.log("File submitted on blockchain!") //IS NEVER EXECUTED


}

【问题讨论】:

  • 你能不能试着用 try/catch 块来换行,这样你就可以很容易地打印出一个错误?我怀疑这个错误是因为它需要超过 750 秒才能被挖掘并抛出一个错误。您可以在web3js.readthedocs.io/en/v1.5.2/… 阅读有关 750 秒的信息。
  • 如果是这种情况,那么最好遵循这个答案ethereum.stackexchange.com/a/58936/6814,订阅receiptconfirmation 事件,而不是等待承诺得到解决。

标签: javascript async-await ethereum web3


【解决方案1】:

这很可能是因为交易没有在 750 秒内被挖掘,.send 抛出错误,但没有被捕获。您可以通过用 try/catch 块包装它并检查错误来证明这一点。

  try {
    var result = await contract.methods.add(ipfsHash, this.state.fileName, this.state.fileType, todayTime).send({from:accounts[0], gas:300000});
  } catch(err) {
    console.error(err);
  }

更好的方法是订阅receipttransactionHashconfirmation 事件,这些事件由send 公开。

  contract.methods.add(ipfsHash, this.state.fileName, this.state.fileType, todayTime)
    .send({from:accounts[0], gas:300000})
    .on('transactionHash', resolve)
    .on('error', reject);

在你的情况下

onSubmit = async (event) => {
  event.preventDefault()
  console.log("Submitting the form...")
  var day = new Date(Date.now()).getDate()
  var month = new Date(Date.now()).getMonth() + 1
  var year = new Date(Date.now()).getFullYear()
  var today = new Date(year, month -1, 1)
  var todayTime = today.getTime()

  const ipfsadded = await ipfs.add({path:this.state.fileName, content:this.state.buffer})
  var ipfsHash = ipfsadded.cid.toString()
  this.setState({ipfsHash: ipfsHash})
  console.log('hash:', ipfsHash, " / name =", this.state.fileName )

  console.log("inserindo na blockchain..")

  const accounts = await web3.eth.getAccounts()
  //ERROR HERE!!
  //THIS FUNCTION IS EXECUTED, THE TRANSACTION IS CONFIRMED IN METAMASK BUT AFTER THAT NOTHING HAPPENS
  const promise = new Promise()
  contract.methods.add(ipfsHash, this.state.fileName, this.state.fileType, todayTime)
  .send({from:accounts[0], gas:300000})
  .on('receipt', (receipt) => {
    console.log('this should be executed now')
    console.log("resultado =", receipt)
    console.log("File submitted on blockchain!")
  })
  .on('error', console.error)
}

https://ethereum.stackexchange.com/a/58936/6814https://ethereum.stackexchange.com/a/59114/6814 的任何一个答案都是正确的。

【讨论】:

  • 感谢您的回答!仅在一次显示 750 秒超时错误时包含 try/catch 块。其余时间,没有错误。包括这些事件,只执行了 transactionHash。为了清楚起见,它是被挖掘和确认的交易。这是我发送的交易示例:rinkeby.etherscan.io/tx/…
  • @GabrielMS 抱歉,我的回答中的代码示例不正确。你不应该在send()await,而是在.on('transactionHash', resolve) 中解决promise。
  • @GabrielMS 我已经添加了您的代码,该代码已更正。它现在应该可以工作了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-15
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多