Java 类org.bitcoinj.core.TransactionOutput 实例源码

项目:uidcore-java    文件:UniquidNodeStateUtils.java   
/**
 * Return true if the transaction in input is a valid imprinting transaction and contains the specified address in
 * one of its output, otherwise false.
 * @param tx the transaction to check if is valid imprinting
 * @param networkParameters the {@link NetworkParameters}
 * @param imprintingAddress the address to check for
 * @return true if it's an imprinting transaction otherwise false
 */
public static boolean isValidImprintingTransaction(Transaction tx, NetworkParameters networkParameters, Address imprintingAddress) {
    // Retrieve sender
    String sender = tx.getInput(0).getFromAddress().toBase58();

    // Check output
    List<TransactionOutput> transactionOutputs = tx.getOutputs();
    for (TransactionOutput to : transactionOutputs) {
        Address address = to.getAddressFromP2PKHScript(networkParameters);
        if (address != null && address.equals(imprintingAddress)) {
            return true;
        }
    }

    return false;
}
项目:xwallet    文件:WalletUtils.java   
@Nullable
public static Address getWalletAddressOfReceived(final Transaction tx, final Wallet wallet) {
    for (final TransactionOutput output : tx.getOutputs()) {
        try {
            if (output.isMine(wallet)) {
                final Script script = output.getScriptPubKey();
                return script.getToAddress(Constants.NETWORK_PARAMETERS, true);
            }
        } catch (final ScriptException x) {
            // swallow
        }
    }

    return null;
}
项目:okwallet    文件:Wallet.java   
/**
 * Marks all keys used in the transaction output as used in the wallet.
 * See {@link org.bitcoinj.wallet.DeterministicKeyChain#markKeyAsUsed(DeterministicKey)} for more info on this.
 */
private void markKeysAsUsed(Transaction tx) {
    keyChainGroupLock.lock();
    try {
        for (TransactionOutput o : tx.getOutputs()) {
            try {
                Script script = o.getScriptPubKey();
                if (script.isSentToRawPubKey()) {
                    byte[] pubkey = script.getPubKey();
                    keyChainGroup.markPubKeyAsUsed(pubkey);
                } else if (script.isSentToAddress()) {
                    byte[] pubkeyHash = script.getPubKeyHash();
                    keyChainGroup.markPubKeyHashAsUsed(pubkeyHash);
                } else if (script.isPayToScriptHash()) {
                    Address a = Address.fromP2SHScript(tx.getParams(), script);
                    keyChainGroup.markP2SHAddressAsUsed(a);
                }
            } catch (ScriptException e) {
                // Just means we didn't understand the output of this transaction: ignore it.
                log.warn("Could not parse tx output script: {}", e.toString());
            }
        }
    } finally {
        keyChainGroupLock.unlock();
    }
}
项目:okwallet    文件:Wallet.java   
@VisibleForTesting
boolean isTxConsistent(final Transaction tx, final boolean isSpent) {
    boolean isActuallySpent = true;
    for (TransactionOutput o : tx.getOutputs()) {
        if (o.isAvailableForSpending()) {
            if (o.isMineOrWatched(this)) isActuallySpent = false;
            if (o.getSpentBy() != null) {
                log.error("isAvailableForSpending != spentBy");
                return false;
            }
        } else {
            if (o.getSpentBy() == null) {
                log.error("isAvailableForSpending != spentBy");
                return false;
            }
        }
    }
    return isActuallySpent == isSpent;
}
项目:okwallet    文件:Wallet.java   
/**
 * Returns all the outputs that match addresses or scripts added via {@link #addWatchedAddress(Address)} or
 * {@link #addWatchedScripts(java.util.List)}.
 * @param excludeImmatureCoinbases Whether to ignore outputs that are unspendable due to being immature.
 */
public List<TransactionOutput> getWatchedOutputs(boolean excludeImmatureCoinbases) {
    lock.lock();
    keyChainGroupLock.lock();
    try {
        LinkedList<TransactionOutput> candidates = Lists.newLinkedList();
        for (Transaction tx : Iterables.concat(unspent.values(), pending.values())) {
            if (excludeImmatureCoinbases && !tx.isMature()) continue;
            for (TransactionOutput output : tx.getOutputs()) {
                if (!output.isAvailableForSpending()) continue;
                try {
                    Script scriptPubKey = output.getScriptPubKey();
                    if (!watchedScripts.contains(scriptPubKey)) continue;
                    candidates.add(output);
                } catch (ScriptException e) {
                    // Ignore
                }
            }
        }
        return candidates;
    } finally {
        keyChainGroupLock.unlock();
        lock.unlock();
    }
}
项目:okwallet    文件:Wallet.java   
/**
 * Returns the balance of this wallet as calculated by the provided balanceType.
 */
public Coin getBalance(BalanceType balanceType) {
    lock.lock();
    try {
        if (balanceType == BalanceType.AVAILABLE || balanceType == BalanceType.AVAILABLE_SPENDABLE) {
            List<TransactionOutput> candidates = calculateAllSpendCandidates(true, balanceType == BalanceType.AVAILABLE_SPENDABLE);
            CoinSelection selection = coinSelector.select(NetworkParameters.MAX_MONEY, candidates);
            return selection.valueGathered;
        } else if (balanceType == BalanceType.ESTIMATED || balanceType == BalanceType.ESTIMATED_SPENDABLE) {
            List<TransactionOutput> all = calculateAllSpendCandidates(false, balanceType == BalanceType.ESTIMATED_SPENDABLE);
            Coin value = Coin.ZERO;
            for (TransactionOutput out : all) value = value.add(out.getValue());
            return value;
        } else {
            throw new AssertionError("Unknown balance type");  // Unreachable.
        }
    } finally {
        lock.unlock();
    }
}
项目:okwallet    文件:Wallet.java   
/**
 * Returns the amount of bitcoin ever received via output. <b>This is not the balance!</b> If an output spends from a
 * transaction whose inputs are also to our wallet, the input amounts are deducted from the outputs contribution, with a minimum of zero
 * contribution. The idea behind this is we avoid double counting money sent to us.
 * @return the total amount of satoshis received, regardless of whether it was spent or not.
 */
public Coin getTotalReceived() {
    Coin total = Coin.ZERO;

    // Include outputs to us if they were not just change outputs, ie the inputs to us summed to less
    // than the outputs to us.
    for (Transaction tx: transactions.values()) {
        Coin txTotal = Coin.ZERO;
        for (TransactionOutput output : tx.getOutputs()) {
            if (output.isMine(this)) {
                txTotal = txTotal.add(output.getValue());
            }
        }
        for (TransactionInput in : tx.getInputs()) {
            TransactionOutput prevOut = in.getConnectedOutput();
            if (prevOut != null && prevOut.isMine(this)) {
                txTotal = txTotal.subtract(prevOut.getValue());
            }
        }
        if (txTotal.isPositive()) {
            total = total.add(txTotal);
        }
    }
    return total;
}
项目:okwallet    文件:Wallet.java   
/**
 * Returns a list of all outputs that are being tracked by this wallet either from the {@link UTXOProvider}
 * (in this case the existence or not of private keys is ignored), or the wallets internal storage (the default)
 * taking into account the flags.
 *
 * @param excludeImmatureCoinbases Whether to ignore coinbase outputs that we will be able to spend in future once they mature.
 * @param excludeUnsignable Whether to ignore outputs that we are tracking but don't have the keys to sign for.
 */
public List<TransactionOutput> calculateAllSpendCandidates(boolean excludeImmatureCoinbases, boolean excludeUnsignable) {
    lock.lock();
    try {
        List<TransactionOutput> candidates;
        if (vUTXOProvider == null) {
            candidates = new ArrayList<>(myUnspents.size());
            for (TransactionOutput output : myUnspents) {
                if (excludeUnsignable && !canSignFor(output.getScriptPubKey())) continue;
                Transaction transaction = checkNotNull(output.getParentTransaction());
                if (excludeImmatureCoinbases && !transaction.isMature())
                    continue;
                candidates.add(output);
            }
        } else {
            candidates = calculateAllSpendCandidatesFromUTXOProvider(excludeImmatureCoinbases);
        }
        return candidates;
    } finally {
        lock.unlock();
    }
}
项目:okwallet    文件:Wallet.java   
private void calcBloomOutPointsLocked() {
    // TODO: This could be done once and then kept up to date.
    bloomOutPoints.clear();
    Set<Transaction> all = new HashSet<>();
    all.addAll(unspent.values());
    all.addAll(spent.values());
    all.addAll(pending.values());
    for (Transaction tx : all) {
        for (TransactionOutput out : tx.getOutputs()) {
            try {
                if (isTxOutputBloomFilterable(out))
                    bloomOutPoints.add(out.getOutPointFor());
            } catch (ScriptException e) {
                // If it is ours, we parsed the script correctly, so this shouldn't happen.
                throw new RuntimeException(e);
            }
        }
    }
}
项目:okwallet    文件:Wallet.java   
private int estimateBytesForSigning(CoinSelection selection) {
    int size = 0;
    for (TransactionOutput output : selection.gathered) {
        try {
            Script script = output.getScriptPubKey();
            ECKey key = null;
            Script redeemScript = null;
            if (script.isSentToAddress()) {
                key = findKeyFromPubHash(script.getPubKeyHash());
                checkNotNull(key, "Coin selection includes unspendable outputs");
            } else if (script.isPayToScriptHash()) {
                redeemScript = findRedeemDataFromScriptHash(script.getPubKeyHash()).redeemScript;
                checkNotNull(redeemScript, "Coin selection includes unspendable outputs");
            }
            size += script.getNumberOfBytesRequiredToSpend(key, redeemScript);
        } catch (ScriptException e) {
            // If this happens it means an output script in a wallet tx could not be understood. That should never
            // happen, if it does it means the wallet has got into an inconsistent state.
            throw new IllegalStateException(e);
        }
    }
    return size;
}
项目:okwallet    文件:SendRequest.java   
/**
 * Construct a SendRequest for a CPFP (child-pays-for-parent) transaction. The resulting transaction is already
 * completed, so you should directly proceed to signing and broadcasting/committing the transaction. CPFP is
 * currently only supported by a few miners, so use with care.
 */
public static SendRequest childPaysForParent(Wallet wallet, Transaction parentTransaction, Coin feeRaise) {
    TransactionOutput outputToSpend = null;
    for (final TransactionOutput output : parentTransaction.getOutputs()) {
        if (output.isMine(wallet) && output.isAvailableForSpending()
                && output.getValue().isGreaterThan(feeRaise)) {
            outputToSpend = output;
            break;
        }
    }
    // TODO spend another confirmed output of own wallet if needed
    checkNotNull(outputToSpend, "Can't find adequately sized output that spends to us");

    final Transaction tx = new Transaction(parentTransaction.getParams());
    tx.addInput(outputToSpend);
    tx.addOutput(outputToSpend.getValue().subtract(feeRaise), wallet.freshAddress(KeyPurpose.CHANGE));
    tx.setPurpose(Transaction.Purpose.RAISE_FEE);
    final SendRequest req = forTx(tx);
    req.completed = true;
    return req;
}
项目:okwallet    文件:DefaultCoinSelector.java   
@Override
public CoinSelection select(Coin target, List<TransactionOutput> candidates) {
    ArrayList<TransactionOutput> selected = new ArrayList<>();
    // Sort the inputs by age*value so we get the highest "coindays" spent.
    // TODO: Consider changing the wallets internal format to track just outputs and keep them ordered.
    ArrayList<TransactionOutput> sortedOutputs = new ArrayList<>(candidates);
    // When calculating the wallet balance, we may be asked to select all possible coins, if so, avoid sorting
    // them in order to improve performance.
    // TODO: Take in network parameters when instanatiated, and then test against the current network. Or just have a boolean parameter for "give me everything"
    if (!target.equals(NetworkParameters.MAX_MONEY)) {
        sortOutputs(sortedOutputs);
    }
    // Now iterate over the sorted outputs until we have got as close to the target as possible or a little
    // bit over (excessive value will be change).
    long total = 0;
    for (TransactionOutput output : sortedOutputs) {
        if (total >= target.value) break;
        // Only pick chain-included transactions, or transactions that are ours and pending.
        if (!shouldSelect(output.getParentTransaction())) continue;
        selected.add(output);
        total += output.getValue().value;
    }
    // Total may be lower than target here, if the given candidates were insufficient to create to requested
    // transaction.
    return new CoinSelection(Coin.valueOf(total), selected);
}
项目:okwallet    文件:DefaultCoinSelector.java   
@VisibleForTesting static void sortOutputs(ArrayList<TransactionOutput> outputs) {
    Collections.sort(outputs, new Comparator<TransactionOutput>() {
        @Override
        public int compare(TransactionOutput a, TransactionOutput b) {
            int depth1 = a.getParentTransactionDepthInBlocks();
            int depth2 = b.getParentTransactionDepthInBlocks();
            Coin aValue = a.getValue();
            Coin bValue = b.getValue();
            BigInteger aCoinDepth = BigInteger.valueOf(aValue.value).multiply(BigInteger.valueOf(depth1));
            BigInteger bCoinDepth = BigInteger.valueOf(bValue.value).multiply(BigInteger.valueOf(depth2));
            int c1 = bCoinDepth.compareTo(aCoinDepth);
            if (c1 != 0) return c1;
            // The "coin*days" destroyed are equal, sort by value alone to get the lowest transaction size.
            int c2 = bValue.compareTo(aValue);
            if (c2 != 0) return c2;
            // They are entirely equivalent (possibly pending) so sort by hash to ensure a total ordering.
            BigInteger aHash = a.getParentTransactionHash().toBigInteger();
            BigInteger bHash = b.getParentTransactionHash().toBigInteger();
            return aHash.compareTo(bHash);
        }
    });
}
项目:coinblesk-client-gui    文件:WalletService.java   
private List<TransactionOutput> getUnlockedUnspentOutputs() {
    final List<TransactionOutput> outputs = new ArrayList<>();
    final List<TransactionOutput> candidates = wallet.calculateAllSpendCandidates(false, false);
    final long currentTimeSec = org.bitcoinj.core.Utils.currentTimeSeconds();
    for (TransactionOutput txOut : candidates) {
        byte[] addressHash = txOut.getScriptPubKey().getPubKeyHash();
        TimeLockedAddress tla = findTimeLockedAddressByHash(addressHash);
        if (tla != null) {
            long lockTime = tla.getLockTime();
            if (BitcoinUtils.isAfterLockTime(currentTimeSec, lockTime)) {
                outputs.add(txOut);
                Log.d(TAG, "getUnlockedUnspentOutputs - unlocked output: " + txOut);
            }
        }
    }
    return outputs;
}
项目:coinblesk-client-gui    文件:WalletService.java   
private List<TransactionSignature> signTransaction(Transaction tx) throws CoinbleskException {
    final List<TransactionInput> inputs = tx.getInputs();
    final List<TransactionSignature> signatures = new ArrayList<>(inputs.size());
    for (int i = 0; i < inputs.size(); ++i) {
        TransactionInput txIn = inputs.get(i);
        TransactionOutput prevTxOut = txIn.getConnectedOutput();
        byte[] sentToHash = prevTxOut.getScriptPubKey().getPubKeyHash();
        TimeLockedAddress tla = findTimeLockedAddressByHash(sentToHash);
        if (tla == null) {
            throw new CoinbleskException(String.format(Locale.US,
                    "Could not sign input (index=%d, pubKeyHash=%s)",
                    i, org.bitcoinj.core.Utils.HEX.encode(sentToHash)));
        }
        byte[] redeemScript = tla.createRedeemScript().getProgram();
        TransactionSignature signature = tx.calculateSignature(
                i, multisigClientKey, redeemScript, Transaction.SigHash.ALL, false);
        signatures.add(signature);
    }
    return signatures;
}
项目:coinblesk-client-gui    文件:TransactionDetailActivity.java   
private String sentToAddressOfTx(TransactionWrapper txWrapper) {
    // positive amount (for our wallet) = incoming tx
    boolean isIncoming = txWrapper.getAmount().isPositive();

    List<TransactionOutput> outputs = txWrapper.getTransaction().getOutputs();
    // due to space limitations we only display if we have a common 2 outputs tx
    if (outputs.size() <= 2) {
        for (TransactionOutput o : outputs) {
            // ignore:
            // tx to me, output not, i.e. change to sender
            // tx from me, output mine, i.e. change to me
            boolean cont = (isIncoming && !o.isMineOrWatched(walletServiceBinder.getWallet()))
                       || (!isIncoming &&  o.isMineOrWatched(walletServiceBinder.getWallet()));

            if (cont) {
                continue;
            }

            Address addr = o.getScriptPubKey().getToAddress(appConfig.getNetworkParameters());
            return addr.toBase58();
        }
    }

    return null;
}
项目:coinblesk-client-gui    文件:Outputs.java   
private synchronized  void refreshOutputs() {
    adapter.getItems().clear();
    adapter.getItems().addAll(walletServiceBinder.getUnspentInstantOutputs());
    Collections.sort(adapter.getItems(), new Comparator<TransactionOutput>() {
        @Override
        public int compare(TransactionOutput lhs, TransactionOutput rhs) {
            Sha256Hash lhsHash = lhs.getParentTransactionHash();
            Sha256Hash rhsHash = lhs.getParentTransactionHash();
            if (lhsHash != null && rhsHash != null) {
                int hashCmp = lhsHash.toString().compareTo(rhsHash.toString());
                if (hashCmp != 0) return hashCmp;
                else return Long.compare(lhs.getIndex(), rhs.getIndex());
            }
            else if (lhsHash != null) return -1;
            else if (rhsHash != null) return 1;
            else return 0;
        }
    });
    adapter.notifyDataSetChanged();
}
项目:cryptwallet    文件:Wallet.java   
/**
 * Marks all keys used in the transaction output as used in the wallet.
 * See {@link org.bitcoinj.wallet.DeterministicKeyChain#markKeyAsUsed(DeterministicKey)} for more info on this.
 */
private void markKeysAsUsed(Transaction tx) {
    keyChainGroupLock.lock();
    try {
        for (TransactionOutput o : tx.getOutputs()) {
            try {
                Script script = o.getScriptPubKey();
                if (script.isSentToRawPubKey()) {
                    byte[] pubkey = script.getPubKey();
                    keyChainGroup.markPubKeyAsUsed(pubkey);
                } else if (script.isSentToAddress()) {
                    byte[] pubkeyHash = script.getPubKeyHash();
                    keyChainGroup.markPubKeyHashAsUsed(pubkeyHash);
                } else if (script.isPayToScriptHash()) {
                    Address a = Address.fromP2SHScript(tx.getParams(), script);
                    keyChainGroup.markP2SHAddressAsUsed(a);
                }
            } catch (ScriptException e) {
                // Just means we didn't understand the output of this transaction: ignore it.
                log.warn("Could not parse tx output script: {}", e.toString());
            }
        }
    } finally {
        keyChainGroupLock.unlock();
    }
}
项目:cryptwallet    文件:Wallet.java   
@VisibleForTesting
boolean isTxConsistent(final Transaction tx, final boolean isSpent) {
    boolean isActuallySpent = true;
    for (TransactionOutput o : tx.getOutputs()) {
        if (o.isAvailableForSpending()) {
            if (o.isMineOrWatched(this)) isActuallySpent = false;
            if (o.getSpentBy() != null) {
                log.error("isAvailableForSpending != spentBy");
                return false;
            }
        } else {
            if (o.getSpentBy() == null) {
                log.error("isAvailableForSpending != spentBy");
                return false;
            }
        }
    }
    return isActuallySpent == isSpent;
}
项目:cryptwallet    文件:Wallet.java   
/**
 * Returns all the outputs that match addresses or scripts added via {@link #addWatchedAddress(Address)} or
 * {@link #addWatchedScripts(java.util.List)}.
 * @param excludeImmatureCoinbases Whether to ignore outputs that are unspendable due to being immature.
 */
public List<TransactionOutput> getWatchedOutputs(boolean excludeImmatureCoinbases) {
    lock.lock();
    keyChainGroupLock.lock();
    try {
        LinkedList<TransactionOutput> candidates = Lists.newLinkedList();
        for (Transaction tx : Iterables.concat(unspent.values(), pending.values())) {
            if (excludeImmatureCoinbases && !tx.isMature()) continue;
            for (TransactionOutput output : tx.getOutputs()) {
                if (!output.isAvailableForSpending()) continue;
                try {
                    Script scriptPubKey = output.getScriptPubKey();
                    if (!watchedScripts.contains(scriptPubKey)) continue;
                    candidates.add(output);
                } catch (ScriptException e) {
                    // Ignore
                }
            }
        }
        return candidates;
    } finally {
        keyChainGroupLock.unlock();
        lock.unlock();
    }
}
项目:cryptwallet    文件:Wallet.java   
/**
 * Returns the balance of this wallet as calculated by the provided balanceType.
 */
public Coin getBalance(BalanceType balanceType) {
    lock.lock();
    try {
        if (balanceType == BalanceType.AVAILABLE || balanceType == BalanceType.AVAILABLE_SPENDABLE) {
            List<TransactionOutput> candidates = calculateAllSpendCandidates(true, balanceType == BalanceType.AVAILABLE_SPENDABLE);
            CoinSelection selection = coinSelector.select(NetworkParameters.MAX_MONEY, candidates);
            return selection.valueGathered;
        } else if (balanceType == BalanceType.ESTIMATED || balanceType == BalanceType.ESTIMATED_SPENDABLE) {
            List<TransactionOutput> all = calculateAllSpendCandidates(false, balanceType == BalanceType.ESTIMATED_SPENDABLE);
            Coin value = Coin.ZERO;
            for (TransactionOutput out : all) value = value.add(out.getValue());
            return value;
        } else {
            throw new AssertionError("Unknown balance type");  // Unreachable.
        }
    } finally {
        lock.unlock();
    }
}
项目:cryptwallet    文件:Wallet.java   
/**
 * Returns the amount of bitcoin ever received via output. <b>This is not the balance!</b> If an output spends from a
 * transaction whose inputs are also to our wallet, the input amounts are deducted from the outputs contribution, with a minimum of zero
 * contribution. The idea behind this is we avoid double counting money sent to us.
 * @return the total amount of satoshis received, regardless of whether it was spent or not.
 */
public Coin getTotalReceived() {
    Coin total = Coin.ZERO;

    // Include outputs to us if they were not just change outputs, ie the inputs to us summed to less
    // than the outputs to us.
    for (Transaction tx: transactions.values()) {
        Coin txTotal = Coin.ZERO;
        for (TransactionOutput output : tx.getOutputs()) {
            if (output.isMine(this)) {
                txTotal = txTotal.add(output.getValue());
            }
        }
        for (TransactionInput in : tx.getInputs()) {
            TransactionOutput prevOut = in.getConnectedOutput();
            if (prevOut != null && prevOut.isMine(this)) {
                txTotal = txTotal.subtract(prevOut.getValue());
            }
        }
        if (txTotal.isPositive()) {
            total = total.add(txTotal);
        }
    }
    return total;
}
项目:cryptwallet    文件:Wallet.java   
/**
 * Returns a list of all outputs that are being tracked by this wallet either from the {@link UTXOProvider}
 * (in this case the existence or not of private keys is ignored), or the wallets internal storage (the default)
 * taking into account the flags.
 *
 * @param excludeImmatureCoinbases Whether to ignore coinbase outputs that we will be able to spend in future once they mature.
 * @param excludeUnsignable Whether to ignore outputs that we are tracking but don't have the keys to sign for.
 */
public List<TransactionOutput> calculateAllSpendCandidates(boolean excludeImmatureCoinbases, boolean excludeUnsignable) {
    lock.lock();
    try {
        List<TransactionOutput> candidates;
        if (vUTXOProvider == null) {
            candidates = new ArrayList<TransactionOutput>(myUnspents.size());
            for (TransactionOutput output : myUnspents) {
                if (excludeUnsignable && !canSignFor(output.getScriptPubKey())) continue;
                Transaction transaction = checkNotNull(output.getParentTransaction());
                if (excludeImmatureCoinbases && !transaction.isMature())
                    continue;
                candidates.add(output);
            }
        } else {
            candidates = calculateAllSpendCandidatesFromUTXOProvider(excludeImmatureCoinbases);
        }
        return candidates;
    } finally {
        lock.unlock();
    }
}
项目:cryptwallet    文件:Wallet.java   
private void calcBloomOutPointsLocked() {
    // TODO: This could be done once and then kept up to date.
    bloomOutPoints.clear();
    Set<Transaction> all = new HashSet<Transaction>();
    all.addAll(unspent.values());
    all.addAll(spent.values());
    all.addAll(pending.values());
    for (Transaction tx : all) {
        for (TransactionOutput out : tx.getOutputs()) {
            try {
                if (isTxOutputBloomFilterable(out))
                    bloomOutPoints.add(out.getOutPointFor());
            } catch (ScriptException e) {
                // If it is ours, we parsed the script correctly, so this shouldn't happen.
                throw new RuntimeException(e);
            }
        }
    }
}
项目:cryptwallet    文件:Wallet.java   
private int estimateBytesForSigning(CoinSelection selection) {
    int size = 0;
    for (TransactionOutput output : selection.gathered) {
        try {
            Script script = output.getScriptPubKey();
            ECKey key = null;
            Script redeemScript = null;
            if (script.isSentToAddress()) {
                key = findKeyFromPubHash(script.getPubKeyHash());
                checkNotNull(key, "Coin selection includes unspendable outputs");
            } else if (script.isPayToScriptHash()) {
                redeemScript = findRedeemDataFromScriptHash(script.getPubKeyHash()).redeemScript;
                checkNotNull(redeemScript, "Coin selection includes unspendable outputs");
            }
            size += script.getNumberOfBytesRequiredToSpend(key, redeemScript);
        } catch (ScriptException e) {
            // If this happens it means an output script in a wallet tx could not be understood. That should never
            // happen, if it does it means the wallet has got into an inconsistent state.
            throw new IllegalStateException(e);
        }
    }
    return size;
}
项目:cryptwallet    文件:SendRequest.java   
/**
 * Construct a SendRequest for a CPFP (child-pays-for-parent) transaction. The resulting transaction is already
 * completed, so you should directly proceed to signing and broadcasting/committing the transaction. CPFP is
 * currently only supported by a few miners, so use with care.
 */
public static SendRequest childPaysForParent(Wallet wallet, Transaction parentTransaction, Coin feeRaise) {
    TransactionOutput outputToSpend = null;
    for (final TransactionOutput output : parentTransaction.getOutputs()) {
        if (output.isMine(wallet) && output.isAvailableForSpending()
                && output.getValue().isGreaterThan(feeRaise)) {
            outputToSpend = output;
            break;
        }
    }
    // TODO spend another confirmed output of own wallet if needed
    checkNotNull(outputToSpend, "Can't find adequately sized output that spends to us");

    final Transaction tx = new Transaction(parentTransaction.getParams());
    tx.addInput(outputToSpend);
    tx.addOutput(outputToSpend.getValue().subtract(feeRaise), wallet.freshAddress(KeyPurpose.CHANGE));
    tx.setPurpose(Transaction.Purpose.RAISE_FEE);
    final SendRequest req = forTx(tx);
    req.completed = true;
    return req;
}
项目:cryptwallet    文件:DefaultCoinSelector.java   
@Override
public CoinSelection select(Coin target, List<TransactionOutput> candidates) {
    ArrayList<TransactionOutput> selected = new ArrayList<TransactionOutput>();
    // Sort the inputs by age*value so we get the highest "coindays" spent.
    // TODO: Consider changing the wallets internal format to track just outputs and keep them ordered.
    ArrayList<TransactionOutput> sortedOutputs = new ArrayList<TransactionOutput>(candidates);
    // When calculating the wallet balance, we may be asked to select all possible coins, if so, avoid sorting
    // them in order to improve performance.
    // TODO: Take in network parameters when instanatiated, and then test against the current network. Or just have a boolean parameter for "give me everything"
    if (!target.equals(NetworkParameters.MAX_MONEY)) {
        sortOutputs(sortedOutputs);
    }
    // Now iterate over the sorted outputs until we have got as close to the target as possible or a little
    // bit over (excessive value will be change).
    long total = 0;
    for (TransactionOutput output : sortedOutputs) {
        if (total >= target.value) break;
        // Only pick chain-included transactions, or transactions that are ours and pending.
        if (!shouldSelect(output.getParentTransaction())) continue;
        selected.add(output);
        total += output.getValue().value;
    }
    // Total may be lower than target here, if the given candidates were insufficient to create to requested
    // transaction.
    return new CoinSelection(Coin.valueOf(total), selected);
}
项目:cryptwallet    文件:DefaultCoinSelector.java   
@VisibleForTesting static void sortOutputs(ArrayList<TransactionOutput> outputs) {
    Collections.sort(outputs, new Comparator<TransactionOutput>() {
        @Override
        public int compare(TransactionOutput a, TransactionOutput b) {
            int depth1 = a.getParentTransactionDepthInBlocks();
            int depth2 = b.getParentTransactionDepthInBlocks();
            Coin aValue = a.getValue();
            Coin bValue = b.getValue();
            BigInteger aCoinDepth = BigInteger.valueOf(aValue.value).multiply(BigInteger.valueOf(depth1));
            BigInteger bCoinDepth = BigInteger.valueOf(bValue.value).multiply(BigInteger.valueOf(depth2));
            int c1 = bCoinDepth.compareTo(aCoinDepth);
            if (c1 != 0) return c1;
            // The "coin*days" destroyed are equal, sort by value alone to get the lowest transaction size.
            int c2 = bValue.compareTo(aValue);
            if (c2 != 0) return c2;
            // They are entirely equivalent (possibly pending) so sort by hash to ensure a total ordering.
            BigInteger aHash = a.getParentTransactionHash().toBigInteger();
            BigInteger bHash = b.getParentTransactionHash().toBigInteger();
            return aHash.compareTo(bHash);
        }
    });
}
项目:cryptwallet    文件:WalletTest.java   
@Test
public void isConsistent_duplicates() throws Exception {
    // This test ensures that isConsistent catches duplicate transactions, eg, because we submitted the same block
    // twice (this is not allowed).
    Transaction tx = createFakeTx(PARAMS, COIN, myAddress);
    TransactionOutput output = new TransactionOutput(PARAMS, tx, valueOf(0, 5), OTHER_ADDRESS);
    tx.addOutput(output);
    wallet.receiveFromBlock(tx, null, BlockChain.NewBlockType.BEST_CHAIN, 0);

    assertTrue(wallet.isConsistent());

    Transaction txClone = PARAMS.getDefaultSerializer().makeTransaction(tx.bitcoinSerialize());
    try {
        wallet.receiveFromBlock(txClone, null, BlockChain.NewBlockType.BEST_CHAIN, 0);
        fail("Illegal argument not thrown when it should have been.");
    } catch (IllegalStateException ex) {
        // expected
    }
}
项目:cryptwallet    文件:WalletTest.java   
@Test
public void transactions() throws Exception {
    // This test covers a bug in which Transaction.getValueSentFromMe was calculating incorrectly.
    Transaction tx = createFakeTx(PARAMS, COIN, myAddress);
    // Now add another output (ie, change) that goes to some other address.
    TransactionOutput output = new TransactionOutput(PARAMS, tx, valueOf(0, 5), OTHER_ADDRESS);
    tx.addOutput(output);
    // Note that tx is no longer valid: it spends more than it imports. However checking transactions balance
    // correctly isn't possible in SPV mode because value is a property of outputs not inputs. Without all
    // transactions you can't check they add up.
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, tx);
    // Now the other guy creates a transaction which spends that change.
    Transaction tx2 = new Transaction(PARAMS);
    tx2.addInput(output);
    tx2.addOutput(new TransactionOutput(PARAMS, tx2, valueOf(0, 5), myAddress));
    // tx2 doesn't send any coins from us, even though the output is in the wallet.
    assertEquals(ZERO, tx2.getValueSentFromMe(wallet));
}
项目:cryptwallet    文件:WalletTest.java   
@Test
public void bounce() throws Exception {
    // This test covers bug 64 (False double spends). Check that if we create a spend and it's immediately sent
    // back to us, this isn't considered as a double spend.
    Coin coin1 = COIN;
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, coin1);
    // Send half to some other guy. Sending only half then waiting for a confirm is important to ensure the tx is
    // in the unspent pool, not pending or spent.
    Coin coinHalf = valueOf(0, 50);
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
    assertEquals(1, wallet.getTransactions(true).size());
    Transaction outbound1 = wallet.createSend(OTHER_ADDRESS, coinHalf);
    wallet.commitTx(outbound1);
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, outbound1);
    assertTrue(outbound1.getWalletOutputs(wallet).size() <= 1); //the change address at most
    // That other guy gives us the coins right back.
    Transaction inbound2 = new Transaction(PARAMS);
    inbound2.addOutput(new TransactionOutput(PARAMS, inbound2, coinHalf, myAddress));
    assertTrue(outbound1.getWalletOutputs(wallet).size() >= 1);
    inbound2.addInput(outbound1.getOutputs().get(0));
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, inbound2);
    assertEquals(coin1, wallet.getBalance());
}
项目:thunder    文件:ToolsTest.java   
private static Transaction shuffleTransaction (Transaction transaction) {
    Transaction shuffledTransaction = new Transaction(Constants.getNetwork());

    List<TransactionInput> shuffledInputs = new ArrayList<>(transaction.getInputs());
    List<TransactionOutput> shuffledOutputs = new ArrayList<>(transaction.getOutputs());

    Collections.shuffle(shuffledInputs);
    Collections.shuffle(shuffledOutputs);
    for (TransactionInput input : shuffledInputs) {
        shuffledTransaction.addInput(input);
    }
    for (TransactionOutput output : shuffledOutputs) {
        shuffledTransaction.addOutput(output);
    }
    return shuffledTransaction;
}
项目:lbry-android    文件:TrimmedTransaction.java   
@Override
public TransactionOutput getOutput(int index) {
    checkIndex(index);

    if (trimmedOutputs == null) {
        return super.getOutput(index);
    } else {
        TransactionOutput output = trimmedOutputs.get(index);
        // Trimmed outputs are empty
        if (output == null) {
            return EmptyTransactionOutput.get();
        } else {
            return output;
        }
    }
}
项目:lbry-android    文件:TrimmedTransaction.java   
public List<TransactionOutput> getOutputs(boolean includeEmptyOutputs) {
    if (trimmedOutputs == null) {
        return super.getOutputs();
    } else {
        ImmutableList.Builder<TransactionOutput> listBuilder = ImmutableList.builder();
        TransactionOutput emptyOutput = EmptyTransactionOutput.get();
        for (int i = 0; i < numberOfOutputs; i++) {
            TransactionOutput output = trimmedOutputs.get(i);
            // Trimmed outputs are empty
            if (output == null && includeEmptyOutputs) {
                listBuilder.add(emptyOutput);
            } else if (output != null) {
                listBuilder.add(output);
            }
        }
        return listBuilder.build();
    }
}
项目:lbry-android    文件:BitTransaction.java   
@Nullable
public Value getRawTxFee(TransactionWatcherWallet wallet) {
    Preconditions.checkState(!isTrimmed, "Cannot get raw tx fee from a trimmed transaction");
    Value fee = type.value(0);
    for (TransactionInput input : tx.getInputs()) {
        TransactionOutPoint outPoint = input.getOutpoint();
        BitTransaction inTx = wallet.getTransaction(outPoint.getHash());
        if (inTx == null || !inTx.isOutputAvailable((int) outPoint.getIndex())) {
            return null;
        }
        TransactionOutput txo = inTx.getOutput((int) outPoint.getIndex());
        fee = fee.add(txo.getValue());
    }
    for (TransactionOutput output : getOutputs()) {
        fee = fee.subtract(output.getValue());
    }
    return fee;
}
项目:lbry-android    文件:TransactionWatcherWallet.java   
private void maybeUpdateBlockDepth(BitTransaction tx, boolean updateUtxoSet) {
    checkState(lock.isHeldByCurrentThread(), "Lock is held by another thread");
    if (tx.getConfidenceType() != BUILDING) return;
    int newDepth = lastBlockSeenHeight - tx.getAppearedAtChainHeight() + 1;
    if (newDepth > 1) {
        tx.setDepthInBlocks(newDepth);

        // Update unspent outputs
        if (updateUtxoSet) {
            for (TransactionOutput output : tx.getOutputs(false)) {
                OutPointOutput unspentOutput = unspentOutputs.get(TrimmedOutPoint.get(output));
                if (unspentOutput != null) {
                    unspentOutput.setDepthInBlocks(newDepth);
                }
            }
        }
    }
}
项目:lbry-android    文件:WalletPocketHDTest.java   
private Map<TrimmedOutPoint, OutPointOutput> getDummyUtxoSet() throws AddressMalformedException, JSONException {
    final HashMap<TrimmedOutPoint, OutPointOutput> unspentOutputs = new HashMap<>();

    for (int i = 0; i < statuses.length; i++) {
        BitAddress address = (BitAddress) DOGE.newAddress(addresses.get(i));
        JSONArray utxoArray = new JSONArray(unspent[i]);

        for (int j = 0; j < utxoArray.length(); j++) {
            JSONObject utxoObject = utxoArray.getJSONObject(j);
            //"[{\"tx_hash\": \"ef74da273e8a77e2d60b707414fb7e0ccb35c7b1b936800a49fe953195b1799f\", \"tx_pos\": 11, \"value\": 500000000, \"height\": 160267}]",
            TrimmedOutPoint outPoint = new TrimmedOutPoint(DOGE, utxoObject.getInt("tx_pos"),
                    new Sha256Hash(utxoObject.getString("tx_hash")));
            TransactionOutput output = new TransactionOutput(DOGE, null,
                    Coin.valueOf(utxoObject.getLong("value")), address);
            OutPointOutput utxo = new OutPointOutput(outPoint, output, false);
            unspentOutputs.put(outPoint, utxo);
        }
    }

    return unspentOutputs;
}
项目:ombuds-android    文件:WalletUtils.java   
@Nullable
public static Address getToAddressOfSent(final Transaction tx, final Wallet wallet)
{
    for (final TransactionOutput output : tx.getOutputs())
    {
        try
        {
            if (!output.isMine(wallet))
            {
                final Script script = output.getScriptPubKey();
                return script.getToAddress(Constants.NETWORK_PARAMETERS, true);
            }
        }
        catch (final ScriptException x)
        {
            // swallow
        }
    }

    return null;
}
项目:ombuds-android    文件:WalletUtils.java   
@Nullable
public static Address getWalletAddressOfReceived(final Transaction tx, final Wallet wallet)
{
    for (final TransactionOutput output : tx.getOutputs())
    {
        try
        {
            if (output.isMine(wallet))
            {
                final Script script = output.getScriptPubKey();
                return script.getToAddress(Constants.NETWORK_PARAMETERS, true);
            }
        }
        catch (final ScriptException x)
        {
            // swallow
        }
    }

    return null;
}
项目:Shufflepuff    文件:Bitcoin.java   
/**
 * Takes in a transaction and a private key and returns a signature (if possible)
 * as a Bytestring object.
 */
public Bytestring getSignature(org.bitcoinj.core.Transaction signTx, ECKey privKey) {

    org.bitcoinj.core.Transaction copyTx = signTx;

    for (int i = 0; i < copyTx.getInputs().size(); i++) {
        TransactionInput input = copyTx.getInput(i);
        TransactionOutput connectedOutput = input.getConnectedOutput();
        Sha256Hash hash = copyTx.hashForSignature(i, connectedOutput.getScriptPubKey(), org.bitcoinj.core.Transaction.SigHash.ALL, false);
        ECKey.ECDSASignature ecSig = privKey.sign(hash);
        TransactionSignature txSig = new TransactionSignature(ecSig, org.bitcoinj.core.Transaction.SigHash.ALL, false);
        byte[] originalScript = input.getScriptBytes().clone();
        Script inputScript = ScriptBuilder.createInputScript(txSig, ECKey.fromPublicOnly(privKey.getPubKey()));
        input.setScriptSig(inputScript);
        try {
            input.verify(connectedOutput);
            return new Bytestring(inputScript.getProgram());
        } catch (VerificationException e) {
            input.setScriptSig(this.bytestringToInputScript(new Bytestring(originalScript)));
        }
    }

    return null;
}