javascript - Infura 为每个 eth_call 调用 eth_getBlockByNumber 十次
问题描述
我正在尝试创建一个简单的 nextjs API 路由(https://nextjs.org/docs/api-routes/introduction),该路由连接到以太坊区块链以执行智能合约的视图功能(不需要气体)。
我有一个系统,您可以在其中购买铸造 NFT (ERC721) 的权利,此功能检查用户是否已为尚未铸造的任何 collectionIds 付费。
import Web3 from 'web3'
import { getPaidForCollectionsIds } from '../../database'
const mnemonic2 = 'main check ...'
var HDWalletProvider = require('truffle-hdwallet-provider')
export default async function (req, res) {
const paidFor = await getPaidForCollectionsIds(req.body.userId)
if (paidFor.length < 1) return res.json({ data: [] })
const provider = new HDWalletProvider(mnemonic2, 'https://rinkeby.infura.io/v3/INFURAAPIKEY', 0)
const web3 = new Web3(provider)
const TheContractAddress = '0xfbeF...'
const { abi } = require('../../abis/TheContract.json')
const KS = new web3.eth.Contract(abi, TheContractAddress, {
from: '0x5EE...', // default from address
gasPrice: '20000000000' // default gas price in wei, 20 gwei in this case
})
const unminted = []
await Promise.all(paidFor.data.map(async pf => KS.methods.readCollectionIdIsUsed(pf.collectionId).call().then(d => {
console.log(d, 'readCollectionIdIsUsed', pf.collectionId)
}).catch(e => {
unminted.push(sign)
})
)
}))
res.statusCode = 200
res.json({ data: unminted })
}
这是智能合约中 readCollectionIdIsUsed 方法的代码:
mapping (uint256 => bool) collectionIdIsUsed;
function readCollectionIdIsUsed(uint256 collectionId) external view returns (bool res) {
require(collectionIdIsUsed[collectionId], 'This signature has not been used');
res = collectionIdIsUsed[collectionId];
}
这一切都很好,除了一段时间后,我达到了 infura 的 100 000 个请求限制。
我不知道为什么每次调用都会调用 eth_getBlockByNumber 10 次,这是必要的还是有解决方法?
解决方案
Web3.js 不应该对调用执行此操作,但应该对发送执行此操作。
这是因为当您使用await
任何 web3.js 合约方法时,它具有内部的、有点出乎意料的隐含“在确认 tx 之前等待 X 个块”机制并且以某种方式触发了这种机制,尽管您的示例代码似乎没有任何合约写入. 它记录在这里。
因为您使用的是 HTTPS 连接而不是 WebSocket 连接,所以 Web3.js 需要轮询新的块号以进行确认。但是如果您切换到 WebSocket infura 提供程序,这些调用应该会消失,因为 Web3.js 可以简单地订阅 WebSocket 新块检测事件。
推荐阅读
- javascript - 菜单正在折叠但没有折叠?
- reactjs - 如何从子组件渲染父组件中的路由组件
- go - 如何从 Go Gin 上下文中找到请求方法?
- ios - AVAssetExportSession 导出视频 AVFoundationErrorDomain Code=-11841 错误
- jquery - 为什么 $.post 的数据为空
- python - 创建 ctypes 数组以使用 sendinput 发送扩展扫描码
- javascript - 如何使用 Node.js 将“\n”写为文件内的值
- html - Create a table of subject using html and ruby
- flutter - How to fetch user's current location using HERE maps in flutter?
- docker - ldd: exited with unknown exit code when use qemu in docker