Bitcoinj
我正在努力為比特幣錢包應用程序添加多錢包支持,但現在餘額不再更新
我使用比特幣錢包應用程序,使用者界面看起來,
當我從下拉菜單中選擇一個地址並按下
balance
或transaction
按鈕時,它們應該在新頁面中打開並顯示相應的資訊。當我在某個錢包中收到 BTC 時,它應該
balance
在活動頁面中更新錢包的 BTC。但是,它沒有按預期工作,我一如既往地只有 0 BTC。以前,它只是一個錢包(不支持多錢包),那時相同的程式碼可以正常工作。設置錢包的類,
public class WalletManager { public static WalletAppKit bitcoin; private static WalletManager walletManager; // public static NetworkParameters networkParameters = MainNetParams.get(); public static NetworkParameters networkParameters = TestNet3Params.get(); public static final String APP_NAME = "WalletTemplate"; public static final String WALLET_FILE_NAME = APP_NAME.replaceAll("[^a-zA-Z0-9.-]", "_") + networkParameters.getPaymentProtocolId(); private static final Logger logger = LoggerFactory.getLogger(WalletManager.class); private WalletModel model = new WalletModel(); private List<WalletSetupCompletedListener> setupCompletedListeners = Collections.synchronizedList(new LinkedList<>()); public static WalletManager setupWallet(final String walletName) { logger.info("Setup Wallet"); walletManager = new WalletManager(); walletManager.setupWalletKit(walletName); try { if (walletManager.bitcoin.isChainFileLocked()) { return walletManager; } } catch (IOException e) { e.printStackTrace(); return walletManager; } walletManager.bitcoin.startAsync(); return walletManager; } private WalletManager() {} protected File getWalletDirectory(final String walletId) { File dir = new File(walletId); if (!dir.exists()) { dir.mkdir(); } return dir; } private void setupWalletKit(final String walletId) { File directory = getWalletDirectory(walletId); // if the seed is not null, that means we are restoring from the backup bitcoin = new WalletAppKit(networkParameters, directory, WALLET_FILE_NAME) { @Override protected void onSetupCompleted() { // Don't make the user wait for confirmations // they're sending their own money anyway!! bitcoin.wallet().allowSpendingUnconfirmedTransactions(); Wallet wallet = bitcoin.wallet(); model.setWallet(wallet); setupCompletedListeners.forEach(listener -> listener.onSetupCompleted(wallet)); } }; // Now configure and start the appkit. This will take a second or two - we could show a temporary splash screen // or progress widget to keep the user engaged whilst we initialise, but we don't. if (networkParameters == RegTestParams.get()) { bitcoin.connectToLocalHost(); // You should run a regtest mode bitcoind locally. } else if (networkParameters == TestNet3Params.get()) { bitcoin.useTor(); } bitcoin.setDownloadListener(model.getSyncProgressUpdater()) .setBlockingStartup(false) .setUserAgent(APP_NAME, "1.0"); } public WalletAppKit getWalletAppKit() { return bitcoin; } public WalletModel getModel() { return model; } public void addWalletSetupCompletedListener(final WalletSetupCompletedListener listener) { setupCompletedListeners.add(listener); } }
下面提供了負責錢包更新的類,
public class WalletModel { private List<Transaction> transactions = Collections.synchronizedList(new ArrayList<>()); private ProgressBarUpdater syncProgressUpdater = new ProgressBarUpdater(); private static double SYNCHRONISATION_FINISHED = 1.0; private double syncProgress = -1.0; private Coin balance = Coin.ZERO; private Address address; private String transaction; private int UserId; public int getUserId() { return UserId; } public void setUserId(int userId) { this.UserId = userId; } public String getTransaction() { return transaction; } public void setTransaction(String transaction) { this.transaction = transaction; } private List<String> history = new ArrayList<>(); public List<String> getHistory() { for (Transaction t : transactions) { history.add(addTransactionHistory(t)); } return history; } public WalletModel() { } public WalletModel(Wallet wallet) { setWallet(wallet); } private void update(Wallet wallet) { this.balance = wallet.getBalance(); this.address = wallet.currentReceiveAddress(); transactions.addAll(wallet.getRecentTransactions(100, true)); this.transaction = Objects.isNull(transactions) || transactions.isEmpty() ? "" : String.valueOf(transactions.get(0)); } public boolean setWallet(Wallet wallet) { try { wallet.addChangeEventListener(new WalletChangeEventListener() { @Override public void onWalletChanged(Wallet wallet) { update(wallet); } }); update(wallet); return true; } catch (Exception e) { e.printStackTrace(); } return false; } private class ProgressBarUpdater extends DownloadProgressTracker { @Override protected void progress(double percentage, int blocksSoFar, Date date) { super.progress(percentage, blocksSoFar, date); syncProgress = percentage / 100.0; } @Override protected void doneDownload() { super.doneDownload(); syncProgress = SYNCHRONISATION_FINISHED; } } public boolean isSyncFinished() { return syncProgress == SYNCHRONISATION_FINISHED; } public Address getAddress() { return address; } /** * @param * @return the Satoshi coin based on the wallet balance */ public Coin getBalance() { return balance; } /** * @return get the BTC amount as float from the wallet balance */ public float getBalanceFloatFormat() { float bal = (float) balance.getValue(); float fac = (float) Math.pow(10, 8); float result = bal / fac; return result; } /** * @param transaction take the wallet transaction as an input * @return the trasaction info of the wallet */ private String addTransactionHistory(Transaction transaction) { if (Objects.isNull(transaction)) { return "No transaction"; } Coin value = transaction.getValue(WalletManager.bitcoin.wallet()); if (value.isPositive()) { String message = "Incoming payment of " + MonetaryFormat.BTC.format(value); return message; } else if (value.isNegative()) { Address address = transaction.getOutput(0).getAddressFromP2PKHScript(networkParameters); String message = "Outbound payment to " + address + " worth of " + (MonetaryFormat.BTC.format(value)).toString().replaceAll("-", ""); return message; } String message = "Payment with id " + transaction.getHash(); return message; } public double getSyncProgress() { return syncProgress; } public ProgressBarUpdater getSyncProgressUpdater() { return syncProgressUpdater; } public List<Transaction> getTransactions() { return transactions; } } public interface WalletSetupCompletedListener { void onSetupCompleted(Wallet wallet); }
如何設計程式碼以支持多個錢包?如果需要,我可以提供截斷的程式碼。
如果您使用了 useTor(),則刪除 else 塊,它根本不需要