以太坊的 ChainId 与 NetworkId

只简单介绍这两个玩意是干啥的

什么是 ChainId

ChainId 是 EIP-155 引入的一个用来区分不同 EVM 链的一个标识。如下图所示,主要作用就是避免一个交易在签名之后被重复在不同的链上提交。最开始主要是为了防止以太坊交易在以太经典网络上重放或者以太经典交易在以太坊网络上重放。在以太坊网络上是从 2675000 这个区块通过 Spurious Dragon 这个硬分叉升级激活。
查看chainID那些已被使用

引入 ChainId 后,带来了哪些影响呢?

1.创建新的 EVM 链时,需要在 genesis 文件中指定 ChainId。这个 ChainId 最好不要和现有任何已经在公开运行的 EVM 链的 ChainId 相同,否则可以一个配置失误就误花掉一笔钱。下面是一个 genesis 文件配置示例。已经被占用的 ChainId 可以通过这个列表查看。

{
  "config": {
    "chainID": 1024,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc": {},
  "coinbase": "0x3333333333333333333333333333333333333333",
  "difficulty": "0x400",
  "extraData": "0x00",
  "gasLimit": "0x8000000",
  "nonce": "0x0000000000000042",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp": "0x00"
}

2.签名交易时,最好指定 ChainId,现在各种 SDK 库基本上都支持指定 ChainId 签名,比如 web3j 就提供了两种签名 API。当前的以太坊应该是两种签名都支持。

public static byte[] signMessage(RawTransaction rawTransaction, Credentials credentials) {
        byte[] encodedTransaction = encode(rawTransaction);
        Sign.SignatureData signatureData =
                Sign.signMessage(encodedTransaction, credentials.getEcKeyPair());

        return encode(rawTransaction, signatureData);
    }

    public static byte[] signMessage(
            RawTransaction rawTransaction, long chainId, Credentials credentials) {
        byte[] encodedTransaction = encode(rawTransaction, chainId);
        Sign.SignatureData signatureData =
                Sign.signMessage(encodedTransaction, credentials.getEcKeyPair());

        Sign.SignatureData eip155SignatureData = createEip155SignatureData(signatureData, chainId);
        return encode(rawTransaction, eip155SignatureData);
    }

什么是 NetworkId

NetworkId 主要用来在网络层标识当前的区块链网络。NetworkId 不一致的两个节点无法建立连接。

// status.NetworkID 为对方节点的 NetworkID,network 为当前节点的 NetworkID
if status.NetworkID != network {
        return errResp(ErrNetworkIDMismatch, "%d (!= %d)", status.NetworkID, network)
    }

NetworkId 无法通过配置文件指定,智能通过参数 --networkid 来指定。所以我们启动自己私链节点上需要记得加上这个参数。如果不加这个参数也不指定网络类型,默认 NetworkId 的值和以太坊主网一致。

3.ChainId 和 NetworkId 是一回事么

不是。
这个根据上面的介绍可以很明显的看出,两者并没有非常高的关联度。
网上几乎所有提到搭建以太坊私链的文章,都要强调 NetworkId 需要和 genesis 文件里 ChainId 的值相同。事实上是没必要的。

ChainId 与 NetworkId
之所以很多文章强调 ChainId 和 NetworkId 要保持一致,可能因为在某一段时间内,一些开发工具比如 MetaMask,会把 NetworkId 当作 ChainId 来用。不过现在 MetaMask 已经支持自定义 ChainId,以太坊也添加了 “eth_chainId” 这个 RPC API,相信两者误用的情况会越来越少。

4 总结

ChainId 是用来防止交易在不同的以太坊同构网络进行交易重放的。主要在交易签名和验证的时候使用。
NetworkId 是用来标识区块链网络的。主要在节点之间握手并相互检验的时候使用。
ChainId 需要在 genesis 文件中指定,NetworkId 需要在启动参数中指定。
ChainId 和 NetworkId 的值不需要相同。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
节点? 要在Windows系统上搭建以太坊节点,您需要执行以下步骤: 1. 安装Geth客户端:Geth是以太坊的官方客户端,您可以从https://geth.ethereum.org/downloads/下载最新版本的Geth客户端。 2. 安装Node.js:以太坊需要Node.js运行时才能正常工作。您可以从https://nodejs.org/en/下载最新版本的Node.js。 3. 安装Git:您需要安装Git才能从以太坊的GitHub存储库中获取源代码。您可以从https://git-scm.com/downloads下载最新版本的Git。 4. 下载以太坊源代码:打开命令提示符(或PowerShell)并使用以下命令克隆以太坊的GitHub存储库: ``` git clone https://github.com/ethereum/go-ethereum.git ``` 5. 安装依赖项:使用以下命令安装以太坊的依赖项: ``` cd go-ethereum make geth ``` 6. 启动节点:使用以下命令启动以太坊节点: ``` geth --datadir=./data init genesis.json geth --datadir=./data --networkid=15 --nodiscover console ``` 其中,`--datadir`指定数据目录,`init`命令初始化以太坊节点,`--networkid`指定以太坊网络ID,`--nodiscover`禁止节点自动发现其他节点,`console`启动以太坊控制台。 7. 连接到节点:打开另一个命令提示符(或PowerShell)并使用以下命令连接到已启动的以太坊节点: ``` geth attach ipc:\.\pipe\geth.ipc ``` 其中,`.\pipe\geth.ipc`是节点的IPC路径,可以在启动节点时找到。 完成上述步骤后,您应该已经成功在Windows系统上搭建了一个以太坊节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值