approve需要时间确认吗,在BSC中如何处理?

Does approve take time to be confirmed, and how to deal with this in BSC?

你好,我正在使用 web3 和 React 做 BSC DApp。我对这个领域很陌生。

我在调用 approve 后发现,transfer(或在我的情况下为 zapInToken)将不会成功,并抱怨没有足够的津贴。所以我添加 wait allowance 存在 10 秒,但似乎在 10 秒后很多次(50% 的机会)津贴仍然不存在。请检查以下代码以获取更多信息。

理论上,approve会产生一笔交易,具体时间视情况而定。如果是这样,approvewait for allowancetransfer是标准模式吗?

谢谢!

const bepContract = getContract(getAddress(from), erc20ABI, library, account)
const tx = await bepContract.approve(getAddress(contracts.zap), weiAmount)
if (!tx) {
    throw new Error('Failed to approve transaction')
}
await waitAllowance(bepContract, account, getAddress(contracts.zap), weiAmount, 10) // <-- and it will stuck here in most time, the code waits for the allowance is present
await getZapContract().zapInToken(getAddress(from), weiAmount, getAddress(to)).then(logInfo).catch(logError)

waitAllowance 如下所示

const waitAllowance = async (
  contract: Contract,
  account: string,
  to: string,
  allowanceNeeded: string,
  timesLeft: number
): Promise<void> => {
  if (timesLeft > 1) {
    const currentAllowance = await contract.allowance(account, to)
    // console.log(`I want ${allowanceNeeded}, and current is ${currentAllowance} `)
    const needed = new BigNumber(allowanceNeeded)
    const current = new BigNumber(currentAllowance.toString())
    if (current.isGreaterThanOrEqualTo(needed)) {
      return
    }
    await new Promise((res) => setTimeout(res, 1000))
    await waitAllowance(contract, account, to, allowanceNeeded, timesLeft - 1)
  }
  throw new Error('wait allowance failed for many times.')
}

我明白了,我需要 tx.wait,所以工作代码如下:

const bepContract = getContract(getAddress(from), erc20ABI, library, account)
const tx = await bepContract.approve(getAddress(contracts.zap), weiAmount)
if (!tx) {
    throw new Error('Failed to approve transaction')
}
const tx = await waitAllowance(bepContract, account, getAddress(contracts.zap), weiAmount, 10)
const txResult = await tx.wait()
if (txResult.status !== 1) {
    throw new Error('Failed approve')
}
const txZap = await getZapContract().zapInToken(getAddress(from), weiAmount, getAddress(to))
const txZapResult = await txZap.wait()
if (txZapResult.status !== 1) {
    throw new Error('Failed zap')
}

查看此 doc 更多详细信息

经过数小时的调试,我意识到这是由于我使用的节点所致。从 getblock 更改为 Moralis 并且有效