public void sweepKey(ECKey key, long fee, int accountId, JSONArray outputs) { mLogger.info("sweepKey starting"); mLogger.info("key addr " + key.toAddress(mParams).toString()); Transaction tx = new Transaction(mParams); long balance = 0; ArrayList<Script> scripts = new ArrayList<Script>(); try { for (int ii = 0; ii < outputs.length(); ++ii) { JSONObject output; output = outputs.getJSONObject(ii); String tx_hash = output.getString("tx_hash"); int tx_output_n = output.getInt("tx_output_n"); String script = output.getString("script"); // Reverse byte order, create hash. Sha256Hash hash = new Sha256Hash(WalletUtil.msgHexToBytes(tx_hash)); tx.addInput( new TransactionInput( mParams, tx, new byte[] {}, new TransactionOutPoint(mParams, tx_output_n, hash))); scripts.add(new Script(Hex.decode(script))); balance += output.getLong("value"); } } catch (JSONException e) { e.printStackTrace(); throw new RuntimeException("trouble parsing unspent outputs"); } // Compute balance - fee. long amount = balance - fee; mLogger.info(String.format("sweeping %d", amount)); // Figure out the destination address. Address to = mHDWallet.nextReceiveAddress(accountId); mLogger.info("sweeping to " + to.toString()); // Add output. tx.addOutput(BigInteger.valueOf(amount), to); WalletUtil.signTransactionInputs(tx, Transaction.SigHash.ALL, key, scripts); mLogger.info("tx bytes: " + new String(Hex.encode(tx.bitcoinSerialize()))); // mKit.peerGroup().broadcastTransaction(tx); broadcastTransaction(mKit.peerGroup(), tx); mLogger.info("sweepKey finished"); }
/** * Generates a Payment message based on the information in the PaymentRequest. Provide * transactions built by the wallet. If the PaymentRequest did not specify a payment_url, returns * null. * * @param txns list of transactions to be included with the Payment message. * @param refundAddr will be used by the merchant to send money back if there was a problem. * @param memo is a message to include in the payment message sent to the merchant. */ public @Nullable Protos.Payment getPayment( List<Transaction> txns, @Nullable Address refundAddr, @Nullable String memo) throws IOException { if (!paymentDetails.hasPaymentUrl()) return null; Protos.Payment.Builder payment = Protos.Payment.newBuilder(); if (paymentDetails.hasMerchantData()) payment.setMerchantData(paymentDetails.getMerchantData()); if (refundAddr != null) { Protos.Output.Builder refundOutput = Protos.Output.newBuilder(); refundOutput.setAmount(totalValue.longValue()); refundOutput.setScript( ByteString.copyFrom(ScriptBuilder.createOutputScript(refundAddr).getProgram())); payment.addRefundTo(refundOutput); } if (memo != null) { payment.setMemo(memo); } for (Transaction txn : txns) { txn.verify(); ByteArrayOutputStream o = new ByteArrayOutputStream(); txn.bitcoinSerialize(o); payment.addTransactions(ByteString.copyFrom(o.toByteArray())); } return payment.build(); }
private void processInMessage(JSONObject msg) throws Exception { long idx = msg.optLong("id", -1); Object id = msg.opt("id"); try { if (!msg.has("method")) { System.out.println("Unknown message: " + msg.toString()); return; } String method = msg.getString("method"); if (method.equals("server.version")) { JSONObject reply = new JSONObject(); reply.put("id", id); reply.put("result", "0.9"); reply.put("jelectrum", JELECTRUM_VERSION); version_info = msg.get("params").toString(); sendMessage(reply); } else if (method.equals("server.banner")) { JSONObject reply = new JSONObject(); reply.put("id", id); reply.put("result", "Jelectrum"); sendMessage(reply); } else if (method.equals("blockchain.headers.subscribe")) { // Should send this on each new block: // {"id": 1, "result": {"nonce": 3114737334, "prev_block_hash": // "000000000000000089e1f388af7cda336b6241b3f0b0ca36def7a8f22e44d39b", "timestamp": // 1387995813, "merkle_root": // "0debf5bd535624a955d229337a9bf3da5f370cc5a1f5fbee7261b0bdd0bd0f10", "block_height": // 276921, "version": 2, "bits": 419668748}} jelectrum.getElectrumNotifier().registerBlockchainHeaders(this, id, true); } else if (method.equals("blockchain.numblocks.subscribe")) { // Should send this on each new block: // {"id": 1, "result": {"nonce": 3114737334, "prev_block_hash": // "000000000000000089e1f388af7cda336b6241b3f0b0ca36def7a8f22e44d39b", "timestamp": // 1387995813, "merkle_root": // "0debf5bd535624a955d229337a9bf3da5f370cc5a1f5fbee7261b0bdd0bd0f10", "block_height": // 276921, "version": 2, "bits": 419668748}} jelectrum.getElectrumNotifier().registerBlockCount(this, id, true); } else if (method.equals("blockchain.address.get_history")) { // {"id": 29, "result": [{"tx_hash": // "fc054ede2383904323d9b54991693b9150bb1a0a7cd3c344afb883d3ffc093f4", "height": 274759}, // {"tx_hash": "9dc9363fe032e08630057edb61488fc8fa9910d8b21f02eb1b12ef2928c88550", "height": // 274709}]} JSONArray params = msg.getJSONArray("params"); String address = params.getString(0); jelectrum.getElectrumNotifier().sendAddressHistory(this, id, address); } else if (method.equals("blockchain.address.subscribe")) { // the result is // sha256(fc054ede2383904323d9b54991693b9150bb1a0a7cd3c344afb883d3ffc093f4:274759:7bb11e62ceb5c9e918d9de541ec8d5d215353c6bbf2fcb32b300ec641f3a0b3f:274708:) // tx:height:tx:height: // or null if no transactions JSONArray params = msg.getJSONArray("params"); String address = params.getString(0); subscription_count.getAndIncrement(); if (first_address == null) { first_address = address; } jelectrum.getElectrumNotifier().registerBlockchainAddress(this, id, true, address); } else if (method.equals("server.peers.subscribe")) { JSONObject reply = new JSONObject(); JSONArray lst = new JSONArray(); reply.put("id", id); reply.put("result", lst); sendMessage(reply); } else if (method.equals("blockchain.transaction.get")) { JSONObject reply = new JSONObject(); reply.put("id", id); JSONArray params = msg.getJSONArray("params"); Sha256Hash hash = new Sha256Hash(params.getString(0)); Transaction tx = jelectrum.getImporter().getTransaction(hash); if (tx == null) { reply.put("error", "unknown transaction"); } else { byte buff[] = tx.bitcoinSerialize(); reply.put("result", Util.getHexString(buff)); } sendMessage(reply); } else if (method.equals("blockchain.block.get_header")) { JSONObject reply = new JSONObject(); reply.put("id", id); JSONArray arr = msg.getJSONArray("params"); int height = arr.getInt(0); Sha256Hash block_hash = jelectrum.getBlockChainCache().getBlockHashAtHeight(height); StoredBlock blk = jelectrum.getDB().getBlockStoreMap().get(block_hash); JSONObject result = new JSONObject(); jelectrum.getElectrumNotifier().populateBlockData(blk, result); reply.put("result", result); sendMessage(reply); } else if (method.equals("blockchain.transaction.broadcast")) { JSONArray arr = msg.getJSONArray("params"); String hex = arr.getString(0); byte[] tx_data = new Hex().decode(hex.getBytes()); Transaction tx = new Transaction(jelectrum.getNetworkParameters(), tx_data); // jelectrum.getPeerGroup().broadcastTransaction(tx); JSONObject res = jelectrum.getBitcoinRPC().submitTransaction(hex); JSONObject reply = new JSONObject(); reply.put("id", id); reply.put("result", tx.getHash().toString()); sendMessage(reply); jelectrum.getImporter().saveTransaction(tx); } else if (method.equals("blockchain.transaction.get_merkle")) { JSONObject reply = new JSONObject(); reply.put("id", id); JSONArray arr = msg.getJSONArray("params"); Sha256Hash tx_hash = new Sha256Hash(arr.getString(0)); int height = arr.getInt(1); Sha256Hash block_hash = jelectrum.getBlockChainCache().getBlockHashAtHeight(height); Block blk = jelectrum .getDB() .getBlockMap() .get(block_hash) .getBlock(jelectrum.getNetworkParameters()); JSONObject result = Util.getMerkleTreeForTransaction(blk.getTransactions(), tx_hash); result.put("block_height", height); reply.put("result", result); sendMessage(reply); } else if (method.equals("blockchain.block.get_chunk")) { JSONObject reply = new JSONObject(); reply.put("id", id); JSONArray arr = msg.getJSONArray("params"); int index = arr.getInt(0); reply.put("result", jelectrum.getHeaderChunkAgent().getChunk(index)); sendMessage(reply); } else { jelectrum.getEventLog().log(connection_id + " - Unknown electrum method: " + method); System.out.println("Unknown method - " + method); JSONObject reply = new JSONObject(); reply.put("id", id); reply.put("error", "unknown method - " + method); sendMessage(reply); } } catch (Throwable t) { JSONObject reply = new JSONObject(); reply.put("id", id); reply.put("error", "Exception: " + t); sendMessage(reply); jelectrum.getEventLog().log(connection_id + " - error: " + t); jelectrum.getEventLog().log(t); // t.printStackTrace(); } }