NomicFoundation / hardhat

Hardhat is a development environment to compile, deploy, test, and debug your Ethereum software.
https://hardhat.org
Other
7.34k stars 1.42k forks source link

Add `--chain-id` param to `node` task #2305

Open dbeal-eth opened 2 years ago

dbeal-eth commented 2 years ago

It is currently not possible to specify the chain ID for a hardhat network invoked with npx hardhat node through any means other than the config file. This means it is impossible to specify the --chain-id argument in the command line, or execute a chain host pragmatically with hre.run('node', { chainId: 100 }).

Please add the chainId parameter to the node command so it is possible to override this value either pragmatically or case-by-case through the command line.

thexeromin commented 2 years ago

@kanej can I work in this issue?

fvictorio commented 2 years ago

@webdevabhijit sure! This is the entry point where that optional param should be added.

We don't have tests for the node task, and they would be tricky to do, so if the change is simple enough, I think we might be ok with not having tests for that change (not sure though).

thexeromin commented 2 years ago

@fvictorio I have added the feature. Should I make a pull request?

fvictorio commented 2 years ago

Sure.

github-actions[bot] commented 2 years ago

This issue was marked as stale because it didn't have any activity in the last 30 days. If you think it's still relevant, please leave a comment indicating so. Otherwise, it will be closed in 7 days.

dbeal-eth commented 2 years ago

this is still relevant.

brunoguerios commented 2 years ago

Hi everyone! Is there an ETA on this feature?

goums commented 2 years ago

would love to see this feature as well

fvictorio commented 1 year ago

I looked a little into this and it's not as straightforward as I thought, because the underlying network is created before the task is executed.

The easiest way to do this is to waint until either https://github.com/NomicFoundation/hardhat/issues/1697 or https://github.com/NomicFoundation/hardhat/issues/3074 are available.

In the meantime, a workaround is to do this in your config:

  networks: {
    hardhat: {
      chainId: Number(process.env.HARDHAT_CHAIN_ID ?? 31337)
    },
  },

and then start the node with HARDHAT_CHAIN_ID=123 npx hardhat node. Not ideal, but it should get the job done until we can add a proper param.

Samboy76 commented 1 year ago

Hi,

I´m facing a similar issue.

I am trying to fork 5 environments and config 5 mainnet networks within the same hardhat.config.js shown below:

require('dotenv').config();
require("@nomicfoundation/hardhat-toolbox");

const FORK_MAINNET = true;
const FORK_POLYGON = false;
const FORK_AVALANCHE = false;
const FORK_ARBITRUM = false;
const FORK_BSC = false;

const MAINNET = false;
const POLYGON = false;
const AVALANCHE = false;
const ARBITRUM = false;
const BSC = false;

const forkingData = FORK_MAINNET
    ? {
        url: process.env.INFURA_URL_API_KEY,
        enabled: true
      }
    : FORK_POLYGON
    ? {
        url: process.env.ALCHEMY_URL_API_KEY,
        enabled: true
      }
    : FORK_AVALANCHE
    ? {
        url: process.env.GETBLOCK_URL_API_KEY,
        enabled: true
      }
    : FORK_ARBITRUM
    ? {
        url: process.env.CHAINSTACK_URL_API_KEY,
        enabled: true
      }
    : FORK_BSC
    ? {
        url: process.env.QUICKNODE_URL,
        enabled: true
      }
    : undefined;

const urlData = MAINNET
    ? process.env.INFURA_URL_API_KEY
    : POLYGON
    ? process.env.ALCHEMY_URL_API_KEY
    : AVALANCHE
    ? process.env.GETBLOCK_URL_API_KEY
    : ARBITRUM
    ? process.env.CHAINSTACK_URL_API_KEY
    : BSC
    ? process.env.QUICKNODE_URL
    : "http://127.0.0.1:8545";
const chainData = MAINNET
    ? 1
    : POLYGON
    ? 137
    : AVALANCHE
    ? 43114
    : ARBITRUM
    ? 42161
    : BSC
    ? 56
    : FORK_MAINNET
    ? 1 // TODO change value
    : FORK_POLYGON
    ? 137 // TODO change value
    : FORK_AVALANCHE
    ? 43114 // TODO change value
    : FORK_ARBITRUM
    ? 42161 // TODO change value
    : FORK_BSC
    ? 56 // TODO change value
    : 31337; // default to Mainnet chainId

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  defaultNetwork: "localhost",
  networks: {
    localhost: {
      url: urlData,
      chainId: chainData,
      throwOnTransactionFailures: true,
      throwOnCallFailures: true,
      forking: forkingData,
      accounts: {
        mnemonic: process.env.MNEMONIC,
        path: "m/44'/60'/0'/0", // HD parent of all the derived keys. Default value: "m/44'/60'/0'/0"
        initialIndex: 0, // The initial index to derive. Default value: 0.
        count: 20, // The number of accounts to derive. Default value: 20.
        passphrase: "" // The passphrase for the wallet. Default value: empty string.
      }
    },
    mainnet: {
      url: urlData,
      chainId: chainData,
      accounts: {
        mnemonic: process.env.MNEMONIC,
        path: "m/44'/60'/0'/0", // HD parent of all the derived keys. Default value: "m/44'/60'/0'/0"
        initialIndex: 0, // The initial index to derive. Default value: 0.
        count: 20, // The number of accounts to derive. Default value: 20.
        passphrase: "" // The passphrase for the wallet. Default value: empty string.
      }
    }
  },
  solidity: {
    compilers: [
      {
        version: "0.8.10"
      }
    ],
    settings: {
      optimizer: {
        enabled: false
      }
    }
  },
  paths: {
    sources: "./contracts",
    tests: "./test",
    cache: "./cache",
    artifacts: "./artifacts"
  },
  mocha: {
    timeout: 100000000
  }
};

I have a monitoring bot setup that listens to each one of the above five forks and mainnets depending on the flag that I set in runtime.

My question is this:

For each one of the forks, I would like to test separate contract addresses (tokens and smart contracts) under my backend solidity smart contract but seem to run into problems such as this one: Error HH101: Hardhat was set to use chain id 1, but connected to a chain with id 31337. And when I seem to progress I run into this other error but this time in Solidity back-end "Error: Transaction reverted: function call to a non-contract account" which indicate perhaps I am running under different network or chainId in Hardhat localhost. This is the confusion that I have and would like to toggle between each of the fork networks/chainId for my bot through this toggle.

Upon deploy function call in deploy JS script, in the backend solidity constructor function for the flashloan smart contract, I print out the current chainId of the network I am using and it keeps returning the same chainId value each time 31337. See below print out code snippet:

console.log("block.chainid ", block.chainid);

I have deployed JS script that deploys my smart contract through usage of these code lines:

const Flashloan = await hre.ethers.getContractFactory("Flashloan");
const flashLoan = await Flashloan.deploy(<input arg>);
await flashLoan.deployed();

What am I missing here or what seems to be the problem.

FYI, I would like to have forks and mainnets for each of Ethereum, Polygon, Avalanche, Arbitrum and BSC networks. Not sure if it´s a question of correctly configuring the corresponding chainIds which I have attempted directly in hardhat.config.as as shown above.

This is where I need some help and guidance from your shared wisdom.

Thank you very much for your assistance on this topic.

Best

fvictorio commented 1 year ago

@Samboy76 I'm not sure I understand what you're asking. But what you might be missing is that, when you fork a network, Hardhat will use the configured chain id (which is 31337 by default), not the chain id of the forked network. If you have more questions, please open a discussion and try to make it as focused as possible.

ToJen commented 1 year ago

@fvictorio how can we override the chainId for a fork? I don't want to use 31337 as that's incorrect

fvictorio commented 1 year ago
module.exports = {
  networks: {
    hardhat: {
      chainId: 123
ToJen commented 1 year ago

I mean on the node itself, when I tried that, it produces an error similar to this (in my own words):

mismatched chain id, expected hardhat=123 but rpc node=31337

How do we configure hardhat node with a --chainId value especially when --fork <fork_url> has been passed. I don't want my local fork to use chain id 31337 during dev/texting.

brunoguerios commented 1 year ago

Hey all 👋 I'll share how I handled the problem of testing against multiple chains in parallel, as I believe this will help solve some of the issues people shared on this discussion. The idea is to have a separate config file for each chain and use that as a parameter when spinning up the node. Besides that, in order to have all nodes running on localhost, we'll a different port for each node. For example, in order to test against polygon:

  1. Create hardhat.config.polygon.ts file with:

    import '@nomiclabs/hardhat-ethers';
    export default {
    networks: {
    hardhat: {
      chainId: 137,
    },
    },
    };
  2. Spin up local polygon node with the following command:

npx hardhat --config hardhat.config.polygon.ts node --fork [REMOTE_RPC_URL_HERE] --port 8137

  1. Set the rpcUrl in the provider to have the same port you specified:

    import { JsonRpcProvider } from '@ethersproject/providers';
    const rpcUrl = 'http://127.0.0.1:8137';
    const chainId = 137;
    const provider = new JsonRpcProvider(rpcUrl, chainId);
  2. Follow the same previous 3 steps for all other networks you'd like to test against.

ToJen commented 1 year ago

Thanks @brunoguerios, I'm guessing you then export common configs out of the main hardhat.config.ts and how many of these hardhat.config.<chain>.ts are you willing to maintain given the number of EVM compatible chains?

brunoguerios commented 1 year ago

In my case I use these only for local testing on some chains and chainId is the only config I need, so I don't have to deal with that much complexity. But I'd probably do as you described in case I needed other common configs.

sify21 commented 1 year ago

Ideally, the node task should respect different network settings through the --network parameter, just like other built-in tasks did. Currently it's only possible to modify the default hardhat network setting for the node task.

valle-xyz commented 10 months ago

Hey guys,

bummer this is still not implemented. We wanted to programmatically change hardhat forks in our tests. If we wanted to run forks in other processes/terminals, we would have used Anvil straight away. But the code we test is JS, so Hardhat makes sense.

I would propose to add: hardhat_setChainId, like anvil does. The config should be avoided. Other option would be to add an optional parameter to the reset call. And, more importantly, when forking or resetting to a fork, the network should return the chainId of the fork.

Keep up your good work.

fvictorio commented 10 months ago

@Valentin-Seehausen I agree that this is super important, but we are in the middle of a huge refactor of the hardhat network which prevents us from implementing things like these (otherwise we get some nasty merge conflicts). As soon as that's finished, this issue will be one of the most important among the ones that are blocked.

BlinkyStitt commented 7 months ago

any eta on that refactor? I've got some scripts that are blocked by this. I can stick with ganache for now, but not for much longer since it is deprecated.

blockedby commented 6 months ago

please

garb4ge commented 1 month ago

Would also really like this feature. I was a bit surprised that something like this is not implemented. For now, I will stick to anvil and run it in a dedicated process in each test but I would really like to see hardhat in my code since it is TS anyway :) Keep up the great work!