Java Code Examples for org.bitcoinj.core.Transaction#addOutput()

The following examples show how to use org.bitcoinj.core.Transaction#addOutput() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
@Test
public void watchingScriptsSentFrom() throws Exception {
    int baseElements = wallet.getBloomFilterElementCount();

    Address watchedAddress = LegacyAddress.fromKey(UNITTEST, new ECKey());
    wallet.addWatchedAddress(watchedAddress);
    assertEquals(baseElements + 1, wallet.getBloomFilterElementCount());

    Transaction t1 = createFakeTx(UNITTEST, CENT, watchedAddress);
    Transaction t2 = createFakeTx(UNITTEST, COIN, OTHER_ADDRESS);
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, t1);
    assertEquals(baseElements + 2, wallet.getBloomFilterElementCount());
    Transaction st2 = new Transaction(UNITTEST);
    st2.addOutput(CENT, OTHER_ADDRESS);
    st2.addOutput(COIN, OTHER_ADDRESS);
    st2.addInput(t1.getOutput(0));
    st2.addInput(t2.getOutput(0));
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, st2);
    assertEquals(baseElements + 2, wallet.getBloomFilterElementCount());
    assertEquals(CENT, st2.getValueSentFromMe(wallet));
}
 
Example 2
Source File: WalletTest.java    From green_android with GNU General Public License v3.0 6 votes vote down vote up
@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());
}
 
Example 3
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 6 votes vote down vote up
@Test
public void outOfOrderPendingTxns() throws Exception {
    // Check that if there are two pending transactions which we receive out of order, they are marked as spent
    // correctly. For instance, we are watching a wallet, someone pays us (A) and we then pay someone else (B)
    // with a change address but the network delivers the transactions to us in order B then A.
    Coin value = COIN;
    Transaction a = createFakeTx(PARAMS, value, myAddress);
    Transaction b = new Transaction(PARAMS);
    b.addInput(a.getOutput(0));
    b.addOutput(CENT, OTHER_ADDRESS);
    Coin v = COIN.subtract(CENT);
    b.addOutput(v, wallet.currentChangeAddress());
    a = roundTripTransaction(PARAMS, a);
    b = roundTripTransaction(PARAMS, b);
    wallet.receivePending(b, null);
    assertEquals(v, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
    wallet.receivePending(a, null);
    assertEquals(v, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
}
 
Example 4
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
@Test
public void outOfOrderPendingTxns() throws Exception {
    // Check that if there are two pending transactions which we receive out of order, they are marked as spent
    // correctly. For instance, we are watching a wallet, someone pays us (A) and we then pay someone else (B)
    // with a change address but the network delivers the transactions to us in order B then A.
    Coin value = COIN;
    Transaction a = createFakeTx(UNITTEST, value, myAddress);
    Transaction b = new Transaction(UNITTEST);
    b.addInput(a.getOutput(0));
    b.addOutput(CENT, OTHER_ADDRESS);
    Coin v = COIN.subtract(CENT);
    b.addOutput(v, wallet.currentChangeAddress());
    a = roundTripTransaction(UNITTEST, a);
    b = roundTripTransaction(UNITTEST, b);
    wallet.receivePending(b, null);
    assertEquals(v, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
    wallet.receivePending(a, null);
    assertEquals(v, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
}
 
Example 5
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
@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(UNITTEST);
    inbound2.addOutput(new TransactionOutput(UNITTEST, 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());
}
 
Example 6
Source File: WalletTest.java    From green_android with GNU General Public License v3.0 6 votes vote down vote up
@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));
}
 
Example 7
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 6 votes vote down vote up
@Test
public void replayWhilstPending() throws Exception {
    // Check that if a pending transaction spends outputs of chain-included transactions, we mark them as spent.
    // See bug 345. This can happen if there is a pending transaction floating around and then you replay the
    // chain without emptying the memory pool (or refilling it from a peer).
    Coin value = COIN;
    Transaction tx1 = createFakeTx(PARAMS, value, myAddress);
    Transaction tx2 = new Transaction(PARAMS);
    tx2.addInput(tx1.getOutput(0));
    tx2.addOutput(valueOf(0, 9), OTHER_ADDRESS);
    // Add a change address to ensure this tx is relevant.
    tx2.addOutput(CENT, wallet.currentChangeAddress());
    wallet.receivePending(tx2, null);
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, tx1);
    assertEquals(ZERO, wallet.getBalance());
    assertEquals(1, wallet.getPoolSize(Pool.SPENT));
    assertEquals(1, wallet.getPoolSize(Pool.PENDING));
    assertEquals(0, wallet.getPoolSize(Pool.UNSPENT));
}
 
Example 8
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
@Test(expected = Wallet.DustySendRequested.class)
public void sendDustAndMessageWithValueTest() throws Exception {
    // Tests sending dust and OP_RETURN with value, should throw DustySendRequested
    receiveATransaction(wallet, myAddress);
    Transaction tx = new Transaction(UNITTEST);
    tx.addOutput(Coin.CENT, ScriptBuilder.createOpReturnScript("hello world!".getBytes()));
    tx.addOutput(Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI), OTHER_ADDRESS);
    SendRequest request = SendRequest.forTx(tx);
    request.ensureMinRequiredFee = true;
    wallet.completeTx(request);
}
 
Example 9
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void balanceWithIdenticalOutputs() {
    assertEquals(Coin.ZERO, wallet.getBalance(BalanceType.ESTIMATED));
    Transaction tx = new Transaction(PARAMS);
    tx.addOutput(Coin.COIN, myAddress);
    tx.addOutput(Coin.COIN, myAddress); // identical to the above
    wallet.addWalletTransaction(new WalletTransaction(Pool.UNSPENT, tx));
    assertEquals(Coin.COIN.plus(Coin.COIN), wallet.getBalance(BalanceType.ESTIMATED));
}
 
Example 10
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void spendOutputFromPendingTransaction() throws Exception {
    // We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
    Coin v1 = COIN;
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, v1);
    // First create our current transaction
    ECKey k2 = wallet.freshReceiveKey();
    Coin v2 = valueOf(0, 50);
    Transaction t2 = new Transaction(PARAMS);
    TransactionOutput o2 = new TransactionOutput(PARAMS, t2, v2, k2.toAddress(PARAMS));
    t2.addOutput(o2);
    SendRequest req = SendRequest.forTx(t2);
    wallet.completeTx(req);

    // Commit t2, so it is placed in the pending pool
    wallet.commitTx(t2);
    assertEquals(0, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
    assertEquals(2, wallet.getTransactions(true).size());

    // Now try to the spend the output.
    ECKey k3 = new ECKey();
    Coin v3 = valueOf(0, 25);
    Transaction t3 = new Transaction(PARAMS);
    t3.addOutput(v3, k3.toAddress(PARAMS));
    t3.addInput(o2);
    wallet.signTransaction(SendRequest.forTx(t3));

    // Commit t3, so the coins from the pending t2 are spent
    wallet.commitTx(t3);
    assertEquals(0, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
    assertEquals(2, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
    assertEquals(3, wallet.getTransactions(true).size());

    // Now the output of t2 must not be available for spending
    assertFalse(o2.isAvailableForSpending());
}
 
Example 11
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void balanceWithIdenticalOutputs() {
    assertEquals(Coin.ZERO, wallet.getBalance(BalanceType.ESTIMATED));
    Transaction tx = new Transaction(UNITTEST);
    tx.addOutput(Coin.COIN, myAddress);
    tx.addOutput(Coin.COIN, myAddress); // identical to the above
    wallet.addWalletTransaction(new WalletTransaction(Pool.UNSPENT, tx));
    assertEquals(Coin.COIN.plus(Coin.COIN), wallet.getBalance(BalanceType.ESTIMATED));
}
 
Example 12
Source File: WalletTest.java    From green_android with GNU General Public License v3.0 5 votes vote down vote up
@Test(expected = Wallet.DustySendRequested.class)
public void sendDustAndOpReturnWithoutValueTest() throws Exception {
    // Tests sending dust and OP_RETURN without value, should throw DustySendRequested because sending sending dust is not allowed in any case.
    receiveATransactionAmount(wallet, myAddress, Coin.COIN);
    Transaction tx = new Transaction(PARAMS);
    tx.addOutput(Coin.ZERO, ScriptBuilder.createOpReturnScript("hello world!".getBytes()));
    tx.addOutput(Coin.SATOSHI, OTHER_ADDRESS);
    SendRequest request = SendRequest.forTx(tx);
    request.ensureMinRequiredFee = true;
    wallet.completeTx(request);
}
 
Example 13
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
@Test(expected = Wallet.MultipleOpReturnRequested.class)
public void twoOpReturnsPerTransactionTest() throws Exception {
    // Tests sending transaction where there are 2 attempts to write OP_RETURN scripts - this should fail and throw MultipleOpReturnRequested.
    receiveATransaction(wallet, myAddress);
    Transaction tx = new Transaction(PARAMS);
    Coin messagePrice = Coin.ZERO;
    Script script1 = ScriptBuilder.createOpReturnScript("hello world 1!".getBytes());
    Script script2 = ScriptBuilder.createOpReturnScript("hello world 2!".getBytes());
    tx.addOutput(messagePrice, script1);
    tx.addOutput(messagePrice, script2);
    SendRequest request = SendRequest.forTx(tx);
    request.ensureMinRequiredFee = true;
    wallet.completeTx(request);
}
 
Example 14
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void opReturnMaxBytes() throws Exception {
    receiveATransaction(wallet, myAddress);
    Transaction tx = new Transaction(UNITTEST);
    Script script = ScriptBuilder.createOpReturnScript(new byte[80]);
    tx.addOutput(Coin.ZERO, script);
    SendRequest request = SendRequest.forTx(tx);
    request.ensureMinRequiredFee = true;
    wallet.completeTx(request);
}
 
Example 15
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void opReturnOneOutputWithValueTest() throws Exception {
    // Tests basic send of transaction with one output that destroys coins and has an OP_RETURN.
    receiveATransaction(wallet, myAddress);
    Transaction tx = new Transaction(UNITTEST);
    Coin messagePrice = CENT;
    Script script = ScriptBuilder.createOpReturnScript("hello world!".getBytes());
    tx.addOutput(messagePrice, script);
    SendRequest request = SendRequest.forTx(tx);
    wallet.completeTx(request);
}
 
Example 16
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
@Test
@SuppressWarnings("deprecation")
// Having a test for deprecated method getFromAddress() is no evil so we suppress the warning here.
public void customTransactionSpending() throws Exception {
    // We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
    Coin v1 = valueOf(3, 0);
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, v1);
    assertEquals(v1, wallet.getBalance());
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
    assertEquals(1, wallet.getTransactions(true).size());

    Coin v2 = valueOf(0, 50);
    Coin v3 = valueOf(0, 75);
    Coin v4 = valueOf(1, 25);

    Transaction t2 = new Transaction(PARAMS);
    t2.addOutput(v2, OTHER_ADDRESS);
    t2.addOutput(v3, OTHER_ADDRESS);
    t2.addOutput(v4, OTHER_ADDRESS);
    SendRequest req = SendRequest.forTx(t2);
    wallet.completeTx(req);

    // Do some basic sanity checks.
    assertEquals(1, t2.getInputs().size());
    assertEquals(myAddress, t2.getInput(0).getScriptSig().getFromAddress(PARAMS));
    assertEquals(TransactionConfidence.ConfidenceType.UNKNOWN, t2.getConfidence().getConfidenceType());

    // We have NOT proven that the signature is correct!
    wallet.commitTx(t2);
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
    assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.SPENT));
    assertEquals(2, wallet.getTransactions(true).size());
}
 
Example 17
Source File: BsqWalletService.java    From bisq-core with GNU Affero General Public License v3.0 5 votes vote down vote up
public Transaction getPreparedVoteRevealTx(TxOutput stakeTxOutput) {
    Transaction tx = new Transaction(params);
    final Coin stake = Coin.valueOf(stakeTxOutput.getValue());
    Transaction blindVoteTx = getTransaction(stakeTxOutput.getTxId());
    checkNotNull(blindVoteTx, "blindVoteTx must not be null");
    TransactionOutPoint outPoint = new TransactionOutPoint(params, stakeTxOutput.getIndex(), blindVoteTx);
    // Input is not signed yet so we use new byte[]{}
    tx.addInput(new TransactionInput(params, tx, new byte[]{}, outPoint, stake));
    tx.addOutput(new TransactionOutput(params, tx, stake, getUnusedAddress()));
    // printTx("getPreparedVoteRevealTx", tx);
    return tx;
}
 
Example 18
Source File: GenerateLowSTests.java    From green_android with GNU General Public License v3.0 4 votes vote down vote up
public static void main(final String[] argv) throws NoSuchAlgorithmException, IOException {
    final NetworkParameters params = new MainNetParams();
    final LocalTransactionSigner signer = new LocalTransactionSigner();
    final SecureRandom secureRandom = SecureRandom.getInstanceStrong();
    final ECKey key = new ECKey(secureRandom);
    final KeyBag bag = new KeyBag() {
        @Override
        public ECKey findKeyFromPubHash(byte[] pubkeyHash) {
            return key;
        }

        @Override
        public ECKey findKeyFromPubKey(byte[] pubkey) {
            return key;
        }

        @Override
        public RedeemData findRedeemDataFromScriptHash(byte[] scriptHash) {
            return null;
        }

    };

    // Generate a fictional output transaction we take values from, and
    // an input transaction for the test case

    final Transaction outputTransaction = new Transaction(params);
    final Transaction inputTransaction = new Transaction(params);
    final TransactionOutput output = new TransactionOutput(params, inputTransaction, Coin.ZERO, key.toAddress(params));

    inputTransaction.addOutput(output);
    outputTransaction.addInput(output);
    outputTransaction.addOutput(Coin.ZERO, new ECKey(secureRandom).toAddress(params));

    addOutputs(outputTransaction, bag);

    // Sign the transaction
    final ProposedTransaction proposedTransaction = new ProposedTransaction(outputTransaction);
    signer.signInputs(proposedTransaction, bag);
    final TransactionInput input = proposedTransaction.partialTx.getInput(0);

    input.verify(output);
    input.getScriptSig().correctlySpends(outputTransaction, 0, output.getScriptPubKey(),
        EnumSet.of(Script.VerifyFlag.DERSIG, Script.VerifyFlag.P2SH));

    final Script scriptSig = input.getScriptSig();
    final TransactionSignature signature = TransactionSignature.decodeFromBitcoin(scriptSig.getChunks().get(0).data, true, false);

    // First output a conventional low-S transaction with the LOW_S flag, for the tx_valid.json set
    System.out.println("[\"A transaction with a low-S signature.\"],");
    System.out.println("[[[\""
        + inputTransaction.getHashAsString() + "\", "
        + output.getIndex() + ", \""
        + scriptToString(output.getScriptPubKey()) + "\"]],\n"
        + "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \""
        + Script.VerifyFlag.P2SH.name() + "," + Script.VerifyFlag.LOW_S.name() + "\"],");

    final BigInteger highS = HIGH_S_DIFFERENCE.subtract(signature.s);
    final TransactionSignature highSig = new TransactionSignature(signature.r, highS);
    input.setScriptSig(new ScriptBuilder().data(highSig.encodeToBitcoin()).data(scriptSig.getChunks().get(1).data).build());
    input.getScriptSig().correctlySpends(outputTransaction, 0, output.getScriptPubKey(),
        EnumSet.of(Script.VerifyFlag.P2SH));

    // A high-S transaction without the LOW_S flag, for the tx_valid.json set
    System.out.println("[\"A transaction with a high-S signature.\"],");
    System.out.println("[[[\""
        + inputTransaction.getHashAsString() + "\", "
        + output.getIndex() + ", \""
        + scriptToString(output.getScriptPubKey()) + "\"]],\n"
        + "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \""
        + Script.VerifyFlag.P2SH.name() + "\"],");

    // Lastly a conventional high-S transaction with the LOW_S flag, for the tx_invalid.json set
    System.out.println("[\"A transaction with a high-S signature.\"],");
    System.out.println("[[[\""
        + inputTransaction.getHashAsString() + "\", "
        + output.getIndex() + ", \""
        + scriptToString(output.getScriptPubKey()) + "\"]],\n"
        + "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \""
        + Script.VerifyFlag.P2SH.name() + "," + Script.VerifyFlag.LOW_S.name() + "\"],");
}
 
Example 19
Source File: LNPaymentLogicImpl.java    From thundernetwork with GNU Affero General Public License v3.0 4 votes vote down vote up
private List<Transaction> getPaymentTransactions (Sha256Hash parentTransactionHash, ChannelStatus channelStatus, RevocationHash
        revocationHash, ECKey keyServer, ECKey keyClient) {

    List<PaymentData> allPayments = new ArrayList<>(channelStatus.remainingPayments);
    allPayments.addAll(channelStatus.newPayments);

    List<Transaction> transactions = new ArrayList<>(allPayments.size());

    int index = 2;

    for (PaymentData payment : allPayments) {

        Transaction transaction = new Transaction(Constants.getNetwork());
        transaction.addInput(parentTransactionHash, index, Tools.getDummyScript());

        Coin value = Coin.valueOf(payment.amount);
        Script script = ScriptTools.getPaymentTxOutput(keyServer, keyClient, revocationHash, payment.csvDelay);
        transaction.addOutput(value, script);

        transactions.add(transaction);

        index++;
    }

    return transactions;
}
 
Example 20
Source File: TradeWalletService.java    From bisq-core with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * The taker creates a dummy transaction to get the input(s) and optional change output for the amount and the takersAddress for that trade.
 * That will be used to send to the maker for creating the deposit transaction.
 *
 * @param inputAmount   Amount of takers input
 * @param txFee         Mining fee
 * @param takersAddress Address of taker
 * @return A data container holding the inputs, the output value and address
 * @throws TransactionVerificationException
 * @throws WalletException
 */
public InputsAndChangeOutput takerCreatesDepositsTxInputs(Coin inputAmount, Coin txFee, Address takersAddress, Address takersChangeAddress) throws
        TransactionVerificationException, WalletException {
    log.debug("takerCreatesDepositsTxInputs called");
    log.debug("inputAmount " + inputAmount.toFriendlyString());
    log.debug("txFee " + txFee.toFriendlyString());
    log.debug("takersAddress " + takersAddress.toString());

    // We add the mining fee 2 times to the deposit tx:
    // 1. Will be spent when publishing the deposit tx (paid by buyer)
    // 2. Will be added to the MS amount, so when publishing the payout tx the fee is already there and the outputs are not changed by fee reduction
    // The fee for the payout will be paid by the seller.

    /*
     The tx we create has that structure:

     IN[0]  any input > inputAmount (including tx fee) (unsigned)
     IN[1...n] optional inputs supported, but normally there is just 1 input (unsigned)
     OUT[0] dummyOutputAmount (inputAmount - tx fee)
     OUT[1] Optional Change = inputAmount - dummyOutputAmount - tx fee

     We are only interested in the inputs and the optional change output.
     */


    // inputAmount includes the tx fee. So we subtract the fee to get the dummyOutputAmount.
    Coin dummyOutputAmount = inputAmount.subtract(txFee);

    Transaction dummyTX = new Transaction(params);
    // The output is just used to get the right inputs and change outputs, so we use an anonymous ECKey, as it will never be used for anything.
    // We don't care about fee calculation differences between the real tx and that dummy tx as we use a static tx fee.
    TransactionOutput dummyOutput = new TransactionOutput(params, dummyTX, dummyOutputAmount, new ECKey().toAddress(params));
    dummyTX.addOutput(dummyOutput);

    // Find the needed inputs to pay the output, optionally add 1 change output.
    // Normally only 1 input and no change output is used, but we support multiple inputs and 1 change output.
    // Our spending transaction output is from the create offer fee payment.
    addAvailableInputsAndChangeOutputs(dummyTX, takersAddress, takersChangeAddress, txFee);

    // The completeTx() call signs the input, but we don't want to pass over signed tx inputs so we remove the signature
    WalletService.removeSignatures(dummyTX);

    WalletService.verifyTransaction(dummyTX);

    //WalletService.printTx("dummyTX", dummyTX);

    List<RawTransactionInput> rawTransactionInputList = dummyTX.getInputs().stream()
            .map(e -> {
                checkNotNull(e.getConnectedOutput(), "e.getConnectedOutput() must not be null");
                checkNotNull(e.getConnectedOutput().getParentTransaction(), "e.getConnectedOutput().getParentTransaction() must not be null");
                checkNotNull(e.getValue(), "e.getValue() must not be null");
                return getRawInputFromTransactionInput(e);
            })
            .collect(Collectors.toList());

    // We don't support more then 1 change outputs, so there are max. 2 outputs
    checkArgument(dummyTX.getOutputs().size() < 3);
    // Only interested in optional change output, the dummy output at index 0 is ignored (that's why we use index 1)
    TransactionOutput changeOutput = dummyTX.getOutputs().size() == 2 ? dummyTX.getOutputs().get(1) : null;
    long changeOutputValue = 0L;
    String changeOutputAddress = null;
    if (changeOutput != null) {
        changeOutputValue = changeOutput.getValue().getValue();
        Address addressFromP2PKHScript = changeOutput.getAddressFromP2PKHScript(params);
        checkNotNull(addressFromP2PKHScript, "changeOutput.getAddressFromP2PKHScript(params) must not be null");
        changeOutputAddress = addressFromP2PKHScript.toString();
    }

    return new InputsAndChangeOutput(new ArrayList<>(rawTransactionInputList), changeOutputValue, changeOutputAddress);
}