private static UnsignedTransaction createUnsignedTransaction( long satoshisFromSeller, long satoshisForBuyer, Address buyerAddress, Address feeAddress, MbwManager mbwManager, SpendableOutputs spendable, PrivateKeyRing keyRing, NetworkParameters network) { Preconditions.checkArgument(satoshisForBuyer > TransactionUtils.MINIMUM_OUTPUT_VALUE); Preconditions.checkArgument(satoshisFromSeller >= satoshisForBuyer); long localTraderFee = satoshisFromSeller - satoshisForBuyer; // Construct list of spendable outputs List<UnspentTransactionOutput> outputs = new LinkedList<UnspentTransactionOutput>(); outputs.addAll(spendable.unspent); outputs.addAll(spendable.change); // Create unsigned empty transaction StandardTransactionBuilder stb = new StandardTransactionBuilder(network); // Add the outputs try { stb.addOutput(buyerAddress, satoshisForBuyer); if (localTraderFee >= TransactionUtils.MINIMUM_OUTPUT_VALUE) { stb.addOutput(feeAddress, localTraderFee); } } catch (OutputTooSmallException e) { // This should not happen as we have checked it above in a precondition Log.e("TradeActivityUtil", "Unexpected OutputTooSmallException exception"); return null; } // Create the unsigned transaction try { return stb.createUnsignedTransaction(outputs, null, keyRing, network); } catch (InsufficientFundsException e) { return null; } }
@Override public synchronized UnsignedTransaction createUnsignedTransaction( List<Receiver> receivers, long minerFeeToUse) throws OutputTooSmallException, InsufficientFundsException { checkNotArchived(); // Determine the list of spendable outputs Collection<UnspentTransactionOutput> spendable = transform(getSpendableOutputs()); // Create the unsigned transaction StandardTransactionBuilder stb = new StandardTransactionBuilder(_network); for (Receiver receiver : receivers) { stb.addOutput(receiver.address, receiver.amount); } Address changeAddress = getChangeAddress(); UnsignedTransaction unsigned = stb.createUnsignedTransaction( spendable, changeAddress, new PublicKeyRing(), _network, minerFeeToUse); return unsigned; }
@Override public synchronized long calculateMaxSpendableAmount(long minerFeeToUse) { checkNotArchived(); Collection<UnspentTransactionOutput> spendableOutputs = transform(getSpendableOutputs()); long satoshis = 0; for (UnspentTransactionOutput output : spendableOutputs) { satoshis += output.value; } // Iteratively figure out whether we can send everything by subtracting // the miner fee for every iteration while (true) { satoshis -= minerFeeToUse; if (satoshis <= 0) { return 0; } // Create transaction builder StandardTransactionBuilder stb = new StandardTransactionBuilder(_network); // Try and add the output try { // Note, null address used here, we just use it for measuring the // transaction size stb.addOutput(Address.getNullAddress(_network), satoshis); } catch (OutputTooSmallException e1) { // The amount we try to send is lower than what the network allows return 0; } // Try to create an unsigned transaction try { stb.createUnsignedTransaction( spendableOutputs, getChangeAddress(), new PublicKeyRing(), _network, minerFeeToUse); // We have enough to pay the fees, return the amount as the maximum return satoshis; } catch (InsufficientFundsException e) { // We cannot send this amount, try again with a little higher fee continue; } } }
/** * Check that the amount is large enough for the network to accept it, and that we have enough * funds to send it. */ private AmountValidation checkSendAmount(long satoshis) { // Create transaction builder StandardTransactionBuilder stb = new StandardTransactionBuilder(_mbwManager.getNetwork()); // Try and add the output try { // Note, null address used here, we just use it for measuring the // transaction size stb.addOutput(Address.getNullAddress(_mbwManager.getNetwork()), satoshis); } catch (OutputTooSmallException e1) { return AmountValidation.ValueTooSmall; } // Try to create an unsigned transaction try { stb.createUnsignedTransaction(_outputs, null, _privateKeyRing, _mbwManager.getNetwork()); } catch (InsufficientFundsException e) { return AmountValidation.NotEnoughFunds; } return AmountValidation.Ok; }