/** Returns true if the tx is a valid settlement transaction. */
 public synchronized boolean isSettlementTransaction(Transaction tx) {
   try {
     tx.verify();
     tx.getInput(0).verify(multisigContract.getOutput(0));
     return true;
   } catch (VerificationException e) {
     return false;
   }
 }
 /**
  * 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();
 }
Example #3
0
  @Test
  public void dataDrivenInvalidTransactions() throws Exception {
    BufferedReader in =
        new BufferedReader(
            new InputStreamReader(
                getClass().getResourceAsStream("tx_invalid.json"), Charset.forName("UTF-8")));

    NetworkParameters params = TestNet3Params.get();

    // Poor man's (aka. really, really poor) JSON parser (because pulling in a lib for this is
    // probably overkill)
    List<JSONObject> tx = new ArrayList<JSONObject>(1);
    in.read(); // remove first [
    StringBuffer buffer = new StringBuffer(1000);
    while (in.ready()) {
      String line = in.readLine();
      if (line == null || line.equals("")) continue;
      buffer.append(line);
      if (line.equals("]") && buffer.toString().equals("]") && !in.ready()) break; // ignore last ]
      boolean isFinished = appendToList(tx, buffer);
      while (tx.size() > 0
          && tx.get(0).isList()
          && tx.get(0).list.size() == 1
          && tx.get(0).list.get(0).isString()) tx.remove(0);
      if (isFinished && tx.size() == 1 && tx.get(0).list.size() == 3) {
        HashMap<TransactionOutPoint, Script> scriptPubKeys =
            new HashMap<TransactionOutPoint, Script>();
        for (JSONObject input : tx.get(0).list.get(0).list) {
          String hash = input.list.get(0).string;
          int index = input.list.get(1).integer;
          String script = input.list.get(2).string;
          Sha256Hash sha256Hash =
              new Sha256Hash(Hex.decode(hash.getBytes(Charset.forName("UTF-8"))));
          scriptPubKeys.put(
              new TransactionOutPoint(params, index, sha256Hash), parseScriptString(script));
        }

        byte[] bytes = tx.get(0).list.get(1).string.getBytes(Charset.forName("UTF-8"));
        Transaction transaction = new Transaction(params, Hex.decode(bytes));
        boolean enforceP2SH = tx.get(0).list.get(2).booleanValue;
        assertTrue(tx.get(0).list.get(2).isBoolean());

        boolean valid = true;
        try {
          transaction.verify();
        } catch (VerificationException e) {
          valid = false;
        }

        // The reference client checks this case in CheckTransaction, but we leave it to
        // later where we will see an attempt to double-spend, so we explicitly check here
        HashSet<TransactionOutPoint> set = new HashSet<TransactionOutPoint>();
        for (TransactionInput input : transaction.getInputs()) {
          if (set.contains(input.getOutpoint())) valid = false;
          set.add(input.getOutpoint());
        }

        for (int i = 0; i < transaction.getInputs().size() && valid; i++) {
          TransactionInput input = transaction.getInputs().get(i);
          assertTrue(scriptPubKeys.containsKey(input.getOutpoint()));
          try {
            input
                .getScriptSig()
                .correctlySpends(
                    transaction, i, scriptPubKeys.get(input.getOutpoint()), enforceP2SH);
          } catch (VerificationException e) {
            valid = false;
          }
        }

        if (valid) fail();

        tx.clear();
      }
    }
    in.close();
  }
Example #4
0
  @Test
  public void dataDrivenValidTransactions() throws Exception {
    BufferedReader in =
        new BufferedReader(
            new InputStreamReader(
                getClass().getResourceAsStream("tx_valid.json"), Charset.forName("UTF-8")));

    NetworkParameters params = TestNet3Params.get();

    // Poor man's (aka. really, really poor) JSON parser (because pulling in a lib for this is
    // probably not overkill)
    int lineNum = -1;
    List<JSONObject> tx = new ArrayList<JSONObject>(3);
    in.read(); // remove first [
    StringBuffer buffer = new StringBuffer(1000);
    while (in.ready()) {
      lineNum++;
      String line = in.readLine();
      if (line == null || line.equals("")) continue;
      buffer.append(line);
      if (line.equals("]") && buffer.toString().equals("]") && !in.ready()) break;
      boolean isFinished = appendToList(tx, buffer);
      while (tx.size() > 0
          && tx.get(0).isList()
          && tx.get(0).list.size() == 1
          && tx.get(0).list.get(0).isString()) tx.remove(0); // ignore last ]
      if (isFinished && tx.size() == 1 && tx.get(0).list.size() == 3) {
        Transaction transaction = null;
        try {
          HashMap<TransactionOutPoint, Script> scriptPubKeys =
              new HashMap<TransactionOutPoint, Script>();
          for (JSONObject input : tx.get(0).list.get(0).list) {
            String hash = input.list.get(0).string;
            int index = input.list.get(1).integer;
            String script = input.list.get(2).string;
            Sha256Hash sha256Hash =
                new Sha256Hash(Hex.decode(hash.getBytes(Charset.forName("UTF-8"))));
            scriptPubKeys.put(
                new TransactionOutPoint(params, index, sha256Hash), parseScriptString(script));
          }

          byte[] bytes = tx.get(0).list.get(1).string.getBytes(Charset.forName("UTF-8"));
          transaction = new Transaction(params, Hex.decode(bytes));
          boolean enforceP2SH = tx.get(0).list.get(2).booleanValue;
          assertTrue(tx.get(0).list.get(2).isBoolean());

          transaction.verify();

          for (int i = 0; i < transaction.getInputs().size(); i++) {
            TransactionInput input = transaction.getInputs().get(i);
            if (input.getOutpoint().getIndex() == 0xffffffffL) input.getOutpoint().setIndex(-1);
            assertTrue(scriptPubKeys.containsKey(input.getOutpoint()));
            input
                .getScriptSig()
                .correctlySpends(
                    transaction, i, scriptPubKeys.get(input.getOutpoint()), enforceP2SH);
          }
          tx.clear();
        } catch (Exception e) {
          System.err.println("Exception processing line " + lineNum + ": " + line);
          if (transaction != null) System.err.println(transaction);
          throw e;
        }
      }
    }
    in.close();
  }