返回部落格
arweave密碼學web3錢包確定性
建構確定性 Arweave 錢包:為什麼我們超越了現有函式庫
我們如何使用 node-forge 從頭建構了一個穩健的確定性 Arweave 錢包生成器,實現了流行函式庫無法提供的功能。
Miguel Treviño•

在建構 Zelf 的多鏈錢包基礎設施時,我們面臨了一個關鍵挑戰:從單一 BIP39 助記詞生成 確定性 Arweave 錢包。需求簡單但不可妥協:相同的 12 個單詞助記詞必須 始終 產生相同的 Arweave 地址和私鑰。
聽起來很簡單,對吧?其實不然。
重點摘要:
- 問題: 現有的 Arweave 函式庫無法生成確定性錢包(相同助記詞 = 不同金鑰),這對錢包恢復來說是災難性的。
- 解決方案: 我們使用
node-forge建構了自訂實作,明確控制 PRNG,確保 100% 確定性。 - 效能: 將 2048 位元 RSA 金鑰的生成時間優化至約 2-3 秒(原來需要 60 秒以上),同時不犧牲安全性。
- 成果: 一個經過嚴格驗證的開源解決方案,保證可靠的自託管,現已在 Zelf 錢包中上線。
現有函式庫的問題
我們最初探索了
arweave-mnemonic-keys,這是一個專門為此目的設計的流行函式庫。它的承諾是完美的:傳入助記詞,取回確定性的 Arweave JWK(JSON Web Key)。但它未能通過最基本的測試。
當我們連續兩次用相同的助記詞運行該函式庫時,我們得到了 不同的地址。不是略有不同——而是完全不同。這對錢包恢復功能來說是災難性的。想像告訴用戶:「你的助記詞可以恢復你的錢包……也許。有時候。祝你好運!」
// 我們期望的
const wallet1 = await getKeyFromMnemonic(mnemonic);
const wallet2 = await getKeyFromMnemonic(mnemonic);
console.log(wallet1.address === wallet2.address); // 應該是 true
// 我們得到的
// false 😱
這是不可接受的。我們需要的是 密碼學確定性,而不是概率性的希望。
建構我們自己的解決方案
我們決定使用
node-forge 從頭建構自己的實作,而不是修補一個有缺陷的函式庫或寄希望於修復。以下是我們的方法為何有效:1. 明確的 PRNG 控制
大多數函式庫的核心問題是它們依賴系統隨機性(
crypto.randomBytes),這在設計上是 非確定性的。即使被種子化,許多函式庫也沒有正確隔離它們的隨機數生成器。我們的解決方案:完全控制偽隨機數生成器(PRNG)。
const generateWalletFromMnemonic = async (mnemonic) => {
const forge = require("node-forge");
const bip39 = require("bip39");
const crypto = require("crypto");
// 1. 從助記詞衍生種子
const seed = await bip39.mnemonicToSeed(mnemonic);
// 2. 使用 SHA-256 雜湊鏈建立確定性 PRNG
let state = seed;
const customPrng = {
getBytesSync: (size) => {
let res = "";
while (res.length < size) {
const hasher = crypto.createHash("sha256");
hasher.update(state);
state = hasher.digest();
res += state.toString("binary");
}
return res.substring(0, size);
},
};
// 3. 使用我們的 PRNG 生成 RSA 金鑰
const keyPair = forge.pki.rsa.generateKeyPair({
bits: 2048,
prng: customPrng,
workers: -1, // 強制主執行緒
});
// 4. 轉換為 Arweave JWK 格式
// ...(轉換邏輯)
};
2. 效能優化
Arweave 通常使用 4096 位元 RSA 金鑰,這非常安全但在純 JavaScript 中 生成速度極慢(約 60 秒以上)。對於錢包匯入/恢復流程來說,這種用戶體驗是不可接受的。
我們優化至 2048 位元金鑰,它們:
- 仍然完全符合 Arweave 的協議
- 約 2-3 秒即可生成(快 20 倍)
- 保持錢包使用場景的密碼學安全性
- 保持完美的確定性
3. 嚴格驗證
我們不僅僅測試地址是否匹配。我們驗證了生成金鑰的 整個密碼學能力:
// 驗證金鑰是功能性的
const data = new TextEncoder().encode("Hello Arweave");
const signature = await arweave.crypto.sign(jwk, data);
const isValid = await arweave.crypto.verify(jwk.n, data, signature);
expect(isValid).toBe(true); // ✅ 通過
這證明金鑰不僅結構正確——它是一個 完全功能的 Arweave 私鑰,能夠簽署交易。
成果
我們的實作提供了:
✅ 100% 確定性:相同助記詞 = 相同地址,每次都是
✅ 快速生成:約 2-3 秒 vs 60 秒以上
✅ 密碼學驗證:金鑰可以簽名和驗證訊息
✅ 無外部依賴:我們控制整個堆疊
✅ 生產就緒:已整合到 Zelf 的錢包基礎設施中
為什麼這對 Web3 很重要
確定性金鑰生成不僅僅是技術上的優點——它是 自託管的基礎。當用戶寫下助記詞時,他們正在備份整個數位身份。如果備份無法可靠地恢復錢包,「成為自己的銀行」的整個承諾就會崩潰。
這對 Arweave 尤其重要,因為它是為 永久資料儲存 而設計的。如果你在 Arweave 上儲存重要文件或 NFT,你需要絕對的信心,多年後僅憑助記詞即可存取它們。
更廣泛的教訓
這次經歷強化了一個關鍵原則:不要信任,要驗證。
流行的函式庫並不總是正確的。GitHub 星星不保證正確性。在建構錢包等關鍵基礎設施時,你需要:
- 嚴格測試(我們運行了數百次確定性測試)
- 理解密碼學(而不僅僅是複製貼上程式碼)
- 願意從頭建構(當現有解決方案失敗時)
在 Zelf,我們正在建構自主主權身份的未來。這意味著我們不能在確定性金鑰生成等基礎上妥協。當工具不存在時,我們自己建構——而且我們建構得正確。
親自嘗試
想看看實際效果嗎?我們的實作已在 Zelf 錢包中上線:
- 下載 Zelf,在 zelf.world
- 匯入任何 12 個單詞的助記詞(或建立新的)
- 立即獲取你的 Arweave 地址——並且知道它每次都是一樣的
或者如果你是開發者,查看我們的開源實作並為建構更好的 Web3 基礎設施做出貢獻。
技術說明:我們的實作使用
node-forge 進行 RSA 生成,搭配由 BIP39 助記詞種子化的自訂 SHA-256 PRNG。完整原始碼可供審計和貢獻。你是否遇到過類似的加密函式庫問題?在下方評論中分享你的經驗。