Wallet

使用 bcoin 創建一個多重簽名錢包並接收交易

  • July 16, 2019

我正在嘗試從兩個外部生成的 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 地址。如果你執行它,你應該看到所有三個輸出地址都是相同的。

要使此腳本正常工作,您需要了解以下幾點:

  1. 要從 中創建 bcoin 錢包,xpub您必須將錢包初始化為watch-only。否則該account-key選項將被忽略,並為錢包生成一個新的主私鑰。
  2. 多重簽名腳本中使用的公鑰必須來自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);
})();

引用自:https://bitcoin.stackexchange.com/questions/89028