Nostr NIP-26 委託機制與以太坊錢包登入完整指南
Nostr(Notes and Other Stuff Transmitted by Relays)是一種去中心化的社交媒體協議,其設計理念是創建一個抗審查、簡潔的社交網絡。NIP-26 是 Nostr 協議中定義委託機制的核心規範,它允許用戶將帳號控制權委託給其他公鑰,同時保持撤銷權限。
Nostr NIP-26 委託機制與以太坊錢包登入完整指南
概述
Nostr(Notes and Other Stuff Transmitted by Relays)是一種去中心化的社交媒體協議,其設計理念是創建一個抗審查、簡潔的社交網絡。NIP-26 是 Nostr 協議中定義委託機制的核心規範,它允許用戶將帳號控制權委託給其他公鑰,同時保持撤銷權限。
這種委託機制與以太坊錢包系統的整合正在開創新的 Web3 身份認證範式——用戶可以使用以太坊錢包直接控制 Nostr 帳號,或者將社交帳號委託給可信的第三方運營商,而無需暴露私鑰。
本文深入解析 NIP-26 委託機制的技術原理、實現方式,以及與以太坊錢包登入系統的整合實踐,幫助開發者和用戶理解這一正在興起的去中心化身份解決方案。
一、Nostr 協議基礎
1.1 Nostr 核心概念
Nostr 是一種極簡的去中心化社交協議,其設計遵循以下核心原則:
簡潔性:
- 只有兩種基本類型:事件(events)和客戶端(clients)
- 中繼器(relays)是可選的訊息轉發節點
- 沒有複雜的共識機制
抗審查:
- 用戶通過公私鑰對控制帳號
- 訊息可以廣播到多個中繼器
- 沒有單一故障點
互通性:
- 所有客戶端使用相同的協議
- 用戶可以切換客戶端而不丟失粉絲
- 公鑰作為全局用戶 ID
1.2 Nostr 事件結構
Nostr 的核心數據單元是「事件」(Event):
{
"id": "<32 字節的事件 ID>",
"pubkey": "<32 字節的公鑰>",
"created_at": "<Unix 時間戳>",
"kind": "<事件類型>",
"tags": "<標籤數組>",
"content": "<訊息內容>",
"sig": "<事件的 Ed25519 簽名>"
}
常見事件類型(kind):
| kind 值 | 說明 |
|---|---|
| 0 | 用戶元數據(個人資料) |
| 1 | 短訊息(類似 Twitter 推文) |
| 2 | 推薦中繼器 |
| 3 | 關注列表 |
| 4 | 直接訊息(加密) |
| 5 | 刪除事件 |
| 6 | 轉發 |
| 7 | 點擊 |
| 8 | 報價 |
| 30023 | 長文內容 |
1.3 Nostr 密碼學基礎
Nostr 使用 Ed25519 橢圓曲線密碼學:
密鑰對:
- 私鑰:32 字節的隨機數
- 公鑰:通過私鑰派生(25519 曲線)
簽名:
- 每個事件包含 Ed25519 簽名
- 驗證簽名確保事件真實性
// 使用 nostr-tools 生成密鑰對
const { generatePrivateKey, getPublicKey, signEvent, verifySignature } = require('nostr-tools');
// 生成私鑰
const privateKey = generatePrivateKey();
// 派生公鑰
const publicKey = getPublicKey(privateKey);
// 創建事件
const event = {
pubkey: publicKey,
created_at: Math.floor(Date.now() / 1000),
kind: 1,
tags: [],
content: 'Hello Nostr!',
id: '',
sig: ''
};
// 計算事件 ID
event.id = sha256(JSON.stringify([0, event.pubkey, event.created_at, event.kind, event.tags, event.content]));
// 簽名
event.sig = signEvent(event, privateKey);
// 驗證
const isValid = verifySignature(event);
二、NIP-26 委託機制詳解
2.1 NIP-26 核心概念
NIP-26 定義了 Nostr 中的委託(delegation)機制,允許用戶將其帳號的控制權委託給另一個密鑰,同時保持隨時撤銷的能力。
委託的典型應用場景:
- 多設備同步:
- 在手機、平板、電腦上使用不同密鑰
- 主帳號委託權限給設備密鑰
- 帳號運營:
- 將社交帳號委託給專業運營團隊
- 團隊成員使用自己的密鑰發文
- 服務集成:
- 將帳號委託給第三方應用
- 應用可以代表用戶發布內容
- 安全隔離:
- 將發布權限委託給專用密鑰
- 主密鑰離線保存
2.2 委託結構
NIP-26 委託通過特殊的事件類型實現:
{
"kind": 0,
"created_at": 1234567890,
"tags": [
["delegation", "<delegator_pubkey>", "<conditions>", "<delegator_signature>"]
],
"content": "{\"name\": \"delegated_account\"}",
"pubkey": "<delegate_pubkey>",
"sig": "<delegate_signature>"
}
委託標籤結構:
["delegation", <委派人公鑰>, <條件>, <委派人簽名>]
條件(conditions):
條件決定了被委託人可以執行哪些操作:
kind=1
或
created_at>1672531200
或
kind=1&created_at>1672531200
2.3 委託實現原理
委派人(Delegator):
- 生成條件表達式
- 對條件表達式簽名
- 將簽名提供給被委託人
// 委派人創建委託
const delegationCondition = 'kind=1';
const delegationSig = signEvent(
{ content: delegationCondition, pubkey: delegatorPubKey },
delegatorPrivateKey
);
// 將委託授予被委託人
const delegationTag = [
'delegation',
delegatorPubKey,
delegationCondition,
delegationSig
];
被委託人(Delegate):
- 使用自己的私鑰對事件簽名
- 在事件中包含委託標籤
- 接收方驗證委託有效性
// 被委託人發布事件
const delegatedEvent = {
pubkey: delegatePubKey,
created_at: Math.floor(Date.now() / 1000),
kind: 1,
tags: [
['delegation', delegatorPubKey, 'kind=1', delegationSig]
],
content: 'Hello from delegated account!',
id: '',
sig: ''
};
// 使用被委託人的私鑰簽名
delegatedEvent.sig = signEvent(delegatedEvent, delegatePrivateKey);
2.4 委託驗證邏輯
客戶端驗證委託事件的流程:
function verifyDelegatedEvent(event) {
// 1. 查找委託標籤
const delegationTag = event.tags.find(t => t[0] === 'delegation');
if (!delegationTag) {
return { valid: false, reason: 'No delegation tag' };
}
const [_, delegatorPubkey, condition, delegatorSig] = delegationTag;
// 2. 驗證委派人簽名
const conditionMessage = { content: condition, pubkey: delegatorPubkey };
if (!verifySignature(conditionMessage, delegatorSig)) {
return { valid: false, reason: 'Invalid delegator signature' };
}
// 3. 解析並驗證條件
const eventConditions = parseConditions(event.kind, event.created_at);
if (!evaluateCondition(condition, eventConditions)) {
return { valid: false, reason: 'Conditions not met' };
}
// 4. 驗證被委託人簽名
if (!verifySignature(event, event.sig)) {
return { valid: false, reason: 'Invalid delegate signature' };
}
// 5. 確認被委託人公鑰有效
// (可選) 檢查被委託人是否在黑名單中
return { valid: true, delegator: delegatorPubkey };
}
function parseConditions(kind, created_at) {
return {
kind: kind,
created_at: created_at
};
}
function evaluateCondition(condition, eventConditions) {
// 簡化的條件評估
// 實際實現需要更複雜的解析器
const parts = condition.split('&');
for (const part of parts) {
if (part.startsWith('kind=')) {
const requiredKind = parseInt(part.split('=')[1]);
if (eventConditions.kind !== requiredKind) {
return false;
}
}
if (part.startsWith('created_at>')) {
const minTime = parseInt(part.split('>')[1]);
if (eventConditions.created_at <= minTime) {
return false;
}
}
}
return true;
}
2.5 委託的權限控制
時間限制:
// 設置時間限制的委託條件
const timeLimitedCondition = 'created_at>1672531200&created_at<1704067200';
// 只能在 2023 年內有效的委託
類型限制:
// 只允許發布短訊息
const kind1Only = 'kind=1';
// 只允許發布元數據
const metadataOnly = 'kind=0';
// 允許多種操作
const multiCondition = 'kind=0|kind=1|kind=30023';
組合限制:
// 複雜條件示例
const complexCondition = `
(kind=1 & created_at>1672531200)
| (kind=0 & created_at>1680307200)
| kind=30023
`;
三、以太坊錢包整合
3.1 整合架構概述
將以太坊錢包與 Nostr NIP-26 委託整合,可以實現:
- 以太坊登入 Nostr:
- 使用以太坊錢包簽名驗證身份
- 無需管理額外的 Ed25519 密鑰
- 帳號委託:
- 以太坊錢包作為委派人
- 將 Nostr 權限委託給服務或設備
- 跨平台身份:
- 統一的以太坊身份
- 多個 Nostr 帳號關聯
3.2 以太坊簽名驗證 Nostr
挑戰-回應機制:
Nostr 客戶端可以使用以太坊錢包進行身份驗證:
// 1. 客戶端生成挑戰
const challenge = generateRandomChallenge(); // "Please sign this message to authenticate: <random>"
// 2. 用戶使用以太坊錢包簽名
async function signInWithEthereum() {
const message = `Nostr Authentication\n\nChallenge: ${challenge}\n\nWallet: ${window.ethereum.selectedAddress}`;
const signature = await window.ethereum.request({
method: 'personal_sign',
params: [message, window.ethereum.selectedAddress]
});
// 3. 發送到服務器驗證
const response = await fetch('/api/auth/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
address: window.ethereum.selectedAddress,
signature,
challenge
})
});
return response.json();
}
// 4. 服務器驗證
async function verifyEthereumSignature(address, signature, challenge) {
const message = `Nostr Authentication\n\nChallenge: ${challenge}\n\nWallet: ${address}`;
const recoveredAddress = await ethers.utils.verifyMessage(message, signature);
return recoveredAddress.toLowerCase() === address.toLowerCase();
}
3.3 從以太坊密鑰派生 Nostr 公鑰
雖然以太坊使用 secp256k1 曲線,而 Nostr 使用 Ed25519,但可以通過以下方式實現整合:
方案一:消息派生:
// 從以太坊私鑰派生 Nostr 私鑰
const { utils } = require('ethers');
// 以太坊私鑰
const ethPrivateKey = "0x...";
// 使用確定性派生
const nostrPrivateKey = utils.keccak256(
utils.solidityKeccak256(
['string', 'bytes'],
['Nostr Key Derivation', ethPrivateKey]
)
);
// Nostr 公鑰
const nostrPublicKey = getPublicKey(nostrPrivateKey);
方案二:委託模式(推薦):
使用 NIP-26 委託,以太坊錢包作為委派人:
// 1. 生成 Nostr 設備密鑰(用於日常操作)
const devicePrivateKey = generatePrivateKey();
const devicePublicKey = getPublicKey(devicePrivateKey);
// 2. 以太坊錢包簽署委託條件
const delegationMessage = `Nostr Delegation\n\nDelegate: ${devicePublicKey}\nConditions: kind=1|kind=6|kind=7\nExpiry: 2027-01-01`;
const delegationSignature = await window.ethereum.request({
method: 'personal_sign',
params: [delegationMessage, window.ethereum.selectedAddress]
});
// 3. 設備密鑰可以使用委託發布內容
const delegatedEvent = {
pubkey: devicePublicKey,
created_at: Math.floor(Date.now() / 1000),
kind: 1,
tags: [
['delegation', ethAddress, 'kind=1|kind=6|kind=7', delegationSignature]
],
content: 'Posted from device with Ethereum delegation!',
id: '',
sig: ''
};
delegatedEvent.sig = signEvent(delegatedEvent, devicePrivateKey);
3.4 NIP-98 HTTP 授權
NIP-98 定義了通過 HTTP 頭進行 Nostr 身份驗證的標準:
// 使用 NIP-98 HTTP 授權發布事件
async function publishWithNIP98(event, privateKey) {
const eventJson = JSON.stringify(event);
const signature = signEvent(event, privateKey);
// 創建 HTTP 授權頭
const authHeader = btoa(JSON.stringify({
sig: signature,
key: event.pubkey
}));
const response = await fetch('https://nostr.example.com/notes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Nostr ${authHeader}`
},
body: eventJson
});
return response.json();
}
3.5 完整整合示例
以下是一個完整的以太坊錢包登入 Nostr 的實現架構:
// nostr-ethereum-integration.js
class NostrEthereumIntegrator {
constructor() {
this.ethereum = window.ethereum;
this.signer = null;
this.nostrPrivateKey = null;
this.nostrPublicKey = null;
this.delegationCondition = 'kind=1|kind=6';
this.delegationExpiry = Math.floor(new Date('2027-01-01').getTime() / 1000);
}
// 初始化
async initialize() {
if (!this.ethereum) {
throw new Error('Ethereum wallet not found');
}
// 連接錢包
const accounts = await this.ethereum.request({
method: 'eth_requestAccounts'
});
this.signer = accounts[0];
console.log('Connected:', this.signer);
}
// 登入流程
async login() {
// 1. 生成 Nostr 臨時密鑰
this.nostrPrivateKey = generatePrivateKey();
this.nostrPublicKey = getPublicKey(this.nostrPrivateKey);
// 2. 創建委託
const delegation = await this.createDelegation();
// 3. 存儲委託信息
await this.storeDelegation(delegation);
return {
nostrPublicKey: this.nostrPublicKey,
delegator: this.signer,
delegation
};
}
// 創建委託
async createDelegation() {
const condition = `${this.delegationCondition}&created_at<${this.delegationExpiry}`;
const message = `Nostr Delegation\n\nDelegator: ${this.signer}\nDelegate: ${this.nostrPublicKey}\nConditions: ${condition}`;
const signature = await this.ethereum.request({
method: 'personal_sign',
params: [message, this.signer]
});
return {
delegator: this.signer,
delegate: this.nostrPublicKey,
condition,
signature,
created_at: Math.floor(Date.now() / 1000)
};
}
// 發布事件(使用委託)
async publishEvent(kind, content, tags = []) {
const event = {
pubkey: this.nostrPublicKey,
created_at: Math.floor(Date.now() / 1000),
kind,
tags: [
['delegation',
this.signer,
this.delegationCondition,
(await this.createDelegation()).signature
],
...tags
],
content,
id: '',
sig: ''
};
event.id = sha256(JSON.stringify([
0, event.pubkey, event.created_at,
event.kind, event.tags, event.content
]));
event.sig = signEvent(event, this.nostrPrivateKey);
return event;
}
// 發布短訊息
async publishNote(content) {
return this.publishEvent(1, content);
}
// 發布元數據
async publishMetadata(metadata) {
return this.publishEvent(0, JSON.stringify(metadata));
}
}
// 使用示例
const integrator = new NostrEthereumIntegrator();
await integrator.initialize();
await integrator.login();
// 發布訊息
const note = await integrator.publishNote('Hello Nostr from Ethereum!');
console.log('Published:', note.id);
四、安全考量
4.1 委託安全風險
條件繞過:
- 委託條件可能被錯誤解析
- 實現需要嚴格的條件驗證
過度授權:
- 避免給予過寬的委託權限
- 最小權限原則
委託撤銷:
- 定期檢查委託狀態
- 及時撤銷不再需要的委託
4.2 以太坊錢包安全
簽名風險:
- 避免簽名未知或惡意消息
- 仔細檢查簽名內容
私鑰保護:
- Nostr 私鑰應妥善備份
- 考虑使用硬件錢包存儲
4.3 最佳實踐
委託管理:
安全委託清單:
- [ ] 設定明確的條件範圍
- [ ] 設定合理的過期時間
- [ ] 定期審查和更新委託
- [ ] 準備緊急撤銷機制
- [ ] 監控帳號活動
錢包安全:
錢包安全清單:
- [ ] 使用硬件錢包進行重要操作
- [ ] 啟用錢包的多重認證
- [ ] 定期備份錢包
- [ ] 驗證每個簽名請求
- [ ] 避免在公共場所使用錢包
五、主要應用與實現
5.1 Nostr 客戶端
支持 NIP-26 的主要 Nostr 客戶端:
| 客戶端 | 平台 | NIP-26 支持 | 以太坊登入 |
|---|---|---|---|
| Damus | iOS | 是 | 有限 |
| Amethyst | Android | 是 | 有限 |
| Snort | Web | 是 | 是 |
| Nostrgram | Web | 是 | 是 |
| Coracle | Web | 是 | 是 |
5.2 身份認證服務
提供以太坊-Nostr 整合的服務:
NIP-07 兼容錢包:
- 瀏覽器擴展錢包
- 類似 MetaMask 的 Nostr 版本
登入服務:
- Nostr Au
- Login with Nostr
- Ethereum + Nostr Bridge
5.3 開發工具
// 開發相關的 JavaScript 庫
const libraries = {
'nostr-tools': '核心 Nostr 功能',
'nostr-hooks': 'React Hooks',
'@nostr/ client': '客戶端庫',
'ether-signer-nostr': '以太坊簽名轉換'
};
六、未來發展趨勢
6.1 標準化進展
NIP 擴展:
- 更多的委託類型
- 更好的條件語法
- 更強的隱私保護
跨平台身份:
- 統一的身份標準
- 去中心化身份(DID)整合
- 的可移植聲譽系統
6.2 採用趨勢
增長驅動因素:
- 以太坊生態的龐大用戶群
- 對抗審查社交的需求
- Web3 身份統一
挑戰:
- 技術複雜度
- 用戶教育
- 生態協調
6.3 創新方向
ZK 證明整合:
- 隱私保護的身份驗證
- 零知識支持的委託
- 匿名帳號
社交恢復:
- 基於社交圖譜的恢復
- 多重委託機制
- 繼承規劃
七、結論
NIP-26 委託機制為 Nostr 帶來了靈活的權限控制能力,而以太坊錢包的整合則開創了 Web3 身份的新範式。通過理解這些技術的原理和實現方式,開發者可以構建更加安全、用戶友好的去中心化應用。
對於普通用戶而言,這些技術意味著:
- 更高的帳號安全性
- 更靈活的帳號管理
- 更統一的 Web3 身份體驗
隨著標準的成熟和工具的完善,基於 Nostr 和以太坊的去中心化身份將在 Web3 生態中發揮越來越重要的作用。
參考資源
- NIP-26 Specification. github.com/nostr-protocol/nips/blob/master/nip-0026.md
- NIP-07 Specification. github.com/nostr-protocol/nips/blob/master/nip-0007.md
- NIP-98 Specification. github.com/nostr-protocol/nips/blob/master/nip-0098.md
- Nostr Protocol Documentation. nostr.how
- nostr-tools Library. github.com/nostr-protocol/nostr-tools
延伸閱讀
去中心化身份
DeSoc 協議
錢包安全
相關文章
- 以太坊供應鏈應用完整指南:從概念到實踐的深度分析 — 供應鏈管理是全球經濟運作的命脈,從原材料採購到最終產品交付,每個環節都涉及複雜的信息流、資金流和物流。傳統的供應鏈系統長期面臨透明度不足、效率低下、欺詐風險和管理成本高昂等問題。這些痛點為區塊鏈技術,特別是以太坊,在供應鏈領域的應用創造了巨大的機會。
- 以太坊生態系地圖 — 深入解析以太坊技術與應用場景,提供完整的專業技術指南。
- 以太坊數據分析工具完整推薦指南 — 以太坊區塊鏈產生海量數據,從簡單的餘額查詢到複雜的交易模式分析,都需要專業的工具支持。對於 DeFi 研究者、量化交易員、項目開發者、以及普通的區塊鏈愛好者而言,掌握合適的數據分析工具是理解和利用以太坊生態的關鍵能力。本文系統性地介紹市場上的主要數據分析工具,涵蓋區塊瀏覽器、SQL 查詢平台、錢包標籤服務、專業分析平台等多個類別,幫助讀者根據自身需求選擇最適合的工具組合。
- 以太坊 Layer 2 遊戲應用深度解析:技術架構、經濟模型與實踐案例 — 以太坊 Layer 2 擴容方案的成熟正在徹底改變區塊鏈遊戲(GameFi)的發展格局。多年來,高 Gas 費用和緩慢的交易確認時間限制了區塊鏈遊戲的創新空間,玩家難以在以太坊主網上享受流暢的遊戲體驗。隨著 Arbitrum、Optimism、Base、zkSync Era、Starknet 等主流 Layer 2 解決方案的蓬勃發展,這些技術瓶頸正在被逐一突破。
- 以太坊 GameFi 完整指南:區塊鏈遊戲的技術架構、經濟模型與發展趨勢 — 遊戲產業正經歷一場由區塊鏈技術驅動的深刻變革。傳統遊戲中,虛擬資產歸遊戲開發商所有,玩家實際上只獲得使用權。然而,區塊鏈技術的引入徹底改變了這一格局——玩家可以真正擁有遊戲內資產(NFT),並且能夠在開放市場上自由交易。以太坊作為最大的智慧合約平台,其生態系統孕育了 Axie Infinity、Illuvium、The Sandbox、Decentraland 等知名區塊鏈遊戲,同時也是大多數鏈遊
延伸閱讀與來源
- Ethereum.org 以太坊官方入口
- EthHub 以太坊知識庫
這篇文章對您有幫助嗎?
請告訴我們如何改進:
評論
發表評論
注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。
目前尚無評論,成為第一個發表評論的人吧!