Nostr NIP 協議詳解
Nostr 改進提案協議詳解
Nostr NIP 協議深度解析
什麼是 NIP
NIP(Nostr Implementation Possibilities)是 Nostr 協議的擴展規範,定義了客戶端和 relays之間交互的標準。每個 NIP 處理特定的用例或功能,確保不同客戶端的互操作性。
NIP 體系結構
協議層級
┌─────────────────────────────────────────┐
│ Application Layer │
│ (Clients: Damus, Iris, etc.) │
├─────────────────────────────────────────┤
│ NIP Layer │
│ (NIP-01, NIP-02, NIP-26, etc.) │
├─────────────────────────────────────────┤
│ Base Protocol │
│ (NIP-01 核心) │
├─────────────────────────────────────────┤
│ Transport Layer │
│ WebSocket │
└─────────────────────────────────────────┘
核心 NIP 與擴展 NIP
| 類別 | NIP 編號 | 描述 |
|---|---|---|
| 核心 | NIP-01 | 基本協議 |
| 核心 | NIP-02 | 聯繫人名單 |
| 核心 | NIP-04 | 加密私信 |
| 擴展 | NIP-26 | 委託登錄 |
| 擴展 | NIP-57 | 閃電網絡 zaps |
| 擴展 | NIP-65 | 公告列表 |
核心 NIP 詳解
NIP-01:基礎協議
定義 Nostr 的基本結構:
{
"kind": 1,
"created_at": 167890,
"content": "Hello Nostr!",
"tags": [],
"pubkey": "npub1...",
"sig": "schnorr签名"
}
事件類型:
| Kind | 描述 |
|---|---|
| 0 | 元數據(用戶資料) |
| 1 | 文字筆記 |
| 3 | 關注列表 |
| 4 | 加密私信 |
| 5 | 刪除事件 |
| 6 | 轉發 |
| 7 | 點讚 |
| 8 | 閒置 |
NIP-02:聯繫人名單
管理用戶的社交圖譜:
class ContactList:
def __init__(self):
self.contacts = [] # [(pubkey, relay_url, petname)]
def add_contact(self, pubkey, relay_url=None, petname=None):
"""添加聯繫人"""
self.contacts.append((pubkey, relay_url, petname))
def to_event(self, kind=3):
"""轉換為 Nostr 事件"""
content = json.dumps([
[pubkey, relay_url, petname]
for pubkey, relay_url, petname in self.contacts
])
return Event(
kind=kind,
content=content,
created_at=time.time()
)
NIP-04:加密私信
端到端加密的私人訊息:
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
import json
class DirectMessage:
def __init__(self, sender_privkey, recipient_pubkey):
self.sender_privkey = sender_privkey
self.recipient_pubkey = recipient_pubkey
def encrypt(self, message):
"""加密訊息"""
# 生成臨時密鑰對
ephemeral_key = ec.generate_private_key(ec.SECP256K1())
# 計算共享密鑰
shared_key = self.derive_shared_key(
ephemeral_key,
self.recipient_pubkey
)
# AES-GCM 加密
ciphertext = encrypt_aes_gcm(shared_key, message)
return {
'epk': ephemeral_key.public_key().serialize(),
'ciphertext': ciphertext
}
def decrypt(self, encrypted_data):
"""解密訊息"""
# 恢復共享密鑰
shared_key = self.derive_shared_key(
self.sender_privkey,
encrypted_data['epk']
)
# 解密
return decrypt_aes_gcm(shared_key, encrypted_data['ciphertext'])
重要擴展 NIP
NIP-26:委託登錄
允許用戶委託其他密鑰發布事件:
class Delegation:
def __init__(self, delegator_privkey):
self.delegator_privkey = delegator_privkey
self.delegator_pubkey = privkey_to_pubkey(delegator_privkey)
def create_delegation(self, delegate_pubkey, conditions):
"""
創建委託權限
conditions: 如 {"kind": 1}
"""
# 委託 token
token = json.dumps({
'delegate': delegate_pubkey,
'conditions': conditions,
'created_at': time.time()
})
# 委託者簽名
signature = sign(self.delegator_privkey, token)
return {
'token': token,
'sig': signature
}
def sign_as_delegate(self, delegate_privkey, delegation, event):
"""使用委託權限簽名"""
# 驗證委託有效性
verify_delegation(delegation)
# 委託者公鑰作為發布者
event.pubkey = delegation.delegate_pubkey
event.delegation = delegation
# 使用委託者密鑰簽名(不是 delegate)
event.sig = sign(self.delegator_privkey, event.serialize())
NIP-57:閃電網絡 Zaps
支持比特幣閃電網絡打賞:
class Zap:
def __init__(self, client):
self.client = client
self.relays = get_zap_enabled_relays()
def create_zap_request(self, recipient_pubkey, amount, content, lnurl):
"""
創建 Zap 請求
"""
# 生成隨機 bolt11 請求
invoice = self.request_invoice(
amount,
recipient_pubkey,
content
)
# 創建 NIP-57 事件 (kind 9734)
zap_request = {
'kind': 9734,
'created_at': time.time(),
'content': content,
'tags': [
['p', recipient_pubkey],
['amount', str(amount)], # millisats
['lnurl', lnurl],
[' Bolt11 發票']
]
}
# 客戶端簽名
zap_request['sig'] = self.client.sign(zap_request)
return zap_request
def process_zap(self, zap_event):
"""
處理收到的 Zap
"""
# 驗證事件有效性
verify_event(zap_event)
# 獲取付款證明
payment_preimage = self.wait_for_payment(zap_event['id'])
# 發布確認事件 (kind 9735)
zap_receipt = {
'kind': 9735,
'created_at': time.time(),
'tags': [
['e', zap_event['id']],
['p', zap_event['pubkey']],
['relays', self.relays]
],
'content': payment_preimage # 付款原像
}
self.client.publish(zap_receipt)
NIP-65:公告列表
管理用戶首選的 relays:
class RelayList:
def __init__(self):
self.read_relays = []
self.write_relays = []
def add_read_relay(self, url):
"""添加讀取 relay"""
if url not in self.read_relays:
self.read_relays.append(url)
def add_write_relay(self, url):
"""添加寫入 relay"""
if url not in self.write_relays:
self.write_relays.append(url)
def to_event(self):
"""轉換為 NIP-65 事件"""
content = json.dumps({
'read': self.read_relays,
'write': self.write_relays
})
return Event(
kind=10002,
content=content,
created_at=time.time()
)
其他重要 NIP
NIP-09:刪除事件
{
"kind": 5,
"created_at": 167890,
"content": "Reason for deletion",
"tags": [
["e", "event_id_to_delete"]
]
}
NIP-10:對事件的回覆
在 ["e"] 標籤中使用 "reply" 標記:
["e", "parent_event_id", "relay_url", "reply"]
NIP-12:通用標籤查詢
允許 relays 支援更靈活的過濾:
{
"kinds": [1],
"#t": ["bitcoin", "nostr"]
}
NIP-15:結束事件
定義事件傳播的結束:
{
"kind": 7,
"created_at": 0,
"content": "EOSE",
"tags": []
}
NIP-20:事件結果
{
"kind": 2000,
"content": "duplicate",
"tags": [
["e", "event_id"]
]
}
客戶端實現指南
1. 基本客戶端結構
class NostrClient:
def __init__(self, private_key):
self.private_key = private_key
self.public_key = private_to_public(private_key)
self.relays = {}
def connect(self, relay_url):
"""連接到 relay"""
ws = websocket.WebSocketApp(
relay_url,
on_message=self.on_message,
on_error=self.on_error,
on_close=self.on_close
)
self.relays[relay_url] = ws
def publish(self, event):
"""發布事件"""
for relay in self.relays.values():
relay.send(json.dumps(event))
def subscribe(self, subscription_id, filters):
"""訂閱事件"""
msg = ["REQ", subscription_id, filters]
for relay in self.relays.values():
relay.send(json.dumps(msg))
2. 事件處理
def on_message(self, ws, message):
"""處理收到的消息"""
msg = json.loads(message)
msg_type = msg[0]
if msg_type == 'EVENT':
# 新事件
subscription_id = msg[1]
event = msg[2]
self.handle_event(event)
elif msg_type == 'EOSE':
# 訂閱結束
subscription_id = msg[1]
self.on_subscription_complete(subscription_id)
elif msg_type == 'OK':
# 事件已接受
event_id = msg[1]
success = msg[2]
NIP 開發最佳實踐
1. 兼容性
- 始終支持核心 NIP
- 實現前檢查客戶端支持
- 處理不支持的 NIP 優雅降級
2. 安全性
- 本地存儲私鑰
- 驗證所有簽名
- 避免在客戶端存儲敏感數據
3. 性能
- 使用多個 relays
- 實現本地緩存
- 懶加載歷史事件
未來 NIP 提案
正在討論
- NIP-66: 群組/頻道增強
- NIP-67: 個人資料圖片
- NIP-68: 長期訂閱
實驗性
- NIP-98: HTTP 驗證
- NIP-99: 分類帳
總結
NIP 協議是 Nostr 生態系統的支柱,為去中心化社交網絡提供了標準化的互操作性。從基礎的發布/訂閱到複雜的閃電網絡打賞,每個 NIP 都擴展了協議的功能。開發者應熟悉核心 NIP,並根據應用需求選擇實現相應的擴展。隨著生態系統的發展,更多 NIP 將被提出和標準化,推動去中心化社交網絡的持續創新。
風險提示
- 閃電網絡技術仍在發展
- 私鑰丟失無法恢復
- 中繼可能被審查
- 某些 NIP 可能不兼容
相關文章
- 什麼是 Nostr? — 理解比特幣開發者構建的去中心化社交協議。
- 閃電 Zap 深度解析 — Nostr 閃電 Zap 支付機制
- Nostr 協議架構 — 深入理解 Nostr 的中繼器、客戶端與密鑰體系。
- Nostr 驗證與身份 — 如何使用 Nostr 進行身份驗證與建立聲譽。
- Nostr Zap 閃電支付 — 透過 Nostr Zap 实现内容变现与小费打赏。
延伸閱讀與來源
這篇文章對您有幫助嗎?
請告訴我們如何改進:
0 人覺得有帮助
評論
發表評論
注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。
目前尚無評論,成為第一個發表評論的人吧!