<p>Sort of. Here's some code to get you started. It creates a transaction with one input and two outputs. One output sends some coins, another one commits some data. However, it still uses <code>Wallet::sendCoinsOffline</code> to complete and commit the TX, but I think you could get rid of it if you understand what <code>Wallet::completeTx</code> and <code>Wallet::commitTx</code> do.</p>

<pre><code>public class App extends WalletAppKit {
    public void commitStatement(String statement) throws InsufficientMoneyException {
        Address addr = getSomeAddress();
        TransactionOutput prevLink = getSomeUtxo();
        NetworkParameters params = RegTestParams.get(); // regtest mode

        byte[] data = statement.getBytes();
        if(data.length &gt; 80) {
            throw new RuntimeException("OP_RETURN data cannot exceed 80 bytes");
        }

        Transaction tx = new Transaction(params);       

        log.trace("prevLink TX for '" + statement + "': " + prevLink.getParentTransaction());

        tx.addInput(prevLink);

        Coin feeAmt = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
        Coin opRetAmt = Transaction.MIN_NONDUST_OUTPUT;
        Coin changeAmt = prevLink.getValue().minus(opRetAmt).minus(feeAmt);

        // 1st output: send coins
        tx.addOutput(changeAmt, addr);
        // 2nd output: commit some data
        tx.addOutput(opRetAmt, ScriptBuilder.createOpReturnScript(data));

        log.trace("TX for '" + statement + "' before SendRequest: " + tx);
        SendRequest req = SendRequest.forTx(tx);
        // Want inputs and outputs to keep their order
        req.shuffleOutputs = false;
        req.ensureMinRequiredFee = true;

        log.trace("SendRequest for '" + statement + "' before completeTx: " + req);
        wallet().sendCoinsOffline(req);

        // NOTE: At this point, the TX is saved in the wallet!
    }
}
</code></pre>

<p><strong>Later edit:</strong> So here's an example of how you can modify <code>completeTx</code> and <code>sendCoinsOffline</code>. I actually had to do this today for my own purposes by subclassing the <code>Wallet</code> class. You probably need to take a different route than subclassing <code>Wallet</code> but this should give you an idea of what you need to do. </p>

<p><strong>Warning:</strong> This modified code takes care of signing and paying the fee <em>only for these special-kind of transactions</em> with one input and two outputs. Seems to work so far as I've tested it.</p>

<pre><code>public class MyWallet extends Wallet {
    private boolean payFee(Transaction tx, Coin feePerKb, boolean ensureMinRequiredFee) {
        final int size = tx.unsafeBitcoinSerialize().length;
        Coin fee = feePerKb.multiply(size).divide(1000);

        if (ensureMinRequiredFee &amp;&amp; fee.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) &lt; 0)
            fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;

        TransactionOutput output = tx.getOutput(0);
        output.setValue(output.getValue().subtract(fee));

        return !output.isDust();
    }

    public void myCompleteTx(SendRequest req) throws InsufficientMoneyException {
        lock.lock();
        try {
            // Print the output value
            Coin value = Coin.ZERO;
            for (TransactionOutput output : req.tx.getOutputs()) {
                value = value.add(output.getValue());
            }

            log.debug("Completing send tx with {} outputs totalling {} (not including fees)",
                    req.tx.getOutputs().size(), value.toFriendlyString());

            // Check for dusty sends and the OP_RETURN limit.
            if (req.ensureMinRequiredFee &amp;&amp; !req.emptyWallet) { // Min fee checking is handled later for emptyWallet.
                int opReturnCount = 0;
                for (TransactionOutput output : req.tx.getOutputs()) {
                    if (output.isDust())
                        throw new DustySendRequested();
                    if (output.getScriptPubKey().isOpReturn())
                        ++opReturnCount;
                }
                if (opReturnCount &gt; 1) // Only 1 OP_RETURN per transaction allowed.
                    throw new MultipleOpReturnRequested();
            }

            // Pay for the TX fee, depending on the TX size.
            Coin feePerKb = req.feePerKb == null ? Coin.ZERO : req.feePerKb;
            if (!payFee(req.tx, feePerKb, req.ensureMinRequiredFee))
                throw new CouldNotAdjustDownwards();

            // Now sign the inputs, thus proving that we are entitled to redeem the connected outputs.
            if (req.signInputs)
                signTransaction(req);

            // Check size.
            final int size = req.tx.unsafeBitcoinSerialize().length;
            if (size &gt; Transaction.MAX_STANDARD_TX_SIZE)
                throw new ExceededMaxTransactionSize();

            final Coin calculatedFee = req.tx.getFee();
            if (calculatedFee != null)
                log.debug("  with a fee of {}/kB, {} for {} bytes",
                        calculatedFee.multiply(1000).divide(size).toFriendlyString(), calculatedFee.toFriendlyString(),
                        size);

            // Label the transaction as being self created. We can use this later to spend its change output even before
            // the transaction is confirmed. We deliberately won't bother notifying listeners here as there's not much
            // point - the user isn't interested in a confidence transition they made themselves.
            req.tx.getConfidence().setSource(TransactionConfidence.Source.SELF);
            // Label the transaction as being a user requested payment. This can be used to render GUI wallet
            // transaction lists more appropriately, especially when the wallet starts to generate transactions itself
            // for internal purposes.
            req.tx.setPurpose(Transaction.Purpose.USER_PAYMENT);
            // Record the exchange rate that was valid when the transaction was completed.
            req.tx.setExchangeRate(req.exchangeRate);
            req.tx.setMemo(req.memo);
            //req.completed = true; // FIXME: ALIN: This field is private, can't set it to true, but thankfully this is just for debugging.
            log.debug("  completed: {}", req.tx);
        } finally {
            lock.unlock();
        }
    }

    public Transaction mySendCoinsOffline(SendRequest request) throws InsufficientMoneyException {
        lock.lock();
        try {
            myCompleteTx(request);
            commitTx(request.tx);
            return request.tx;
        } finally {
            lock.unlock();
        }
    }
}
</code></pre>

CC BY-SA 3.0
2016-08-25T17:28:20.400Z
2016-08-25T23:34:21.710Z
2016-08-25T23:34:21.710Z
Alin Tomescu
<p>Is there a way to construct and send a transaction in <code>BitcoinJ</code> without a wallet? I just want to build my transaction from a utxo and broadcast it.</p>

<transactions><bitcoinj><raw-transaction><utxo>
How do you create a transaction from a UTXO in BitcoinJ?
Dragomirus
# How do you create a transaction from a UTXO in BitcoinJ?

(Asked by: username_0 on 2016-08-23)

Is there a way to construct and send a transaction in `BitcoinJ` without a wallet? I just want to build my transaction from a utxo and broadcast it.

**Tags:** transactions, bitcoinj, raw-transaction, utxo


---

## 1 answers

### Answer by username_1 on 2016-08-25. Score: 1

Sort of. Here's some code to get you started. It creates a transaction with one input and two outputs. One output sends some coins, another one commits some data. However, it still uses `Wallet::sendCoinsOffline` to complete and commit the TX, but I think you could get rid of it if you understand what `Wallet::completeTx` and `Wallet::commitTx` do.

```
public class App extends WalletAppKit {
    public void commitStatement(String statement) throws InsufficientMoneyException {
        Address addr = getSomeAddress();
        TransactionOutput prevLink = getSomeUtxo();
        NetworkParameters params = RegTestParams.get(); // regtest mode

        byte[] data = statement.getBytes();
        if(data.length > 80) {
            throw new RuntimeException("OP_RETURN data cannot exceed 80 bytes");
        }

        Transaction tx = new Transaction(params);       

        log.trace("prevLink TX for '" + statement + "': " + prevLink.getParentTransaction());

        tx.addInput(prevLink);

        Coin feeAmt = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
        Coin opRetAmt = Transaction.MIN_NONDUST_OUTPUT;
        Coin changeAmt = prevLink.getValue().minus(opRetAmt).minus(feeAmt);

        // 1st output: send coins
        tx.addOutput(changeAmt, addr);
        // 2nd output: commit some data
        tx.addOutput(opRetAmt, ScriptBuilder.createOpReturnScript(data));

        log.trace("TX for '" + statement + "' before SendRequest: " + tx);
        SendRequest req = SendRequest.forTx(tx);
        // Want inputs and outputs to keep their order
        req.shuffleOutputs = false;
        req.ensureMinRequiredFee = true;

        log.trace("SendRequest for '" + statement + "' before completeTx: " + req);
        wallet().sendCoinsOffline(req);

        // NOTE: At this point, the TX is saved in the wallet!
    }
}

```

**Later edit:** So here's an example of how you can modify `completeTx` and `sendCoinsOffline`. I actually had to do this today for my own purposes by subclassing the `Wallet` class. You probably need to take a different route than subclassing `Wallet` but this should give you an idea of what you need to do.

**Warning:** This modified code takes care of signing and paying the fee *only for these special-kind of transactions* with one input and two outputs. Seems to work so far as I've tested it.

```
public class MyWallet extends Wallet {
    private boolean payFee(Transaction tx, Coin feePerKb, boolean ensureMinRequiredFee) {
        final int size = tx.unsafeBitcoinSerialize().length;
        Coin fee = feePerKb.multiply(size).divide(1000);

        if (ensureMinRequiredFee && fee.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0)
            fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;

        TransactionOutput output = tx.getOutput(0);
        output.setValue(output.getValue().subtract(fee));

        return !output.isDust();
    }

    public void myCompleteTx(SendRequest req) throws InsufficientMoneyException {
        lock.lock();
        try {
            // Print the output value
            Coin value = Coin.ZERO;
            for (TransactionOutput output : req.tx.getOutputs()) {
                value = value.add(output.getValue());
            }

            log.debug("Completing send tx with {} outputs totalling {} (not including fees)",
                    req.tx.getOutputs().size(), value.toFriendlyString());

            // Check for dusty sends and the OP_RETURN limit.
            if (req.ensureMinRequiredFee && !req.emptyWallet) { // Min fee checking is handled later for emptyWallet.
                int opReturnCount = 0;
                for (TransactionOutput output : req.tx.getOutputs()) {
                    if (output.isDust())
                        throw new DustySendRequested();
                    if (output.getScriptPubKey().isOpReturn())
                        ++opReturnCount;
                }
                if (opReturnCount > 1) // Only 1 OP_RETURN per transaction allowed.
                    throw new MultipleOpReturnRequested();
            }

            // Pay for the TX fee, depending on the TX size.
            Coin feePerKb = req.feePerKb == null ? Coin.ZERO : req.feePerKb;
            if (!payFee(req.tx, feePerKb, req.ensureMinRequiredFee))
                throw new CouldNotAdjustDownwards();

            // Now sign the inputs, thus proving that we are entitled to redeem the connected outputs.
            if (req.signInputs)
                signTransaction(req);

            // Check size.
            final int size = req.tx.unsafeBitcoinSerialize().length;
            if (size > Transaction.MAX_STANDARD_TX_SIZE)
                throw new ExceededMaxTransactionSize();

            final Coin calculatedFee = req.tx.getFee();
            if (calculatedFee != null)
                log.debug("  with a fee of {}/kB, {} for {} bytes",
                        calculatedFee.multiply(1000).divide(size).toFriendlyString(), calculatedFee.toFriendlyString(),
                        size);

            // Label the transaction as being self created. We can use this later to spend its change output even before
            // the transaction is confirmed. We deliberately won't bother notifying listeners here as there's not much
            // point - the user isn't interested in a confidence transition they made themselves.
            req.tx.getConfidence().setSource(TransactionConfidence.Source.SELF);
            // Label the transaction as being a user requested payment. This can be used to render GUI wallet
            // transaction lists more appropriately, especially when the wallet starts to generate transactions itself
            // for internal purposes.
            req.tx.setPurpose(Transaction.Purpose.USER_PAYMENT);
            // Record the exchange rate that was valid when the transaction was completed.
            req.tx.setExchangeRate(req.exchangeRate);
            req.tx.setMemo(req.memo);
            //req.completed = true; // FIXME: username_1: This field is private, can't set it to true, but thankfully this is just for debugging.
            log.debug("  completed: {}", req.tx);
        } finally {
            lock.unlock();
        }
    }

    public Transaction mySendCoinsOffline(SendRequest request) throws InsufficientMoneyException {
        lock.lock();
        try {
            myCompleteTx(request);
            commitTx(request.tx);
            return request.tx;
        } finally {
            lock.unlock();
        }
    }
}

```


---

