@Override public Transaction signTransaction(UnsignedTransaction unsigned, KeyCipher cipher) throws InvalidKeyCipher { checkNotArchived(); if (!isValidEncryptionKey(cipher)) { throw new InvalidKeyCipher(); } // Make all signatures, this is the CPU intensive part List<byte[]> signatures = StandardTransactionBuilder.generateSignatures( unsigned.getSignatureInfo(), new PrivateKeyRing(cipher)); // Apply signatures and finalize transaction Transaction transaction = StandardTransactionBuilder.finalizeTransaction(unsigned, signatures); return transaction; }
@Override public UnsignedTransaction createUnsignedTransaction(OutputList outputs, 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); stb.addOutputs(outputs); 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; } } }
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; } }
/** * 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; }
public static Transaction createSignedTransaction(TradeSession ts, MbwManager mbwManager) { Preconditions.checkNotNull(ts.buyerAddress); // Create default wallet Wallet wallet = mbwManager.getRecordManager().getWallet(mbwManager.getWalletMode()); // Get spendable outputs SpendableOutputs spendable = wallet.getLocalSpendableOutputs(mbwManager.getBlockChainAddressTracker()); // Extract private key ring PrivateKeyRing keyRing = wallet.getPrivateKeyRing(); // Create unsigned transaction UnsignedTransaction unsigned = createUnsignedTransaction( ts.satoshisFromSeller, ts.satoshisForBuyer, ts.buyerAddress, ts.feeAddress, mbwManager, spendable, keyRing, mbwManager.getNetwork()); if (unsigned == null) { return null; } // Make signatures List<byte[]> signatures = StandardTransactionBuilder.generateSignatures( unsigned.getSignatureInfo(), keyRing, mbwManager.getRecordManager().getRandomSource()); // Sign transaction Transaction tx = StandardTransactionBuilder.finalizeTransaction(unsigned, signatures); return tx; }