/** * Verifies that this input can spend the given output. Note that this input must be a part of a * transaction. Also note that the consistency of the outpoint will be checked, even if this input * has not been connected. * * @param output the output that this input is supposed to spend. * @throws ScriptException If the script doesn't verify. * @throws VerificationException If the outpoint doesn't match the given output. */ public void verify(TransactionOutput output) throws VerificationException { if (output.parent != null) { if (!getOutpoint().getHash().equals(output.getParentTransaction().getHash())) throw new VerificationException( "This input does not refer to the tx containing the output."); if (getOutpoint().getIndex() != output.getIndex()) throw new VerificationException("This input refers to a different output on the given tx."); } Script pubKey = output.getScriptPubKey(); int myIndex = getParentTransaction().getInputs().indexOf(this); getScriptSig().correctlySpends(getParentTransaction(), myIndex, pubKey); }
@Override public CoinSelection select(Coin target, List<TransactionOutput> candidates) { try { LinkedList<TransactionOutput> gathered = Lists.newLinkedList(); Coin valueGathered = Coin.ZERO; for (TransactionOutput output : candidates) { if (ignorePending && !isConfirmed(output)) continue; // Find the key that controls output, assuming it's a regular pay-to-pubkey or // pay-to-address output. // We ignore any other kind of exotic output on the assumption we can't spend it ourselves. final Script scriptPubKey = output.getScriptPubKey(); ECKey controllingKey; if (scriptPubKey.isSentToRawPubKey()) { controllingKey = wallet.findKeyFromPubKey(scriptPubKey.getPubKey()); } else if (scriptPubKey.isSentToAddress()) { controllingKey = wallet.findKeyFromPubHash(scriptPubKey.getPubKeyHash()); } else { log.info("Skipping tx output {} because it's not of simple form.", output); continue; } checkNotNull( controllingKey, "Coin selector given output as candidate for which we lack the key"); if (controllingKey.getCreationTimeSeconds() >= unixTimeSeconds) continue; // It's older than the cutoff time so select. valueGathered = valueGathered.add(output.getValue()); gathered.push(output); if (gathered.size() >= MAX_SIMULTANEOUS_INPUTS) { log.warn( "Reached {} inputs, going further would yield a tx that is too large, stopping here.", gathered.size()); break; } } return new CoinSelection(valueGathered, gathered); } catch (ScriptException e) { throw new RuntimeException( e); // We should never have problems understanding scripts in our wallet. } }