I have set up a private Ethereum network with a custom chainId (for example 67890) specified in the config part of the genesis.json file, did geth init genesis.json, and got the private net up and running. However then I noticed some weird things like the web3 sendTransaction doesn't work as it says invalid sender, only after I specify the chainId explicitly in the transaction json to 67890 then it can send out the transaction correctly.

So I tried some test and found out that when I run web3.eth.net.getNetworkType() it returns privatenet, but when I run web3.eth.net.getId() it returns 1. And after some fumbling, I found out that I need to add a --networkid 67890 in the geth commandline parameter for the web3.eth.net.getId() to return the correct value of 67890.

So my question is, what's the difference between specifying the networkid in geth commandline and specifying the chainId in genesis.json? I thought the networkid and chainId are one and the same, and it seems that web3 uses the value of the networkid for the default value of the transaction chainId, but somehow when I start geth without explicit networkid parameter, it will ignore the chainId config and still use 1 as default, resulting in a different networkid from the chainId.

So for an ethereum blockchain, does it really make sense for the networkid and chainId to be different from each other, or is it some kind of bug?


1 Answer 1

  1. Network id and Chain id are the same thing

  2. You can edit NetworkId in eth/config.go & params/config.go and get rid of this problem forever, you won't need to specify network id on the commandline anymore.

  3. Ethereum's geth has hardcoded the value 1 in the files I told you , so this is why you have these problems.

  4. The chain id is now part of transaction as result of Ethereum Improvement Proposal (EIP) #155, so the invalid sender is shown because chain id is different. You can disable this using EIP155BlockNum , but you would be vulnerable to replay attack, if you use multiple networks, like a testnet for example.

  5. chain id is not part of the block's hash, so specifying it in the genesis file is really useless. What you have to do instead, is specify chainID in the source code or using commandline parameters.

  • I don't think I fully understand your answer, so you mean that we should not specify the chainId in the genesis.json? that it is useless to specify the chainId in the genesis file? Then why when I specify a chainId in genesis file but not the networkid in the geth command line, it will return an invalid sender error? Also it will send out the transaction correctly if I specify the chainId in the transaction to be the same as the genesis file. So it seems although web3.eth.net.getId() depends on the networkid parameter, the web3.eth.sendSignedTransaction depends on the chainID in genesis file?
    – hellopeach
    Aug 9, 2018 at 9:43
  • That's right, you can put chainID field into genesis block, but the blockchain database doesn't not store it. chainID is a parameter of geths source code only, not the database. That's what I mean.
    – Nulik
    Aug 9, 2018 at 13:24
  • However one year later, at block 2675000 chainID was added to Transactions table by adding EIP155 proposal to geth. This is the only storage of chainID in the database.
    – Nulik
    Aug 9, 2018 at 13:30
  • So, if you configure your private chain, you can work it with EIP155 or without. Without EIP155 you don't need chainID
    – Nulik
    Aug 9, 2018 at 13:32
  • type admin in the console, in protocols section you can see the network (which is the chainID) and verify it is set correctly
    – Nulik
    Aug 9, 2018 at 13:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.