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实现抗审查主要通过以下机制:

  1. 去中心化架构:没有中心服务器,消息通过中继网络传播
  2. 加密签名:所有消息都经过发送者私钥签名,确保真实性
  3. 中继多样性:用户可以连接到多个中继,避免单点故障
  4. 内容不可变:事件一旦发布就无法修改,只能删除
  5. 开放协议:任何人都可以运行中继或开发客户端

注意事项

  • 该库目前处于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实现,具有以下特点:

  • 去中心化:没有中心服务器控制网络
  • 抗审查:消息通过中继节点传播,难以被单一实体屏蔽
  • 身份验证:基于公私钥加密的身份系统
  • 轻量级:协议简单,易于实现

核心概念

  1. 事件(Events):网络中的基本数据单元,包含消息内容
  2. 中继(Relays):存储和转发事件的服务器
  3. 密钥对:用户身份基于加密密钥对(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(())
}

示例说明

  1. 密钥生成:程序首先生成新的加密密钥对,这是用户在nostr网络中的身份标识
  2. 客户端初始化:创建客户端并连接到一个公共中继服务器
  3. 个人资料设置:更新用户的名称和简介信息
  4. 消息发送
    • 发送公开消息,所有订阅者都能看到
    • 发送加密私信,只有指定接收者能解密阅读
  5. 消息接收:订阅并监听新的公开消息

使用建议

  1. 在实际应用中,应该将密钥安全存储
  2. 可以连接多个中继以提高消息可达性
  3. 对于生产环境,建议运行自己的中继服务器
  4. 加密私信需要预先知道接收者的公钥

这个完整示例展示了nostr库的主要功能,包括身份管理、消息发送接收、加密通信等核心特性。开发者可以根据需要扩展更多功能,如实现更复杂的事件过滤、支持更多种类的事件类型等。

回到顶部