#record #ed25519-key #ethereum #node #eip-778

enr

Rust 实现 Ethereum 节点记录 (ENR) EIP778

30 个版本

0.12.1 2024年6月17日
0.11.1 2024年4月9日
0.11.0 2024年3月17日
0.10.0 2023年11月28日
0.1.0-alpha-1 2020年2月17日

1393神奇豆子

Download history 55247/week @ 2024-04-16 55260/week @ 2024-04-23 46008/week @ 2024-04-30 47217/week @ 2024-05-07 47078/week @ 2024-05-14 44324/week @ 2024-05-21 45178/week @ 2024-05-28 49774/week @ 2024-06-04 51713/week @ 2024-06-11 50708/week @ 2024-06-18 51884/week @ 2024-06-25 44868/week @ 2024-07-02 48173/week @ 2024-07-09 55895/week @ 2024-07-16 51346/week @ 2024-07-23 47699/week @ 2024-07-30

211,965 每月下载量
用于 184 个 crate(4 个直接使用)

MIT 许可证

120KB
2K SLoC

enr

Build Status Doc Status Crates Status

在 docs.rs 上的文档

此 crate 包含了一个 Ethereum 节点记录 (ENR) 的实现,该记录由 EIP-778 规定,并扩展以允许使用 ed25519 密钥。

ENR 是一个带签名的键值记录,与一个相关的 NodeId(一个 32 字节标识符)相关联。更新/修改 ENR 需要一个 EnrKey 来重新签名记录,使用相关密钥对。

ENR 通过其序列号进行标识。更新 ENR 时,序列号会增加。

可以使用不同的身份方案来定义节点 ID 和签名。目前仅支持 "v4" 身份,并默认设置。

签名算法

希望实现自己的签名算法的用户只需实现 EnrKey 特性并将其应用于 Enr

默认情况下,k256::SigningKey 实现 EnrKey 并可用于签名和验证 ENR 记录。此库还通过 ed25519 功能标志实现了 ed25519_dalek::KeypairEnrKey

此外,如果设置了 ed25519 功能标志,提供了一个 CombinedKey,它提供了一个可以支持 secp256k1ed25519 签名 ENR 记录的 ENR 类型。以下给出了这些密钥类型的每个示例使用。

功能

此包支持许多功能。

  • serde:允许对ENRs进行serde序列化和反序列化。
  • ed25519:为ed25519_dalek密钥对类型提供支持。
  • rust-secp256k1:使用c-secp256k1进行secp256k1密钥。

您可以通过在您的Cargo.toml中添加功能标志来启用这些功能。

enr = { version = "*", features = ["serde", "ed25519", "rust-secp256k1"] }

示例

使用默认的k256密钥类型构建ENR

use enr::{Enr, k256};
use std::net::Ipv4Addr;
use rand::thread_rng;

// generate a random secp256k1 key
let mut rng = thread_rng();
let key = k256::ecdsa::SigningKey::random(&mut rng);

let ip = Ipv4Addr::new(192,168,0,1);
let enr = Enr::builder().ip4(ip).tcp4(8000).build(&key).unwrap();

assert_eq!(enr.ip4(), Some("192.168.0.1".parse().unwrap()));
assert_eq!(enr.id(), Some("v4".into()));

使用CombinedKey类型构建ENR(支持多种签名算法)。

请注意必须设置ed25519功能标志。这使builder::Builder结构体可用。

use enr::{Enr, CombinedKey};
use std::net::Ipv4Addr;

// create a new secp256k1 key
let key = CombinedKey::generate_secp256k1();

// or create a new ed25519 key
let key = CombinedKey::generate_ed25519();

let ip = Ipv4Addr::new(192,168,0,1);
let enr = Enr::builder().ip4(ip).tcp4(8000).build(&key).unwrap();

assert_eq!(enr.ip4(), Some("192.168.0.1".parse().unwrap()));
assert_eq!(enr.id(), Some("v4".into()));

修改ENR

可以使用Enr上的getter/setter来添加和修改ENR字段。可以使用insert添加自定义字段,并使用get检索。

use enr::{k256::ecdsa::SigningKey, Enr};
use std::net::Ipv4Addr;
use rand::thread_rng;

// specify the type of ENR
type DefaultEnr = Enr<SigningKey>;

// generate a random secp256k1 key
let mut rng = thread_rng();
let key = SigningKey::random(&mut rng);

let ip = Ipv4Addr::new(192,168,0,1);
let mut enr = Enr::builder().ip4(ip).tcp4(8000).build(&key).unwrap();

enr.set_tcp4(8001, &key);
// set a custom key
enr.insert("custom_key", &vec![0,0,1], &key);

// encode to base64
let base_64_string = enr.to_base64();

// decode from base64
let decoded_enr: DefaultEnr = base_64_string.parse().unwrap();

assert_eq!(decoded_enr.ip4(), Some("192.168.0.1".parse().unwrap()));
assert_eq!(decoded_enr.id(), Some("v4".into()));
assert_eq!(decoded_enr.tcp4(), Some(8001));
assert_eq!(decoded_enr.get("custom_key"), Some(vec![0,0,1].as_slice()));

编码/解码各种密钥类型的ENR

use enr::{k256::ecdsa::SigningKey, Enr, ed25519_dalek::Keypair, CombinedKey};
use std::net::Ipv4Addr;
use rand::thread_rng;
use rand::Rng;

// generate a random secp256k1 key
let mut rng = thread_rng();
let key = SigningKey::random(&mut rng);
let ip = Ipv4Addr::new(192,168,0,1);
let enr_secp256k1 = Enr::builder().ip4(ip).tcp4(8000).build(&key).unwrap();

// encode to base64
let base64_string_secp256k1 = enr_secp256k1.to_base64();

// generate a random ed25519 key
let mut rng = rand_07::thread_rng();
let key = Keypair::generate(&mut rng);
let enr_ed25519 = Enr::builder().ip4(ip).tcp4(8000).build(&key).unwrap();

// encode to base64
let base64_string_ed25519 = enr_ed25519.to_base64();

// decode base64 strings of varying key types
// decode the secp256k1 with default Enr
let decoded_enr_secp256k1: Enr<k256::ecdsa::SigningKey> = base64_string_secp256k1.parse().unwrap();
// decode ed25519 ENRs
let decoded_enr_ed25519: Enr<ed25519_dalek::Keypair> = base64_string_ed25519.parse().unwrap();

// use the combined key to be able to decode either
let decoded_enr: Enr<CombinedKey> = base64_string_secp256k1.parse().unwrap();
let decoded_enr: Enr<CombinedKey> = base64_string_ed25519.parse().unwrap();

依赖关系

~4–6MB
~105K SLoC