Wallet
使用 bcoin 創建一個多重簽名錢包並接收交易
我正在嘗試從兩個外部生成的 xpub 創建一個多重簽名錢包。我正在採取的過程是使用兩個 xpub 創建兩個多重簽名錢包,將彼此的密鑰添加為共享密鑰,並使用密鑰環生成多重簽名腳本。但是,當我將測試網硬幣發送到
base58addr
我最終生成的那個時,我沒有看到它進入我的任何一個錢包。有人可以幫我找出我做錯了什麼嗎?這是我的程式碼:const wallet1_accountKey = "tpubDCe8iQEHFMvcm9WZsYZEd8h9dNvoDidS3y9EVkDzZZr59NcNF2n8ecfZWQkttDp6PWujaCUcXrptSoTKUuYjXp8fMKsz3wJvYpnpxsMQUbD" const wallet2_accountKey = "tpubDDQHqrK6Xj7A9tfW2zkiZiBPs475QJ8EQ5obViboBxgA1BG5Ai1BnPqBWKTVf6ecEi8XoKK9WQP7GK5jYgdjaoegqBH1EvhVCx2PLc3Zgru" const type='multisig' const options_wallet1 = { ... }; const options_wallet2 = { ... }; const result1 = await walletClient.createWallet('wallet1', options_wallet1); const result2 = await walletClient.createWallet('wallet2', options_wallet2); // ADDING SHARED KEYS const wallet1 = walletClient.wallet('wallet1'); const wallet2 = walletClient.wallet('wallet2'); const wallet1_account = await wallet1.getAccount('default'); const result3 = await wallet2.addSharedKey('default', wallet1_account.accountKey); const wallet2_account = await wallet6.getAccount('default'); const result4 = await wallet1.addSharedKey('default', wallet2_account.accountKey); // GENERATING P2SH WITH KEYRINGS const wallet1_address = await wallet1.createAddress('default'); const wallet2_address = await wallet2.createAddress('default'); const ring1 = KeyRing.fromJSON(wallet1_address); const ring2 = KeyRing.fromJSON(wallet2_address); const pubKeys = [ring1.publicKey, ring2.publicKey]; const multiSigScript = Script.fromMultisig(m, n, pubKeys); const base58addr = multiSigScript.getAddress().toBase58('testnet');
關於 BIP32/BIP44 密鑰派生,尤其是 bcoin 錢包的使用,可能存在一些誤解。我在下面重新編寫了您的腳本,以展示如何使用 bcoin 多重簽名錢包並從密鑰中手動派生多重簽名 P2SH 地址。如果你執行它,你應該看到所有三個輸出地址都是相同的。
要使此腳本正常工作,您需要了解以下幾點:
- 要從 中創建 bcoin 錢包,
xpub
您必須將錢包初始化為watch-only
。否則該account-key
選項將被忽略,並為錢包生成一個新的主私鑰。- 多重簽名腳本中使用的公鑰必須來自xpub(參見 BIP32 和 BIP44)。在這種情況下,您需要派生分支鍵(0=receive,1=change),然後從那裡派生索引鍵(在這種情況下為 0,每次需要新的接收地址時遞增)
如果您對 bcoin 有任何其他問題,請告訴我!
'use strict'; const {WalletDB, HDPublicKey, Script} = require('bcoin'); const wdb = new WalletDB({ network: 'testnet' }); const key1 = 'tpubDCe8iQEHFMvcm9WZsYZEd8h9dNvoDidS3y9EVkDzZZr59NcNF2n8ec' + 'fZWQkttDp6PWujaCUcXrptSoTKUuYjXp8fMKsz3wJvYpnpxsMQUbD'; const key2 = 'tpubDDQHqrK6Xj7A9tfW2zkiZiBPs475QJ8EQ5obViboBxgA1BG5Ai1BnP' + 'qBWKTVf6ecEi8XoKK9WQP7GK5jYgdjaoegqBH1EvhVCx2PLc3Zgru'; (async() => { await wdb.open(); // Create two watch-only multisig wallets const wallet1 = await wdb.create({ m: 2, n: 2, watchOnly: true, accountKey: key1 }); const wallet2 = await wdb.create({ m: 2, n: 2, watchOnly: true, accountKey: key2 }); // Add xpubs to each other's wallet's default account await wallet1.addSharedKey('default', key2); await wallet2.addSharedKey('default', key1); // Get receive address index=0 from each wallet const addr1 = await wallet1.receiveAddress(); const addr2 = await wallet2.receiveAddress(); // They will be the same console.log(addr1.toBase58('testnet')); console.log(addr2.toBase58('testnet')); // Now do it all manually... // Create HDPublicKey objects from xpubs const xpub1 = HDPublicKey.fromBase58(key1); const xpub2 = HDPublicKey.fromBase58(key2); // Derive public keys for each xpub (branch=0, index=0) const pubKey1 = xpub1.derive(0).derive(0); const pubKey2 = xpub2.derive(0).derive(0); // Construct multisig script with 2 pubkeys const script = Script.fromMultisig( 2, 2, [pubKey1.publicKey, pubKey2.publicKey]); // Create P2SH address from script const addr3 = script.getAddress().toString('testnet'); // Will match the first two results console.log(addr3); })();