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

The following examples show how to use org.bitcoinj.core.Transaction#getOutput() . 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: TradeWalletService.java    From bisq with GNU Affero General Public License v3.0 6 votes vote down vote up
private Transaction createPayoutTx(Transaction depositTx,
                                   Coin buyerPayoutAmount,
                                   Coin sellerPayoutAmount,
                                   String buyerAddressString,
                                   String sellerAddressString) throws AddressFormatException {
    TransactionOutput p2SHMultiSigOutput = depositTx.getOutput(0);
    Transaction transaction = new Transaction(params);
    transaction.addInput(p2SHMultiSigOutput);
    if (buyerPayoutAmount.isPositive()) {
        transaction.addOutput(buyerPayoutAmount, Address.fromBase58(params, buyerAddressString));
    }
    if (sellerPayoutAmount.isPositive()) {
        transaction.addOutput(sellerPayoutAmount, Address.fromBase58(params, sellerAddressString));
    }
    checkArgument(transaction.getOutputs().size() >= 1, "We need at least one output.");
    return transaction;
}
 
Example 2
Source File: TradeWalletService.java    From bisq-core with GNU Affero General Public License v3.0 5 votes vote down vote up
private Transaction createPayoutTx(Transaction depositTx,
                                   Coin buyerPayoutAmount,
                                   Coin sellerPayoutAmount,
                                   String buyerAddressString,
                                   String sellerAddressString) throws AddressFormatException {
    TransactionOutput p2SHMultiSigOutput = depositTx.getOutput(0);
    Transaction transaction = new Transaction(params);
    transaction.addInput(p2SHMultiSigOutput);
    transaction.addOutput(buyerPayoutAmount, Address.fromBase58(params, buyerAddressString));
    transaction.addOutput(sellerPayoutAmount, Address.fromBase58(params, sellerAddressString));
    return transaction;
}
 
Example 3
Source File: GATx.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
public static ChangeOutput findChangeOutput(final List<JSONMap> endPoints,
                                            final Transaction tx,
                                            final int forSubAccount) {
    int index = -1;
    int pubkey_pointer = -1;
    int scriptType = 0;
    for (final JSONMap ep : endPoints) {
        if (!ep.getBool("is_credit") || !ep.getBool("is_relevant") ||
            ep.getInt("subaccount", 0) != forSubAccount)
            continue;

        if (index != -1) {
            // Found another output paying to this account. This can
            // only happend when redepositing to our own acount with
            // a change output (e.g. by manually sending some amount
            // of funds to ourself). In this case the change output
            // will have been created after the amount output by the
            // tx construction code, so the output with the highest
            // pubkey pointer is our change, as they are incremented
            // for each new output. Note that we can't use the order
            // of the output in the tx due to change randomisation.
            if (ep.getInt("pubkey_pointer") < pubkey_pointer)
                continue; // Not our change output
        }
        index = ep.getInt("pt_idx");
        pubkey_pointer = ep.getInt("pubkey_pointer");
        scriptType = ep.getInt("script_type");
    }
    if (index == -1)
        return null;
    return new ChangeOutput(tx.getOutput(index), pubkey_pointer,
                            getOutScriptType(scriptType) == P2SH_P2WSH_FORTIFIED_OUT);
}
 
Example 4
Source File: GATx.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
public static boolean randomizeChangeOutput(final Transaction tx) {
    if (CryptoHelper.randomBytes(1)[0] < 0)
        return false;

    final TransactionOutput a = tx.getOutput(0);
    final TransactionOutput b = tx.getOutput(1);
    tx.clearOutputs();
    tx.addOutput(b);
    tx.addOutput(a);
    return true;
}
 
Example 5
Source File: TradeWalletService.java    From bisq with GNU Affero General Public License v3.0 5 votes vote down vote up
public Transaction createDelayedUnsignedPayoutTx(Transaction depositTx,
                                                 String donationAddressString,
                                                 Coin minerFee,
                                                 long lockTime)
        throws AddressFormatException, TransactionVerificationException {
    TransactionOutput p2SHMultiSigOutput = depositTx.getOutput(0);
    Transaction delayedPayoutTx = new Transaction(params);
    delayedPayoutTx.addInput(p2SHMultiSigOutput);
    applyLockTime(lockTime, delayedPayoutTx);
    Coin outputAmount = p2SHMultiSigOutput.getValue().subtract(minerFee);
    delayedPayoutTx.addOutput(outputAmount, Address.fromBase58(params, donationAddressString));
    WalletService.printTx("Unsigned delayedPayoutTx ToDonationAddress", delayedPayoutTx);
    WalletService.verifyTransaction(delayedPayoutTx);
    return delayedPayoutTx;
}
 
Example 6
Source File: TradeWalletService.java    From bisq-core with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * That arbitrator signs the payout transaction
 *
 * @param depositTxSerialized Serialized deposit tx
 * @param buyerPayoutAmount   The payout amount of the buyer.
 * @param sellerPayoutAmount  The payout amount of the seller.
 * @param buyerAddressString  The address of the buyer.
 * @param sellerAddressString The address of the seller.
 * @param arbitratorKeyPair   The keypair of the arbitrator.
 * @param buyerPubKey         The public key of the buyer.
 * @param sellerPubKey        The public key of the seller.
 * @param arbitratorPubKey    The public key of the arbitrator.
 * @return DER encoded canonical signature of arbitrator
 * @throws AddressFormatException
 * @throws TransactionVerificationException
 */
public byte[] arbitratorSignsDisputedPayoutTx(byte[] depositTxSerialized,
                                              Coin buyerPayoutAmount,
                                              Coin sellerPayoutAmount,
                                              String buyerAddressString,
                                              String sellerAddressString,
                                              DeterministicKey arbitratorKeyPair,
                                              byte[] buyerPubKey,
                                              byte[] sellerPubKey,
                                              byte[] arbitratorPubKey)
        throws AddressFormatException, TransactionVerificationException {
    Transaction depositTx = new Transaction(params, depositTxSerialized);
    log.trace("signDisputedPayoutTx called");
    log.trace("depositTx " + depositTx.toString());
    log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString());
    log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString());
    log.trace("buyerAddressString " + buyerAddressString);
    log.trace("sellerAddressString " + sellerAddressString);
    log.trace("arbitratorKeyPair (not displayed for security reasons)");
    log.info("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString());
    log.info("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString());
    log.info("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString());

    // Our MS is index 0
    TransactionOutput p2SHMultiSigOutput = depositTx.getOutput(0);
    Transaction preparedPayoutTx = new Transaction(params);
    preparedPayoutTx.addInput(p2SHMultiSigOutput);
    if (buyerPayoutAmount.isGreaterThan(Coin.ZERO))
        preparedPayoutTx.addOutput(buyerPayoutAmount, Address.fromBase58(params, buyerAddressString));
    if (sellerPayoutAmount.isGreaterThan(Coin.ZERO))
        preparedPayoutTx.addOutput(sellerPayoutAmount, Address.fromBase58(params, sellerAddressString));

    // take care of sorting!
    Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey);
    Sha256Hash sigHash = preparedPayoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false);
    checkNotNull(arbitratorKeyPair, "arbitratorKeyPair must not be null");
    if (arbitratorKeyPair.isEncrypted())
        checkNotNull(aesKey);

    ECKey.ECDSASignature arbitratorSignature = arbitratorKeyPair.sign(sigHash, aesKey).toCanonicalised();

    WalletService.verifyTransaction(preparedPayoutTx);

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

    return arbitratorSignature.encodeToDER();
}
 
Example 7
Source File: TradeWalletService.java    From bisq-core with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * A trader who got the signed tx from the arbitrator finalizes the payout tx
 *
 * @param depositTxSerialized    Serialized deposit tx
 * @param arbitratorSignature    DER encoded canonical signature of arbitrator
 * @param buyerPayoutAmount      Payout amount of the buyer
 * @param sellerPayoutAmount     Payout amount of the seller
 * @param buyerAddressString     The address of the buyer.
 * @param sellerAddressString    The address of the seller.
 * @param tradersMultiSigKeyPair The keypair for the MultiSig of the trader who calls that method
 * @param buyerPubKey            The public key of the buyer.
 * @param sellerPubKey           The public key of the seller.
 * @param arbitratorPubKey       The public key of the arbitrator.
 * @return The completed payout tx
 * @throws AddressFormatException
 * @throws TransactionVerificationException
 * @throws WalletException
 */
public Transaction traderSignAndFinalizeDisputedPayoutTx(byte[] depositTxSerialized,
                                                         byte[] arbitratorSignature,
                                                         Coin buyerPayoutAmount,
                                                         Coin sellerPayoutAmount,
                                                         String buyerAddressString,
                                                         String sellerAddressString,
                                                         DeterministicKey tradersMultiSigKeyPair,
                                                         byte[] buyerPubKey,
                                                         byte[] sellerPubKey,
                                                         byte[] arbitratorPubKey)
        throws AddressFormatException, TransactionVerificationException, WalletException {
    Transaction depositTx = new Transaction(params, depositTxSerialized);

    log.trace("signAndFinalizeDisputedPayoutTx called");
    log.trace("depositTx " + depositTx);
    log.trace("arbitratorSignature r " + ECKey.ECDSASignature.decodeFromDER(arbitratorSignature).r.toString());
    log.trace("arbitratorSignature s " + ECKey.ECDSASignature.decodeFromDER(arbitratorSignature).s.toString());
    log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString());
    log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString());
    log.trace("buyerAddressString " + buyerAddressString);
    log.trace("sellerAddressString " + sellerAddressString);
    log.trace("tradersMultiSigKeyPair (not displayed for security reasons)");
    log.info("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString());
    log.info("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString());
    log.info("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString());


    TransactionOutput p2SHMultiSigOutput = depositTx.getOutput(0);
    Transaction payoutTx = new Transaction(params);
    payoutTx.addInput(p2SHMultiSigOutput);
    if (buyerPayoutAmount.isGreaterThan(Coin.ZERO))
        payoutTx.addOutput(buyerPayoutAmount, Address.fromBase58(params, buyerAddressString));
    if (sellerPayoutAmount.isGreaterThan(Coin.ZERO))
        payoutTx.addOutput(sellerPayoutAmount, Address.fromBase58(params, sellerAddressString));

    // take care of sorting!
    Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey);
    Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false);
    checkNotNull(tradersMultiSigKeyPair, "tradersMultiSigKeyPair must not be null");
    if (tradersMultiSigKeyPair.isEncrypted())
        checkNotNull(aesKey);
    ECKey.ECDSASignature tradersSignature = tradersMultiSigKeyPair.sign(sigHash, aesKey).toCanonicalised();

    TransactionSignature tradersTxSig = new TransactionSignature(tradersSignature, Transaction.SigHash.ALL, false);
    TransactionSignature arbitratorTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(arbitratorSignature),
            Transaction.SigHash.ALL, false);
    // Take care of order of signatures. See comment below at getMultiSigRedeemScript (sort order needed here: arbitrator, seller, buyer)
    Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(arbitratorTxSig, tradersTxSig), redeemScript);
    TransactionInput input = payoutTx.getInput(0);
    input.setScriptSig(inputScript);

    WalletService.printTx("disputed payoutTx", payoutTx);

    WalletService.verifyTransaction(payoutTx);
    WalletService.checkWalletConsistency(wallet);
    WalletService.checkScriptSig(payoutTx, input, 0);
    checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null");
    input.verify(input.getConnectedOutput());
    return payoutTx;
}
 
Example 8
Source File: TransactionActivity.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
private static Pair<Integer, JSONMap>
createRawTransaction(final GaService service,
                     final Transaction tx, final List<JSONMap> usedUtxos,
                     final List<JSONMap> utxos, final int subAccount,
                     GATx.ChangeOutput changeOutput,
                     final Coin amount, final Coin oldFee,
                     final Coin feeRate,
                     final JSONMap privateData, final boolean sendAll) {

    final boolean isRBF = usedUtxos != null;
    final boolean haveExistingChange = changeOutput != null;
    Coin total =  isRBF ? getUtxoSum(usedUtxos) : Coin.ZERO;
    Coin fee;

    // First add inputs until we cover the amount to send
    while ((sendAll || total.isLessThan(amount)) && !utxos.isEmpty())
        total = total.add(GATx.addUtxo(service, tx, utxos, usedUtxos));

    // Then add inputs until we cover amount + fee/change
    while (true) {
        fee = GATx.getTxFee(service, tx, feeRate);
        if (isRBF) {
            final Coin bandwidthFee = GATx.getTxFee(service, tx, service.getMinFeeRate());
            fee = (fee.isLessThan(oldFee) ? oldFee : fee).add(bandwidthFee);
        }

        final Coin minChange = changeOutput == null ? Coin.ZERO : service.getDustThreshold();
        final int cmp = sendAll ? 0 : total.compareTo(amount.add(fee).add(minChange));
        if (cmp < 0) {
            // Need more inputs to cover amount + fee/change
            if (utxos.isEmpty())
                return createFailed(R.string.insufficientFundsText); // None left, fail

            total = total.add(GATx.addUtxo(service, tx, utxos, usedUtxos));
            continue;
        }

        if (cmp == 0 || changeOutput != null) {
            // Inputs exactly match amount + fee/change, or are greater
            // and we have a change output for the excess
            break;
        }

        // Inputs greater than amount + fee, add a change output and try again
        changeOutput = GATx.addChangeOutput(service, tx, subAccount);
        if (changeOutput == null)
            return createFailed(R.string.unable_to_create_change);
    }

    boolean randomizedChange = false;
    if (changeOutput != null) {
        // Set the value of the change output
        if (tx.getOutputs().size() == 1)
            changeOutput.mOutput.setValue(total.subtract(fee)); // Redeposit
        else
            changeOutput.mOutput.setValue(total.subtract(amount).subtract(fee));
        if (haveExistingChange)
            randomizedChange = changeOutput.mOutput == tx.getOutput(0);
        else
            randomizedChange = GATx.randomizeChangeOutput(tx);
    }

    if (sendAll) {
        final Coin actualAmount = total.subtract(fee);
        if (!actualAmount.isGreaterThan(Coin.ZERO))
            return createFailed(R.string.insufficientFundsText);
        final int amtIndex = tx.getOutputs().size() == 1 ? 0 : (randomizedChange ? 1 : 0);
        tx.getOutput(amtIndex).setValue(actualAmount);
    }

    tx.setLockTime(service.getCurrentBlock()); // Prevent fee sniping

    int changeIndex = -1;
    if (changeOutput != null && tx.getOutputs().size() != 1)
        changeIndex = randomizedChange ? 0 : 1;
    return new Pair<>(0,
                      GATx.makeLimitsData(fee.subtract(oldFee), fee, changeIndex));
}
 
Example 9
Source File: TradeWalletService.java    From bisq with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * A trader who got the signed tx from the arbitrator finalizes the payout tx.
 *
 * @param depositTxSerialized    serialized deposit tx
 * @param arbitratorSignature    DER encoded canonical signature of arbitrator
 * @param buyerPayoutAmount      payout amount of the buyer
 * @param sellerPayoutAmount     payout amount of the seller
 * @param buyerAddressString     the address of the buyer
 * @param sellerAddressString    the address of the seller
 * @param tradersMultiSigKeyPair the key pair for the MultiSig of the trader who calls that method
 * @param buyerPubKey            the public key of the buyer
 * @param sellerPubKey           the public key of the seller
 * @param arbitratorPubKey       the public key of the arbitrator
 * @return the completed payout tx
 * @throws AddressFormatException if the buyer or seller base58 address doesn't parse or its checksum is invalid
 * @throws TransactionVerificationException if there was an unexpected problem with the payout tx or its signature
 * @throws WalletException if the trade wallet is null or structurally inconsistent
 */
public Transaction traderSignAndFinalizeDisputedPayoutTx(byte[] depositTxSerialized,
                                                         byte[] arbitratorSignature,
                                                         Coin buyerPayoutAmount,
                                                         Coin sellerPayoutAmount,
                                                         String buyerAddressString,
                                                         String sellerAddressString,
                                                         DeterministicKey tradersMultiSigKeyPair,
                                                         byte[] buyerPubKey,
                                                         byte[] sellerPubKey,
                                                         byte[] arbitratorPubKey)
        throws AddressFormatException, TransactionVerificationException, WalletException {
    Transaction depositTx = new Transaction(params, depositTxSerialized);
    TransactionOutput p2SHMultiSigOutput = depositTx.getOutput(0);
    Transaction payoutTx = new Transaction(params);
    payoutTx.addInput(p2SHMultiSigOutput);
    if (buyerPayoutAmount.isPositive()) {
        payoutTx.addOutput(buyerPayoutAmount, Address.fromBase58(params, buyerAddressString));
    }
    if (sellerPayoutAmount.isPositive()) {
        payoutTx.addOutput(sellerPayoutAmount, Address.fromBase58(params, sellerAddressString));
    }

    // take care of sorting!
    Script redeemScript = get2of3MultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey);
    Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false);
    checkNotNull(tradersMultiSigKeyPair, "tradersMultiSigKeyPair must not be null");
    if (tradersMultiSigKeyPair.isEncrypted()) {
        checkNotNull(aesKey);
    }
    ECKey.ECDSASignature tradersSignature = tradersMultiSigKeyPair.sign(sigHash, aesKey).toCanonicalised();
    TransactionSignature tradersTxSig = new TransactionSignature(tradersSignature, Transaction.SigHash.ALL, false);
    TransactionSignature arbitratorTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(arbitratorSignature),
            Transaction.SigHash.ALL, false);
    // Take care of order of signatures. See comment below at getMultiSigRedeemScript (sort order needed here: arbitrator, seller, buyer)
    Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(arbitratorTxSig, tradersTxSig),
            redeemScript);
    TransactionInput input = payoutTx.getInput(0);
    input.setScriptSig(inputScript);
    WalletService.printTx("disputed payoutTx", payoutTx);
    WalletService.verifyTransaction(payoutTx);
    WalletService.checkWalletConsistency(wallet);
    WalletService.checkScriptSig(payoutTx, input, 0);
    checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null");
    input.verify(input.getConnectedOutput());
    return payoutTx;
}
 
Example 10
Source File: UtxoTrieMgr.java    From jelectrum with MIT License 4 votes vote down vote up
public String getKeyForInput(TransactionInput in)
{
  if (in.isCoinBase()) return null;
  try
  {   
    byte[] public_key=null; 
    Address a = in.getFromAddress();
    public_key = a.getHash160();

    return getKey(public_key, in.getOutpoint().getHash(), (int)in.getOutpoint().getIndex());
  }
  catch(ScriptException e)
  {
    //Lets try this the other way
    try
    {   

      TransactionOutPoint out_p = in.getOutpoint();

      Transaction src_tx = tx_util.getTransaction(out_p.getHash());
      TransactionOutput out = src_tx.getOutput((int)out_p.getIndex());
      return getKeyForOutput(out, (int)out_p.getIndex());
    }
    catch(ScriptException e2)
    {   
      return null;
    }
  }

 
}