閃電 Zap 深度解析
Nostr 閃電 Zap 支付機制
Nostr 閃電網絡 Zaps 深度解析
概述
Zap 是 Nostr 生態系統中的打賞機制,允許用戶通過比特幣閃電網絡向內容創作者進行即時、小額的支付。Zap 結合了 Nostr 的去中心化社交協議和閃電網絡的高效支付能力,創造了一種新型的創作者經濟模式。
Zap 運作原理
整體流程
┌─────────────────────────────────────────────────────────────────┐
│ Zap 流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ 1. 發布筆記 ┌─────────┐ │
│ │ 創作者 │───────────────────►│ Nostr │ │
│ └─────────┘ (kind:1) └────┬────┘ │
│ │ │
│ ┌─────────┐ 2. 發起 Zap ┌────▼────┐ │
│ │ 粉絲 │───────────────────►│ Zap │ │
│ └─────────┘ (kind:9734) │ Request │ │
│ └────┬────┘ │
│ │ │
│ ┌─────────┐ 3. 生成發票 ┌────▼────┐ │
│ │ LN │◄──────────────────│ Zap │ │
│ │ Gateway │ (bolt11) │ Request │ │
│ └────┬────┘ └─────────┘ │
│ │ │
│ │ 4. 支付 │
│ ▼ │
│ ┌─────────┐ ┌─────────┐ │
│ │ 閃電 │───────────────────►│ LN │ │
│ │ 網絡 │ (支付路由) │ Gateway │ │
│ └─────────┘ └────┬────┘ │
│ │ │
│ ▼ 5. 確認 │
│ ┌─────────┐ │
│ │ Zap │ │
│ │ Receipt │ │
│ │ (kind:9735) │
│ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
技術實現
1. Zap Request(kind: 9734)
粉絲發起的 Zap 請求:
{
"kind": 9734,
"created_at": 1704067200,
"content": "Great post! ⚡️",
"tags": [
["p", "npub1creator..."], // 創作者公鑰
["e", "note1xxx..."], // 被 Zap 的筆記 ID
["amount", "1000"], // 金額(毫 satoshis)
["lnurl", "lnurl1..."], // LNURL
[" Bolt11", "lnbc10n..."] // 閃電發票(可選)
],
"pubkey": "npub1fan...",
"sig": "schnorr_signature..."
}
2. Zap Receipt(kind: 9735)
Zap 成功的收據:
{
"kind": 9735,
"created_at": 1704067201,
"content": "preimage_of_payment",
"tags": [
["e", "note1xxx..."], // 被 Zap 的筆記
["p", "npub1creator..."], // 創作者
["bolt11", "lnbc10n..."], // 發票
["preimage", "payment_preimage"], // 付款原像
["description", "Zap for note"],
["amount", "1000"]
],
"pubkey": "npub1zap...",
"sig": "schnorr_signature..."
}
3. LNURL 協議
LNURL 是 Zap 的核心組件:
import hashlib
import bech32
class LNURL:
def __init__(self, lud16_or_lnurl):
self.lud16_or_lnurl = lud16_or_lnurl
def encode(self, amount_msats):
"""
編碼 LNURL 為 Zap 請求 URL
"""
# 步驟 1: 創建服務器回調 URL
callback_url = f"https://zap.example.com/callback?amount={amount_msats}"
# 步驟 2: 壓縮並編碼為 bech32
# LNURL 使用特定的前綴
return bech32.encode('lnurl', compress_url(callback_url))
def decode(self, lnurl):
"""
解碼 LNURL
"""
# 移除 lnurl1 前綴
data = lnurl[4:]
# 解碼 bech32
decoded = bech32.decode('lnurl', data)
# 解壓縮 URL
return decompress_url(decoded)
4. 完整 Zap 流程代碼
class ZapProcessor:
def __init__(self, client, ln_node):
self.client = client
self.ln_node = ln_node
def process_zap(self, zap_request):
"""
處理 Zap 請求
"""
# 1. 解析 Zap 請求
recipient_pubkey = zap_request.get_tag('p')
event_id = zap_request.get_tag('e')
amount_msats = int(zap_request.get_tag('amount'))
# 2. 從 LNURL 獲取發票
lnurl = zap_request.get_tag('lnurl')
callback_url = LNURL.decode(lnurl)
invoice = self.request_invoice(
callback_url,
amount_msats,
event_id,
recipient_pubkey
)
# 3. 等待粉絲支付
payment = self.wait_for_payment(invoice['hash'])
# 4. 生成 Zap Receipt
receipt = self.create_receipt(
event_id,
recipient_pubkey,
invoice,
payment
)
# 5. 發布 Receipt
self.client.publish(receipt)
return receipt
Zap 類型
1. 筆記 Zap(Note Zaps)
直接對帖子進行打賞:
def create_note_zap(note_id, amount, content):
"""創建筆記 Zap"""
return {
'kind': 9734,
'content': content,
'tags': [
['e', note_id],
['amount', str(amount)]
]
}
2. 個人資料 Zap(Profile Zaps)
對用戶資料頁面進行打賞:
def create_profile_zap(pubkey, amount, message):
"""創建個人資料 Zap"""
return {
'kind': 9734,
'content': message,
'tags': [
['p', pubkey],
['amount', str(amount)]
]
}
3. 匿名 Zap(Anonymous Zaps)
不公開資助者身份:
def create_anonymous_zap(note_id, amount):
"""創建匿名 Zap"""
zap = create_note_zap(note_id, amount, "")
# 使用空的 pubkey 或特定標記
zap['pubkey'] = "anonymous"
return zap
閃電網關
1. 什麼是 Zap Gateway
Zap Gateway 是連接 Nostr 和閃電網絡的服務器:
┌─────────────┐ Zap Request ┌─────────────┐
│ Nostr │──────────────────────►│ Gateway │
│ Client │ │ │
└─────────────┘ └──────┬──────┘
│
┌─────────▼─────────┐
│ Lightning │
│ Network │
└───────────────────┘
2. 選擇 Gateway
| Gateway | 特性 | 費用 |
|---|---|---|
| Zap.store | 免費,開源 | 0% |
| LNtxBot | Telegram 集成 | 1% |
| Alby | 瀏覽器擴展 | 0% |
| ZBD | 遊戲/社交 | 2.5% |
3. 自托管 Gateway
# 自定義 Zap Gateway 示例
from flask import Flask, request
import ln_service
app = Flask(__name__)
@app.route('/callback', methods=['GET'])
def zap_callback():
amount = request.args.get('amount')
event_id = request.args.get('e')
pubkey = request.args.get('p')
# 生成閃電發票
invoice = ln_service.create_invoice(
amount_msats=int(amount),
description=f"Zap for {event_id}",
expiry=3600
)
return {
'pr': invoice.bolt11,
'disposable': True
}
@app.route('/webhook/ln', methods=['POST'])
def ln_webhook():
"""處理閃電網絡回調"""
payment = request.json
# 驗證付款
verify_payment(payment)
# 發布 Zap Receipt
publish_zap_receipt(payment)
return {'success': True}
經濟模型
1. 費用結構
┌─────────────────────────────────────────────────┐
│ Zap 費用 │
├─────────────────────────────────────────────────┤
│ │
│ 粉絲支付 ─────► Gateway ─────► 創作者 │
│ 1000 │ 950 │
│ 服務費 (5%) │
│ │
└─────────────────────────────────────────────────┘
2. 收益計算
def calculate_zap_earnings(zaps_received, gateway_fee_percent=5):
"""
計算 Zap 收入
"""
total_sats = sum(zap['amount'] for zap in zaps_received)
# 轉換為 satoshis (1 msat = 0.001 sat)
total_satoshis = total_sats / 1000
# 扣除費用
gateway_fee = total_satoshis * (gateway_fee_percent / 100)
net_earnings = total_satoshis - gateway_fee
return {
'gross': total_satoshis,
'fee': gateway_fee,
'net': net_earnings
}
3. 收益預期
| 粉絲數 | 平均 Zap | 月收入預估 |
|---|---|---|
| 100 | 50 sats | 1,500 sats |
| 1,000 | 50 sats | 15,000 sats |
| 10,000 | 50 sats | 150,000 sats |
安全考量
1. 隱私風險
| 風險 | 描述 | 緩解 |
|---|---|---|
| 支付路徑分析 | 節點運營商可追蹤 | 使用混音器 |
| LNURL 泄露 | URL 可能被監控 | HTTPS + 短期 |
| 接收者追蹤 | 創作者收入可見 | 合併輸出 |
2. 欺詐防護
class ZapValidator:
def validate_zap_request(self, zap_request):
"""
驗證 Zap 請求有效性
"""
# 1. 驗證簽名
if not verify_signature(zap_request):
return False, "Invalid signature"
# 2. 檢查金額範圍
amount = int(zap_request.get_tag('amount'))
if amount < 1 or amount > 100000000: # 1 sat - 100k sats
return False, "Invalid amount"
# 3. 驗證目標存在
if not self.verify_target_exists(zap_request):
return False, "Target not found"
return True, "Valid"
def verify_payment(self, payment, zap_request):
"""驗證支付是否完成"""
expected_amount = int(zap_request.get_tag('amount'))
return (
payment['amount'] >= expected_amount and
payment['status'] == 'completed'
)
3. 最佳實踐
- 使用知名 Gateway:選擇有良好聲譽的服務
- 驗證發票:確認發票金額和描述正確
- 小額測試:首次使用先小額測試
- 關注費用:選擇低費用的Gateway
集成開發
1. 客戶端集成
// 在客戶端實現 Zap
async function sendZap(event, amount, recipientPubkey) {
// 1. 獲取接收者的 LNURL
const profile = await getProfile(recipientPubkey);
const lnurl = profile.lud16 || profile.lnurl;
// 2. 解碼 LNURL
const callback = await decodeLNURL(lnurl);
// 3. 請求發票
const invoice = await fetch(callback + `?amount=${amount}&e=${event.id}`);
// 4. 發起支付
await window.webln.sendPayment(invoice.pr);
// 5. 發布 Zap Receipt
const zapReceipt = createZapReceipt(event, amount, invoice);
await publish(zapReceipt);
}
2. 創作者接入
# 創作者配置 LNURL
def create_lnurl_for_creator(pubkey):
"""
為創作者生成 LNURL
"""
# 方式 1: 使用服務(如 Alby)
alby_lnurl = f"https://getalby.com/lnurlp/{pubkey}"
# 方式 2: 自托管
# 需設置 LN 節點和 Zap Gateway
self_hosted_lnurl = f"https://your-domain.com/lnurl/{pubkey}"
return alby_lnurl
常見問題
1. Zap 失敗
| 原因 | 解決方案 |
|---|---|
| LNURL 無效 | 檢查配置是否正確 |
| 支付超時 | 增加發票過期時間 |
| 金額過小 | 提高最小金額限制 |
| 節點離線 | 更換 Gateway |
2. 費用過高
- 選擇費用較低的 Gateway
- 批量處理小額 Zap
- 考慮自托管
3. 隱私問題
- 使用匿名 Zap
- 避免公開收入
- 使用 Tor 連接
未來發展
1. 技術改進
- NIP-57 升級:更靈活的 Zap 選項
- 多貨幣支持:支持多種閃電資產
- 自動化:訂閱式 Zap
2. 生態擴展
- Zap 市場:付費內容平台
- 去中心化募資:Kickstarter 風格
- 訂閱服務:月度 Zap 訂閱
3. 與比特幣生態整合
- RGB 集成:代幣化 Zap
- BitVM:智能合約條件 Zap
總結
Zap 機制是 Nostr 生態中最具創新性的功能之一,它將比特幣 micropayment 的能力與去中心化社交網絡相結合。通過閃電網絡的即時結算和低成本,Zap 為內容創作者開闢了新的收入來源。雖然目前仍處於早期階段,但隨著工具和服務的成熟,Zap 有潛力成為互聯網內容創作的標準經濟模式。
風險提示
- 閃電網絡技術仍在發展中
- 支付失敗可能發生
- 隱私保護有限
- 監管政策不確定
- 建議僅使用可承受損失的金額
相關文章
- Nostr Zap 閃電支付 — 透過 Nostr Zap 实现内容变现与小费打赏。
- 閃電網路 Channels 詳解 — 深入理解 HTLC、通道狀態與流動性管理。
- 閃電網路路由機制完全指南 — 深入解析閃電網路的路由演算法、費用計算、流動性管理與隱私保護機制。
- 閃電網路費用計算完全指南 — 深入理解閃電費用結構,學習如何計算與優化費用。
- 閃電網路支付實戰:LNURLw 完整教學 — 深入理解 LNURLw 標準,包含 Channels.open()、Invoice.create() 等實際操作流程。
延伸閱讀與來源
這篇文章對您有幫助嗎?
請告訴我們如何改進:
0 人覺得有帮助
評論
發表評論
注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。
目前尚無評論,成為第一個發表評論的人吧!