ethers.js
ethers.js copied to clipboard
blockTag usage
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
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?
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.