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 |
|
1393 在 神奇豆子
211,965 每月下载量
用于 184 个 crate(4 个直接使用)
120KB
2K SLoC
enr
此 crate 包含了一个 Ethereum 节点记录 (ENR) 的实现,该记录由 EIP-778 规定,并扩展以允许使用 ed25519 密钥。
ENR 是一个带签名的键值记录,与一个相关的 NodeId
(一个 32 字节标识符)相关联。更新/修改 ENR 需要一个 EnrKey
来重新签名记录,使用相关密钥对。
ENR 通过其序列号进行标识。更新 ENR 时,序列号会增加。
可以使用不同的身份方案来定义节点 ID 和签名。目前仅支持 "v4" 身份,并默认设置。
签名算法
希望实现自己的签名算法的用户只需实现 EnrKey
特性并将其应用于 Enr
。
默认情况下,k256::SigningKey
实现 EnrKey
并可用于签名和验证 ENR 记录。此库还通过 ed25519
功能标志实现了 ed25519_dalek::Keypair
的 EnrKey
。
此外,如果设置了 ed25519
功能标志,提供了一个 CombinedKey
,它提供了一个可以支持 secp256k1
和 ed25519
签名 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