EIP-778: 以太坊节点记录 (ENR)
Authors | Felix Lange <fjl@ethereum.org> |
---|---|
Created | 2017-11-23 |
摘要
本 EIP 定义了以太坊节点记录,这是一种用于 p2p 连接信息的开放格式。
动机
以太坊节点通过节点发现协议相互发现。该协议的目的是传递节点身份公钥(在 secp256k1 曲线上的)、它们的 IP 地址和两个端口号。没有其他信息可以传递。
本规范旨在通过定义一种灵活的格式,即 节点记录,来消除发现 v4 协议的限制,该格式包含与连接性相关的信息。节点记录可以通过未来版本的节点发现协议进行传递。它们也可以通过任意其他机制进行传递,例如 DNS、ENS、devp2p 子协议等。
节点记录改进了密码学灵活性和协议升级的处理。一条记录可以包含有关任意传输协议以及与之关联的公钥材料的信息。
新格式的另一个目标是提供连接信息的权威更新。如果一个节点更改了它的端点并发布了一条新记录,其他节点应该能够确定哪条记录更新。
规范
节点记录的组成部分是:
signature
:记录内容的密码学签名seq
:序列号,一个 64 位无符号整数。节点应该在记录更改并重新发布记录时增加该数字。- 记录的其余部分由任意的键/值对组成
记录的签名根据 身份方案 进行创建和验证。身份方案还负责在 DHT 中派生节点的地址。
键/值对必须按键排序并且必须是唯一的,即任何键只能出现一次。从技术上讲,键可以是任何字节序列,但首选 ASCII 文本。下表中的键名具有预定义的含义。
键 | 值 |
---|---|
id |
身份方案的名称,例如 “v4” |
secp256k1 |
压缩的 secp256k1 公钥,33 字节 |
ip |
IPv4 地址,4 字节 |
tcp |
TCP 端口,大端整数 |
udp |
UDP 端口,大端整数 |
ip6 |
IPv6 地址,16 字节 |
tcp6 |
IPv6 特定的 TCP 端口,大端整数 |
udp6 |
IPv6 特定的 UDP 端口,大端整数 |
除了 id
之外的所有键都是可选的,包括 IP 地址和端口。只要其签名有效,没有端点信息的记录仍然有效。 如果没有提供 tcp6
/ udp6
端口,则 tcp
/ udp
端口同时适用于这两个 IP 地址。应避免在 tcp
,tcp6
或 udp
,udp6
中声明相同的端口号,但这不会使记录无效。
RLP 编码
节点记录的规范编码是 [signature, seq, k, v, ...]
的 RLP 列表。节点记录的最大编码大小为 300 字节。实现应拒绝大于此大小的记录。
记录按如下方式签名和编码:
content = [seq, k, v, ...]
signature = sign(content)
record = [signature, seq, k, v, ...]
文本编码
节点记录的文本形式是其 RLP 表示的 base64 编码,前缀为 enr:
。实现应使用 URL 安全的 base64 字母表 并省略填充字符。
“v4” 身份方案
本规范定义了一个单一的身份方案,在其他方案通过进一步的 EIP 定义之前,将其用作默认方案。 “v4” 方案与节点发现 v4 使用的密码系统向后兼容。
- 要使用此方案对记录
content
进行签名,请将 keccak256 哈希函数(由 EVM 使用)应用于content
,然后创建哈希的签名。生成的 64 字节签名编码为r
和s
签名值的连接(省略恢复 IDv
)。 - 要验证记录,请检查签名是否由记录的 “secp256k1” 键/值对中的公钥生成。
- 要派生节点地址,请获取未压缩公钥的 keccak256 哈希。
理由
该格式旨在通过两种方式满足未来的需求:
- 添加新的键/值对:这始终是可能的,并且不需要实现共识。 现有的客户端将接受任何键/值对,无论它们是否可以解释其内容。
- 添加身份方案:这些需要实现共识,否则网络将不接受该签名。 要引入新的身份方案,请提出 EIP 并使其实现。 只要大多数客户端接受该方案,就可以使用该方案。
记录的大小受到限制,因为记录被频繁传递,并且可能包含在大小受限的协议(例如 DNS)中。 当使用 “v4” 方案签名时,包含 IPv4 地址的记录大约占用 120 字节,从而为其他元数据留出了足够的空间。
您可能想知道为什么需要如此多与 IP 地址和端口相关的预定义键。 出现这种需求的原因是,住宅和移动网络设置通常将 IPv4 放在 NAT 之后,而 IPv6 流量(如果支持)则直接路由到同一主机。 声明两种地址类型可确保节点可以从仅 IPv4 的位置以及同时支持这两种协议的位置访问。
测试向量
这是一个包含 IPv4 地址 127.0.0.1
和 UDP 端口 30303
的示例记录。 节点 ID 是 a448f24c6d18e575453db13171562b71999873db5b286df957af199ec94617f7
。
enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5wBgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8
该记录使用序列号 1
和以下私钥,使用 “v4” 身份方案进行签名:
b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291
记录的 RLP 结构是:
[
7098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c,
01,
"id",
"v4",
"ip",
7f000001,
"secp256k1",
03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138,
"udp",
765f,
]
版权
版权及相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Felix Lange <fjl@ethereum.org>, "EIP-778: 以太坊节点记录 (ENR)," Ethereum Improvement Proposals, no. 778, November 2017. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-778.