首页 > 解决方案 > 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 个请求限制。

infura 顶级方法

我不知道为什么每次调用都会调用 eth_getBlockByNumber 10 次,这是必要的还是有解决方法?

标签: javascriptnode.jsnext.jsethereumsolidity

解决方案


Web3.js 不应该对调用执行此操作,但应该对发送执行此操作。

这是因为当您使用await任何 web3.js 合约方法时,它具有内部的、有点出乎意料的隐含“在确认 tx 之前等待 X 个块”机制并且以某种方式触发了这种机制,尽管您的示例代码似乎没有任何合约写入. 它记录在这里。

因为您使用的是 HTTPS 连接而不是 WebSocket 连接,所以 Web3.js 需要轮询新的块号以进行确认。但是如果您切换到 WebSocket infura 提供程序,这些调用应该会消失,因为 Web3.js 可以简单地订阅 WebSocket 新块检测事件。


推荐阅读