以太坊的NodeID
在启动Geth客户端时,会看到有如下输出内容:
节点的NodeID在上图中已经圈出来了,这个NodeID在别人通过admin.addPeer添加节点时要作为参数传入。
这个NodeID是怎么计算出来的?
NodeID的计算
上图NodeID值如下:
enode://af18b22fcb7de98ab4ef5e0d273d516e7d31d7ebca2362a2fcf9eff821da0b6a98bea6c091743f339a8010812d94e685dc370a97a57e5134dbefd753ccf8c5d8@127.0.0.1:30303
由"enode://",一个16进制字符串,"@",IP地址和P2P端口(也是geth的TCP端口)组成。
16进制字符串
通过查看go-ethereum-1.10.26源代码,发现这个十六进制字符串是节点的ECDSA公钥的16进制形式。
也就是这里:
再深入看下FromECDSAPub做了什么:
S256()是ECDSA的一个曲线,包含了曲线的具体参数,再将公钥的X和Y值(一个公钥仅包含曲线参数、X、Y三个值)传入编码函数Marshal。
可以看到,Marshal将X、Y编码为了Bytes并返回。
一直返回,最后将Bytes转为了16进制并输出。
所以,这个NodeID就是节点的公钥。
我们没有创建账户,为什么会有公私钥?
在geth代码注释中,其对Node的解读为:
Node represents a host on the network.
所以在以太坊节点启动时,geth会自动随机生成一个公私钥作为节点的P2P网络身份,用于后续的P2P连接认证等用处。
可以尝试运行调试go-ethereum-1.10.26/cmd/bootnode/main.go并带上参数-genkey randomString --writeaddress
查看效果。