Beispiel #1
0
  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();
    }
  }