/** 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(); }
@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(); }
@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(); }