ethers.js icon indicating copy to clipboard operation
ethers.js copied to clipboard

blockTag usage

Open PedroReyes opened this issue 2 years ago • 0 comments

Ethers Version

5.6.9

Search Terms

blockTag

Describe the Problem

Hello,

👁 Context

I am trying to get the return value of a method at a specific block following the next documentation:

  • https://docs.ethers.io/v5/api/providers/types/#providers-BlockTag
  • https://docs.ethers.io/v5/api/providers/provider/#Provider--transaction-methods

💻 System setup

  • OS: Windows 10
  • node: v18.2.0
  • npm 8.9.0
  • ethers: 5.6.9

🔁 Reproduction

// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// When running the script with `npx hardhat run <script>` you'll find the Hardhat
// Runtime Environment's members available in the global scope.
const { ethers } = require("hardhat");
const hre = require("hardhat");

async function main() {
  console.log(`💻 Network: ${hre.network.name}`);

  // 👁‍🗨 Address we retrieve the data from
  let userAddress = "0xd0a111d4349aad1f8ce82e61d5c8c2beac6b2e92";
  console.log(`👀  Retrieving data from ${userAddress}...`);

  // 👉 Contracts
  const nbuContract = await hre.ethers.getContractAt(
    "NBU",
    "0x5f20559235479F5B6abb40dFC6f55185b74E7b55"
  );

  const gnbuContract = await hre.ethers.getContractAt(
    "GNBU",
    "0xA4d872235dde5694AF92a1d0df20d723E8e9E5fC"
  );

  // 🔨 Get accounts
  let [hacker, _, tester] = await hre.ethers.getSigners();
  hacker = tester;

  // 👁‍🗨 Get data from contract (alt1)
  if (false) {
    let gnbuBalanceAlt1 = await hre.ethers.provider.call(
      await gnbuContract.populateTransaction.balanceOf(userAddress),
      (blockTag = 20260300)
    );
    console.log(`📗 GNBU balance (alt1):\n ${gnbuBalanceAlt1} \n`);
  }

  // 👁‍🗨 Get data from contract (alt2)
  if (false) {
    let gnbuBalanceAlt2 = await gnbuContract.balanceOf(userAddress, {
      // blockTag: 3412629,
      blockTag: 20260300,
    });
    console.log(`📗 GNBU balance (alt2):\n ${gnbuBalanceAlt2} \n`);
  }

  // 👁‍🗨 Get data from contract (alt3)
  if (false) {
    let gnbuBalanceAlt3 = await ethers.provider.getStorageAt(
      gnbuContract.address,
      1,
      (blockTag = 3412629)
    );
    console.log(`📗 GNBU balance (alt3):\n ${gnbuBalanceAlt3} \n`);
    gnbuBalanceAlt3 = ethers.utils.parseBytes32String(gnbuBalanceAlt3);
    console.log(`📗 GNBU balance (alt3):\n ${gnbuBalanceAlt3} \n`);
  }
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

❌ Problem

For the next cases I am getting an error in BSC using a NodeReal archive node (https://meganode.nodereal.io/app/dashboard):

  • blockTag: 3412629
  • blockTag: 20260300
  • blockTag: "earliest"
  • blockTag: -1000

The error response I am getting:

Error: missing revert data in call exception; Transaction reverted without a reason string [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (data="0x", transaction={"from":"0xd299d4C11A1FA966a2E97B89e03DA42029c61152","to":"0xA4d872235dde5694AF92a1d0df20d723E8e9E5fC","data":"0x313ce567","accessList":null}, error={"name":"ProviderError","code":-32000,"_isProviderError":true}, code=CALL_EXCEPTION, version=providers/5.6.8)
    at Logger.makeError (C:\blockchain\ethernaut\node_modules\@ethersproject\logger\src.ts\index.ts:261:28)
    at Logger.throwError (C:\blockchain\ethernaut\node_modules\@ethersproject\logger\src.ts\index.ts:273:20)
    at checkError (C:\blockchain\ethernaut\node_modules\@ethersproject\providers\src.ts\json-rpc-provider.ts:66:16)
    at EthersProviderWrapper.<anonymous> (C:\blockchain\ethernaut\node_modules\@ethersproject\providers\src.ts\json-rpc-provider.ts:603:20)
    at step (C:\blockchain\ethernaut\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:48:23)
    at Object.throw (C:\blockchain\ethernaut\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:29:53)
    at rejected (C:\blockchain\ethernaut\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:21:65)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) { 
  reason: 'missing revert data in call exception; Transaction reverted without a reason string',
  code: 'CALL_EXCEPTION',
  data: '0x',
  transaction: {
    from: '0xd299d4C11A1FA966a2E97B89e03DA42029c61152',
    to: '0xA4d872235dde5694AF92a1d0df20d723E8e9E5fC',
    data: '0x313ce567',
    accessList: null
  },
  error: ProviderError: header not found
      at HttpProvider.request (C:\blockchain\ethernaut\node_modules\hardhat\src\internal\core\providers\http.ts:78:19)
      at LocalAccountsProvider.request (C:\blockchain\ethernaut\node_modules\hardhat\src\internal\core\providers\accounts.ts:188:34)
      at processTicksAndRejections (node:internal/process/task_queues:96:5) 
      at EthersProviderWrapper.send (C:\blockchain\ethernaut\node_modules\@nomiclabs\hardhat-ethers\src\internal\ethers-provider-wrapper.ts:13:20) 

Thanks in advanced for your help.

Best regards, Pedro Reyes.

Code Snippet

https://bscscan.com/address/0xa4d872235dde5694af92a1d0df20d723e8e9e5fc

// 👁‍🗨 Address we retrieve the data from
let userAddress = "0xd0a111d4349aad1f8ce82e61d5c8c2beac6b2e92";

// 👉 Contracts
const gnbuContract = await hre.ethers.getContractAt(
    "GNBU",
    "0xA4d872235dde5694AF92a1d0df20d723E8e9E5fC"
  );

// 👁‍🗨 Get data from contract (alternative 1)
let gnbuBalance = await gnbuContract.balanceOf(userAddress, {
    // blockTag: 3412629,   // ❌- not working
    blockTag: 20260300,    // ❌ - not working
    // blockTag: "earliest", // ❌  - not working
    // blockTag: "latest",    // ✅ - working
  })

// 👁‍🗨 Get data from contract (alternative 2)
let gnbuBalance = await hre.ethers.provider.call(
    await gnbuContract.populateTransaction.balanceOf(userAddress),
    (blockTag = 20260300)
  );

Contract ABI

https://bscscan.com/address/0xa4d872235dde5694af92a1d0df20d723e8e9e5fc

Errors

Error: missing revert data in call exception; Transaction reverted without a reason string [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (data="0x", transaction={"from":"0xd299d4C11A1FA966a2E97B89e03DA42029c61152","to":"0xA4d872235dde5694AF92a1d0df20d723E8e9E5fC","data":"0x313ce567","accessList":null}, error={"name":"ProviderError","code":-32000,"_isProviderError":true}, code=CALL_EXCEPTION, version=providers/5.6.8)
    at Logger.makeError (C:\blockchain\ethernaut\node_modules\@ethersproject\logger\src.ts\index.ts:261:28)
    at Logger.throwError (C:\blockchain\ethernaut\node_modules\@ethersproject\logger\src.ts\index.ts:273:20)
    at checkError (C:\blockchain\ethernaut\node_modules\@ethersproject\providers\src.ts\json-rpc-provider.ts:66:16)
    at EthersProviderWrapper.<anonymous> (C:\blockchain\ethernaut\node_modules\@ethersproject\providers\src.ts\json-rpc-provider.ts:603:20)
    at step (C:\blockchain\ethernaut\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:48:23)
    at Object.throw (C:\blockchain\ethernaut\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:29:53)
    at rejected (C:\blockchain\ethernaut\node_modules\@ethersproject\providers\lib\json-rpc-provider.js:21:65)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) { 
  reason: 'missing revert data in call exception; Transaction reverted without a reason string',
  code: 'CALL_EXCEPTION',
  data: '0x',
  transaction: {
    from: '0xd299d4C11A1FA966a2E97B89e03DA42029c61152',
    to: '0xA4d872235dde5694AF92a1d0df20d723E8e9E5fC',
    data: '0x313ce567',
    accessList: null
  },
  error: ProviderError: header not found
      at HttpProvider.request (C:\blockchain\ethernaut\node_modules\hardhat\src\internal\core\providers\http.ts:78:19)
      at LocalAccountsProvider.request (C:\blockchain\ethernaut\node_modules\hardhat\src\internal\core\providers\accounts.ts:188:34)
      at processTicksAndRejections (node:internal/process/task_queues:96:5) 
      at EthersProviderWrapper.send (C:\blockchain\ethernaut\node_modules\@nomiclabs\hardhat-ethers\src\internal\ethers-provider-wrapper.ts:13:20)

Environment

Ethereum (mainnet/ropsten/rinkeby/goerli), node.js (v12 or newer), Hardhat

Environment (Other)

BSC mainnet

PedroReyes avatar Aug 08 '22 16:08 PedroReyes

I just tried to reproduce using https://meganode.nodereal.io, seems to work with plain ethers.js. Are you still facing this issue? How are you running the hardhat script and how is the network specified in the hardhat config?

zemse avatar Aug 14 '22 12:08 zemse

Hello @zemse ,

Thanks for helping. I am using the next code:

const gnbuContract = await hre.ethers.getContractAt(
    "GNBU",
    "0xA4d872235dde5694AF92a1d0df20d723E8e9E5fC"
);

let gnbuBalanceAlt2 = await gnbuContract.balanceOf(userAddress, {
      blockTag: 3412629,
});
console.log(`📗 GNBU balance (alt2):\n ${gnbuBalanceAlt2} \n`);

My hardhat.config.js setup is the next one:

require("@nomiclabs/hardhat-waffle");
require("@nomiclabs/hardhat-etherscan");
const { task } = require("hardhat/config");
require("dotenv").config();

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  defaultNetwork: "bsc_mainnet",

  mocha: {
    timeout: 120000,
  },

  networks: {
    bsc_mainnet: {
      url:
        "https://bsc-mainnet.nodereal.io/v1/" +
        process.env.ARCHIVE_NODE_API_KEY,
      chainId: 56,
      gasPrice: 20000000000,
      accounts: [process.env.DEPLOYER_PRIVATE_KEY],
    }
  },

  solidity: {
    compilers: [
      {
        version: "0.8.10",
        settings: {
          optimizer: {
            enabled: true,
            runs: 1000,
          },
        },
      },
    ],
  },
};

For executing I am not defining the network so I am taking the default one: npx hardhat run scripts/archiveBalanceOf.js . I want to get the balanceOf at block 3412629 in the BSC, that is, here https://bscscan.com/block/3412629.

Thanks in advance for helping me out.

Best regards, Pedro Reyes.

PedroReyes avatar Aug 14 '22 14:08 PedroReyes