Rust去中心化社交协议库nostr的使用,nostr实现抗审查的点对点消息传递与身份验证
Rust去中心化社交协议库nostr的使用,nostr实现抗审查的点对点消息传递与身份验证
简介
Nostr是一个去中心化的社交网络协议,Rust实现版提供了完整的协议支持。它具有以下特点:
- 完全去中心化,无需中心服务器
- 抗审查的点对点消息传递
- 基于公私钥的身份验证系统
- 支持多种NIP( Nostr Implementation Possibilities)扩展
快速开始示例
use nostr::prelude::*;
fn main() -> Result<()> {
// 生成新的随机密钥
let keys = Keys::generate();
// 或者使用已有的密钥(从hex或bech32格式)
let keys = Keys::parse("hex-or-bech32-secret-key")?;
// 将公钥转换为bech32格式
println!("Public key: {}", keys.public_key().to_bech32()?);
let metadata = Metadata::new()
.name("username")
.display_name("My Username")
.about("Description")
.picture(Url::parse("https://example.com/avatar.png")?)
.banner(Url::parse("https://example.com/banner.png")?)
.nip05("username@example.com")
.lud16("pay@yukikishimoto.com")
.custom_field("custom_field", "my value");
let event: Event = EventBuilder::metadata(&metadata).sign_with_keys(&keys)?;
// 新建文本笔记
let event: Event = EventBuilder::text_note("Hello from rust-nostr").sign_with_keys(&keys)?;
// 新建POW文本笔记
let event: Event = EventBuilder::text_note("POW text note from rust-nostr").pow(20).sign_with_keys(&keys)?;
// 将客户端消息转换为JSON
let json = ClientMessage::event(event).as_json();
println!("{json}");
Ok(())
}
完整示例代码
use nostr::prelude::*;
use nostr_sdk::Client;
#[tokio::main]
async fn main() -> Result<()> {
// 1. 生成密钥对(身份验证基础)
let keys = Keys::generate();
println!("生成新密钥对,公钥(bech32格式): {}", keys.public_key().to_bech32()?);
// 2. 创建客户端并连接中继服务器
let client = Client::new(&keys);
// 添加中继服务器地址
client.add_relay("wss://relay.example.com").await?;
client.add_relay("wss://backup.relay.example.org").await?;
// 连接到所有中继
client.connect().await;
// 3. 设置用户元数据(个人资料信息)
let metadata = Metadata::new()
.name("rust_nostr_user") // 用户名
.display_name("Rust Nostr用户") // 显示名称
.about("使用Rust nostr库的示例用户") // 个人简介
.picture(Url::parse("https://example.com/avatar.png")?) // 头像
.banner(Url::parse("https://example.com/banner.png")?) // 横幅图片
.nip05("user@example.com") // NIP-05验证标识
.lud16("pay@example.com"); // 闪电网络支付地址
// 创建元数据事件并签名
let metadata_event = EventBuilder::metadata(&metadata).sign_with_keys(&keys)?;
// 发布元数据到中继
client.send_event(metadata_event).await?;
println!("用户元数据已发布");
// 4. 发送抗审查的消息
let message = "这是一条通过nostr协议发送的抗审查消息,任何人都无法阻止它传播";
let event = EventBuilder::text_note(message)
.sign_with_keys(&keys)?;
client.send_event(event).await?;
println!("消息已发送到中继网络");
// 5. 接收消息
// 创建订阅过滤器,只接收自己发送的消息
let subscription = Filter::new()
.authors(vec![keys.public_key()]) // 只监听自己的公钥
.limit(10); // 最多10条消息
// 订阅消息
client.subscribe(vec![subscription]).await;
println!("开始监听消息...");
// 处理接收到的消息
while let Ok(notification) = client.notifications().recv().await {
match notification {
RelayPoolNotification::Event(_, event) => {
println!("收到新事件 - 类型: {}, 内容: {}", event.kind, event.content);
}
RelayPoolNotification::Message(_, msg) => {
println!("收到中继消息: {:?}", msg);
}
_ => {}
}
}
Ok(())
}
特性支持
nostr库支持多种NIP扩展功能:
特性 | 默认 | 描述 |
---|---|---|
nip04 |
否 | 支持NIP-04: 加密直接消息 |
nip06 |
否 | 支持NIP-06: 从助记词派生密钥 |
nip44 |
否 | 支持NIP-44: 加密负载(版本化) |
nip46 |
否 | 支持NIP-46: Nostr连接 |
nip47 |
否 | 支持NIP-47: Nostr钱包连接 |
抗审查实现原理
nostr实现抗审查主要通过以下机制:
- 去中心化架构:没有中心服务器,消息通过中继网络传播
- 加密签名:所有消息都经过发送者私钥签名,确保真实性
- 中继多样性:用户可以连接到多个中继,避免单点故障
- 内容不可变:事件一旦发布就无法修改,只能删除
- 开放协议:任何人都可以运行中继或开发客户端
注意事项
- 该库目前处于ALPHA状态,API可能会有重大变更
- 在生产环境中使用前请充分测试
- 确保妥善保管私钥,丢失私钥将无法恢复账户
可以通过添加以下依赖来使用nostr:
[dependencies]
nostr = "0.43.0"
tokio = { version = "1.0", features = ["full"] }
1 回复
Rust去中心化社交协议库nostr的使用
nostr简介
nostr(Notes and Other Stuff Transmitted by Relays)是一个极简的开放协议,用于抗审查的点对点消息传递和身份验证。它基于Rust实现,具有以下特点:
- 去中心化:没有中心服务器控制网络
- 抗审查:消息通过中继节点传播,难以被单一实体屏蔽
- 身份验证:基于公私钥加密的身份系统
- 轻量级:协议简单,易于实现
核心概念
- 事件(Events):网络中的基本数据单元,包含消息内容
- 中继(Relays):存储和转发事件的服务器
- 密钥对:用户身份基于加密密钥对(secp256k1)
完整示例demo
use nostr::prelude::*;
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<()> {
// 1. 生成密钥对
let keys = Keys::generate();
println!("公钥: {}", keys.public_key());
println!("私钥: {}", keys.secret_key()?);
// 2. 创建客户端并添加中继
let client = Client::new(&keys);
client.add_relay("wss://relay.damus.io").await?;
// 3. 更新用户元数据
update_profile(&client, "nostr用户", "这是一个测试账号").await?;
// 4. 发送公开消息
send_message(&client, "大家好,这是我的第一条nostr消息!").await?;
// 5. 发送加密私信(需要替换为实际接收者公钥)
let recipient_pubkey = "接收者公钥";
send_encrypted_dm(&client, recipient_pubkey, "这是一个秘密消息").await?;
// 6. 接收消息
receive_messages(&client).await;
Ok(())
}
async fn send_message(client: &Client, message: &str) -> Result<()> {
// 创建文本事件
let event = EventBuilder::new_text_note(message).to_event(&client.keys())?;
// 发送事件
client.send_event(event).await?;
println!("消息已发送: {}", message);
Ok(())
}
async fn receive_messages(client: &Client) -> Result<()> {
// 订阅文本事件
let subscription = Filter::new()
.kind(Kind::TextNote)
.limit(10);
client.subscribe(vec![subscription]).await;
// 处理接收到的消息
let mut notifications = client.notifications();
while let Ok(notification) = notifications.recv().await {
if let RelayPoolNotification::Event(_, event) = notification {
println!("收到新消息[{}]: {}", event.pubkey, event.content);
}
}
Ok(())
}
async fn send_encrypted_dm(client: &Client, recipient_pubkey: &str, message: &str) -> Result<()> {
let recipient_pubkey = XOnlyPublicKey::from_str(recipient_pubkey)?;
let event = EventBuilder::new_encrypted_direct_msg(&client.keys(), recipient_pubkey, message)?
.to_event(&client.keys())?;
client.send_event(event).await?;
println!("加密私信已发送给: {}", recipient_pubkey);
Ok(())
}
async fn update_profile(client: &Client, name: &str, about: &str) -> Result<()> {
let metadata = Metadata::new()
.name(name)
.about(about);
let event = EventBuilder::set_metadata(&metadata).to_event(&client.keys())?;
client.send_event(event).await?;
println!("个人资料已更新: {} - {}", name, about);
Ok(())
}
示例说明
- 密钥生成:程序首先生成新的加密密钥对,这是用户在nostr网络中的身份标识
- 客户端初始化:创建客户端并连接到一个公共中继服务器
- 个人资料设置:更新用户的名称和简介信息
- 消息发送:
- 发送公开消息,所有订阅者都能看到
- 发送加密私信,只有指定接收者能解密阅读
- 消息接收:订阅并监听新的公开消息
使用建议
- 在实际应用中,应该将密钥安全存储
- 可以连接多个中继以提高消息可达性
- 对于生产环境,建议运行自己的中继服务器
- 加密私信需要预先知道接收者的公钥
这个完整示例展示了nostr库的主要功能,包括身份管理、消息发送接收、加密通信等核心特性。开发者可以根据需要扩展更多功能,如实现更复杂的事件过滤、支持更多种类的事件类型等。