7

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?

hellopeach
  • 861
  • 7
  • 19
  • Related: https://ethereum.stackexchange.com/questions/37533/what-is-a-chainid-in-ethereum-how-is-it-different-than-networkid-and-how-is-it?rq=1 – Richard Horrocks Aug 09 '18 at 19:52

1 Answers1

7
  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.

Nulik
  • 4,061
  • 1
  • 18
  • 30
  • 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 09 '18 at 09: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 09 '18 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 09 '18 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 09 '18 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 09 '18 at 13:34
  • I'm still quite confused about this EIP155 thing. So with EIP155, you need to put a chainId in your genesis file so that when you send the transaction you need to make sure the chainId parameter is the same as the one specified in the genesis file. However it does not enforce the chainId in the genesis file to be the same as the networkid of Geth, thus you may end up in a private chain where the web3.eth.getId() returns one number while you need to put another number for the chainId parameter in the transaction for it to send out correctly? That sounds quite weird, why should they allow this? – hellopeach Aug 09 '18 at 13:37
  • Probably at blockchain initialization, geth reads your genesis.json, and stores the chainID in parameters internally. Next time you start geth it reads chainID from there. But chainID is not part of block's hash, so it is not sealed cryptographically, if somebody copies your database and changes chainID everything is going to work fine with another chainID, unless EIP155 is enabled. If EIP155 is enabled, geth will give you error of invalid sender at processing first EIP155 enabled transaction – Nulik Aug 09 '18 at 13:39
  • I think that to understand what I mean, you have to do an excercise. Create 2 private chains. On the first chain, you are going to specify chainId in the genesis file. On the second chain you are going to delete this line, and initialize it without specifying chainID in the genesis. You will find out that both blockhains are exactly the same. – Nulik Aug 09 '18 at 13:54
  • I have also edited the answer #5 to make it more understandable. – Nulik Aug 09 '18 at 13:56
  • What I find confusing is,if I specify say "chainId: 67890" in the genesis file, and start geth without changing the code or setting the networkid (thus it remains as the default 1), when I run web3.eth.net.getId() I will get the result as 1. When I try to send transaction with web3.eth.sendSignedTransaction without specifying the chainId, it will report "invalid sender", but if I send transaction with web3.eth.sendSignedTransaction and specifying the chainId as 67890, it will succeed. That seems quite a weird situation. – hellopeach Aug 09 '18 at 14:36
  • I thought they should report an error or something if your netwokid in geth parameters and the chainId in the genesis file are different when you start geth, but apparently there's no error in starting geth, just that when you read networkid with web3 you get 1, but when you send transaction with web3 you need to specify 67890 as the chainId. Why should they allow such a situation if networkid and chainId are meant to be the same thing? Why am I allowed to start a private chain where the networkid and chainId are actually different? – hellopeach Aug 09 '18 at 14:40
  • well that's a question to the Ethereum Foundation. – Nulik Aug 09 '18 at 14:45