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
会产生一笔交易,具体时间视情况而定。如果是这样,approve
、wait for allowance
和transfer
是标准模式吗?
谢谢!
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
并且有效
你好,我正在使用 web3 和 React 做 BSC DApp。我对这个领域很陌生。
我在调用 approve
后发现,transfer
(或在我的情况下为 zapInToken)将不会成功,并抱怨没有足够的津贴。所以我添加 wait allowance
存在 10 秒,但似乎在 10 秒后很多次(50% 的机会)津贴仍然不存在。请检查以下代码以获取更多信息。
理论上,approve
会产生一笔交易,具体时间视情况而定。如果是这样,approve
、wait for allowance
和transfer
是标准模式吗?
谢谢!
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
并且有效