信息的自由流通和分享是互聯網最大的魅力之一。
出於對更自由開放的互聯網的向往,我決定啟用碎片化信息發布平台,其中包括 Nostr (Notes and Other Stuff Transmitted by Relays)。Nostr 是一個協議,類似電子郵件協議;Nostr 的客戶端,如 Damus ,可看作一個去中心化的 Twitter。
本文介紹了 Nostr 協議,以及如何使用 Python 發布 Nostr Post 信息。
如果想關注本文作者,請前往 其他 頁面查看
Nostr 介紹#
- 協議簡介:nostr-protocol/nostr: a truly censorship-resistant alternative to Twitter that has a chance of working
- 協議細節:nostr-protocol/nips: Nostr Implementation Possibilities
通訊過程#
- 這個協議中有兩個東西,一個是 client,一個是 relay,client 就是用戶社交的客戶端,relay 就是轉發服務器。
- 用戶不需要註冊,用戶只需要有一個密鑰對(公鑰 + 私鑰)就好了,然後把要發的信息做簽名,發給一組 relays
- 然後你的 Follower 就可以從這些 relays 上訂閱到你的信息。(通過輸入 公鑰)
技術細節摘要#
-
技術實現上,nostr 使用 websocket + JSON 的方式。其中主要是下面這幾個指令
-
Client 到 Relay 主要是下面這幾個指令:
EVENT
。發出事件,可以擴展出很多很多的動作來,比如:發信息,刪信息,遷移信息,建 Channel …… 擴展性很好。REQ
。用於請求事件和訂閱更新。收到REQ
消息後,relay 會查詢其內部數據庫並返回與過濾器匹配的事件,然後存儲該過濾器,並將其接收的所有未來事件再次發送到同一 websocket,直到 websocket 關閉。CLOSE
。用於停止被REQ
請求的訂閱。
-
Relay 到 Client 主要是下面幾個指令:
EVENT
。用於發送客戶端請求的事件。NOTICE
。用於向客戶端發送人類可讀的錯誤消息或其他信息
-
-
關於
EVENT
下面是幾個常用的基本事件:0
:set_metadata
:比如,用戶名,用戶頭像,用戶簡介等這樣的信息。1
:text_note
:用戶要發的信息內容2
:recommend_server
:用戶想要推薦給關注者的 Relay 的 URL(例如wss://somerelay.com
)
Python 發布 Nostr 信息#
目標#
- 需求:提供私鑰和一段字符串文本,使用 Python 發布 Nostr 純文本 Post 信息
- 盡可能支持更多平台
方案#
調庫。
jeffthibault/python-nostr: A Python library for Nostr 這個,實際操作發現有依賴 secp256k1 ,對 Windows 系統不友好,排除。
比對後使用:
holgern/pynostr: Python library for nostr
pip install pynostr[websocket-client]
完整代碼#
发布 Nostr Post 信息.py・GitHub,內容:
import json
import ssl
import time
import uuid
from pynostr.event import Event
from pynostr.relay_manager import RelayManager
from pynostr.filters import FiltersList, Filters
from pynostr.message_type import ClientMessageType
from pynostr.key import PrivateKey
relay_manager = RelayManager(timeout=6)
relay_manager.add_relay("wss://nostr-pub.wellorder.net")
relay_manager.add_relay("wss://relay.damus.io")
private_key = PrivateKey.from_nsec("你的私鑰")
filters = FiltersList([Filters(authors=[private_key.public_key.hex()], limit=100)])
subscription_id = uuid.uuid1().hex
relay_manager.add_subscription_on_all_relays(subscription_id, filters)
event = Event("字符串消息")
event.sign(private_key.hex())
relay_manager.publish_event(event)
relay_manager.run_sync()
time.sleep(5)
while relay_manager.message_pool.has_ok_notices():
ok_msg = relay_manager.message_pool.get_ok_notice()
print(ok_msg)
while relay_manager.message_pool.has_events():
event_msg = relay_manager.message_pool.get_event()
print(event_msg.event.to_dict())
參考#
聊聊 nostr 和 审查 | 酷 壳 - CoolShell
以及文中鏈接。