Infura 调用 eth_getBlockByNumber 十次,每个 eth_call
Infura calls eth_getBlockByNumber ten times for each eth_call
我正在尝试创建一个简单的 nextjs API 路由 (https://nextjs.org/docs/api-routes/introduction),它连接到以太坊区块链以从智能合约执行视图功能(不需要 gas)。
我有一个系统,您可以在其中购买铸造 NFT (ERC721) 的权利,此功能会检查用户是否已为任何尚未铸造的 collectionId 付款。
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 个请求限制。
infura top methods
我不知道为什么每次调用都要调用 eth_getBlockByNumber 10 次,这是必要的还是有解决办法?
Web3.js 不应为呼叫执行此操作,但应为发送执行此操作。
这是因为当你 await
任何 web3.js 合同方法时,它有内部的,有点出乎意料的,暗示“在确认 tx 之前等待 X 个块”机制并且以某种方式触发,尽管您的示例代码似乎没有任何合同写入。 It is documented here.
因为您使用的是 HTTPS 连接而不是 WebSocket 连接,Web3.js 需要轮询新块号以进行确认。但是,如果您切换到 WebSocket infura 提供程序,这些调用应该会消失,因为 Web3.js 可以简单地订阅 WebSocket 新块检测事件。
我正在尝试创建一个简单的 nextjs API 路由 (https://nextjs.org/docs/api-routes/introduction),它连接到以太坊区块链以从智能合约执行视图功能(不需要 gas)。
我有一个系统,您可以在其中购买铸造 NFT (ERC721) 的权利,此功能会检查用户是否已为任何尚未铸造的 collectionId 付款。
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 个请求限制。
infura top methods
我不知道为什么每次调用都要调用 eth_getBlockByNumber 10 次,这是必要的还是有解决办法?
Web3.js 不应为呼叫执行此操作,但应为发送执行此操作。
这是因为当你 await
任何 web3.js 合同方法时,它有内部的,有点出乎意料的,暗示“在确认 tx 之前等待 X 个块”机制并且以某种方式触发,尽管您的示例代码似乎没有任何合同写入。 It is documented here.
因为您使用的是 HTTPS 连接而不是 WebSocket 连接,Web3.js 需要轮询新块号以进行确认。但是,如果您切换到 WebSocket infura 提供程序,这些调用应该会消失,因为 Web3.js 可以简单地订阅 WebSocket 新块检测事件。