Search in sources :

Example 6 with TransactionInput

use of org.bitcoinj.core.TransactionInput in project bisq-core by bisq-network.

the class TradeWalletService method traderSignAndFinalizeDisputedPayoutTx.

/**
 * 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;
}
Also used : Script(org.bitcoinj.script.Script) TransactionOutput(org.bitcoinj.core.TransactionOutput) Transaction(org.bitcoinj.core.Transaction) Sha256Hash(org.bitcoinj.core.Sha256Hash) ECKey(org.bitcoinj.core.ECKey) TransactionSignature(org.bitcoinj.crypto.TransactionSignature) RawTransactionInput(bisq.core.btc.data.RawTransactionInput) TransactionInput(org.bitcoinj.core.TransactionInput)

Example 7 with TransactionInput

use of org.bitcoinj.core.TransactionInput in project bisq-core by bisq-network.

the class TradeWalletService method sellerSignsAndFinalizesPayoutTx.

/**
 * Buyer creates and signs payout transaction and adds signature of seller to complete the transaction
 *
 * @param depositTx                 Deposit transaction
 * @param buyerSignature            DER encoded canonical signature of seller
 * @param buyerPayoutAmount         Payout amount for buyer
 * @param sellerPayoutAmount        Payout amount for seller
 * @param buyerPayoutAddressString  Address for buyer
 * @param sellerPayoutAddressString Address for seller
 * @param multiSigKeyPair           Buyer's keypair for MultiSig
 * @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 payout transaction
 * @throws AddressFormatException
 * @throws TransactionVerificationException
 * @throws WalletException
 */
public Transaction sellerSignsAndFinalizesPayoutTx(Transaction depositTx, byte[] buyerSignature, Coin buyerPayoutAmount, Coin sellerPayoutAmount, String buyerPayoutAddressString, String sellerPayoutAddressString, DeterministicKey multiSigKeyPair, byte[] buyerPubKey, byte[] sellerPubKey, byte[] arbitratorPubKey) throws AddressFormatException, TransactionVerificationException, WalletException {
    log.trace("buyerSignsAndFinalizesPayoutTx called");
    log.trace("depositTx " + depositTx.toString());
    log.trace("buyerSignature r " + ECKey.ECDSASignature.decodeFromDER(buyerSignature).r.toString());
    log.trace("buyerSignature s " + ECKey.ECDSASignature.decodeFromDER(buyerSignature).s.toString());
    log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString());
    log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString());
    log.trace("buyerPayoutAddressString " + buyerPayoutAddressString);
    log.trace("sellerPayoutAddressString " + sellerPayoutAddressString);
    log.trace("multiSigKeyPair (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());
    Transaction payoutTx = createPayoutTx(depositTx, buyerPayoutAmount, sellerPayoutAmount, buyerPayoutAddressString, sellerPayoutAddressString);
    // MS redeemScript
    Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey);
    // MS output from prev. tx is index 0
    Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false);
    checkNotNull(multiSigKeyPair, "multiSigKeyPair must not be null");
    if (multiSigKeyPair.isEncrypted())
        checkNotNull(aesKey);
    ECKey.ECDSASignature sellerSignature = multiSigKeyPair.sign(sigHash, aesKey).toCanonicalised();
    TransactionSignature buyerTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(buyerSignature), Transaction.SigHash.ALL, false);
    TransactionSignature sellerTxSig = new TransactionSignature(sellerSignature, Transaction.SigHash.ALL, false);
    // Take care of order of signatures. Need to be reversed here. See comment below at getMultiSigRedeemScript (arbitrator, seller, buyer)
    Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(sellerTxSig, buyerTxSig), redeemScript);
    TransactionInput input = payoutTx.getInput(0);
    input.setScriptSig(inputScript);
    WalletService.printTx("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;
}
Also used : Script(org.bitcoinj.script.Script) Transaction(org.bitcoinj.core.Transaction) Sha256Hash(org.bitcoinj.core.Sha256Hash) ECKey(org.bitcoinj.core.ECKey) TransactionSignature(org.bitcoinj.crypto.TransactionSignature) RawTransactionInput(bisq.core.btc.data.RawTransactionInput) TransactionInput(org.bitcoinj.core.TransactionInput)

Example 8 with TransactionInput

use of org.bitcoinj.core.TransactionInput in project samourai-wallet-android by Samourai-Wallet.

the class BatchSendActivity method doSpend.

private void doSpend() {
    HashMap<String, BigInteger> receivers = new HashMap<String, BigInteger>();
    long amount = 0L;
    for (BatchSendUtil.BatchSend _data : data) {
        Log.d("BatchSendActivity", "output:" + _data.amount);
        Log.d("BatchSendActivity", "output:" + _data.addr);
        Log.d("BatchSendActivity", "output:" + _data.pcode);
        amount += _data.amount;
        receivers.put(_data.addr, BigInteger.valueOf(_data.amount));
    }
    Log.d("BatchSendActivity", "amount:" + amount);
    List<UTXO> utxos = APIFactory.getInstance(BatchSendActivity.this).getUtxos(true);
    Collections.sort(utxos, new UTXO.UTXOComparator());
    List<UTXO> selectedUTXO = new ArrayList<UTXO>();
    int p2pkh = 0;
    int p2wpkh = 0;
    long totalValueSelected = 0L;
    int totalSelected = 0;
    for (UTXO utxo : utxos) {
        Log.d("BatchSendActivity", "utxo value:" + utxo.getValue());
        selectedUTXO.add(utxo);
        totalValueSelected += utxo.getValue();
        totalSelected += utxo.getOutpoints().size();
        Pair<Integer, Integer> outpointTypes = FeeUtil.getInstance().getOutpointCount(utxo.getOutpoints());
        p2pkh += outpointTypes.getLeft();
        p2wpkh += outpointTypes.getRight();
        if (totalValueSelected >= (amount + SamouraiWallet.bDust.longValue() + FeeUtil.getInstance().estimatedFeeSegwit(p2pkh, p2wpkh, receivers.size() + 1).longValue())) {
            break;
        }
    }
    Log.d("BatchSendActivity", "totalSelected:" + totalSelected);
    Log.d("BatchSendActivity", "totalValueSelected:" + totalValueSelected);
    List<MyTransactionOutPoint> outpoints = new ArrayList<MyTransactionOutPoint>();
    for (UTXO utxo : selectedUTXO) {
        outpoints.addAll(utxo.getOutpoints());
        for (MyTransactionOutPoint out : utxo.getOutpoints()) {
            Log.d("BatchSendActivity", "outpoint hash:" + out.getTxHash().toString());
            Log.d("BatchSendActivity", "outpoint idx:" + out.getTxOutputN());
            Log.d("BatchSendActivity", "outpoint address:" + out.getAddress());
        }
    }
    Pair<Integer, Integer> outpointTypes = FeeUtil.getInstance().getOutpointCount(outpoints);
    BigInteger fee = FeeUtil.getInstance().estimatedFeeSegwit(outpointTypes.getLeft(), outpointTypes.getRight(), receivers.size() + 1);
    Log.d("BatchSendActivity", "fee:" + fee.longValue());
    if (amount + fee.longValue() > balance) {
        Toast.makeText(BatchSendActivity.this, R.string.insufficient_funds, Toast.LENGTH_SHORT).show();
        return;
    }
    long changeAmount = totalValueSelected - (amount + fee.longValue());
    String change_address = null;
    int change_idx = -1;
    if (changeAmount > 0L) {
        change_idx = BIP49Util.getInstance(BatchSendActivity.this).getWallet().getAccount(0).getChange().getAddrIdx();
        change_address = BIP49Util.getInstance(BatchSendActivity.this).getAddressAt(AddressFactory.CHANGE_CHAIN, change_idx).getAddressAsString();
        receivers.put(change_address, BigInteger.valueOf(changeAmount));
        Log.d("BatchSendActivity", "change output:" + changeAmount);
        Log.d("BatchSendActivity", "change output:" + change_address);
    }
    Transaction tx = SendFactory.getInstance(BatchSendActivity.this).makeTransaction(0, outpoints, receivers);
    if (tx != null) {
        final RBFSpend rbf;
        if (PrefsUtil.getInstance(BatchSendActivity.this).getValue(PrefsUtil.RBF_OPT_IN, false) == true) {
            rbf = new RBFSpend();
            for (TransactionInput input : tx.getInputs()) {
                boolean _isBIP49 = false;
                String _addr = null;
                Address _address = input.getConnectedOutput().getAddressFromP2PKHScript(SamouraiWallet.getInstance().getCurrentNetworkParams());
                if (_address != null) {
                    _addr = _address.toString();
                }
                if (_addr == null) {
                    _addr = input.getConnectedOutput().getAddressFromP2SH(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
                    _isBIP49 = true;
                }
                String path = APIFactory.getInstance(BatchSendActivity.this).getUnspentPaths().get(_addr);
                if (path != null) {
                    if (_isBIP49) {
                        rbf.addKey(input.getOutpoint().toString(), path + "/49");
                    } else {
                        rbf.addKey(input.getOutpoint().toString(), path);
                    }
                } else {
                    String pcode = BIP47Meta.getInstance().getPCode4Addr(_addr);
                    int idx = BIP47Meta.getInstance().getIdx4Addr(_addr);
                    rbf.addKey(input.getOutpoint().toString(), pcode + "/" + idx);
                }
            }
        } else {
            rbf = null;
        }
        String strChangeIsDust = "";
        String strPrivacyWarning = "";
        String strMessage = strChangeIsDust + strPrivacyWarning + "Send " + Coin.valueOf(amount).toPlainString() + " BTC. (fee:" + Coin.valueOf(fee.longValue()).toPlainString() + ")?\n";
        final long _change = changeAmount;
        final String _change_address = change_address;
        final int _change_idx = change_idx;
        tx = SendFactory.getInstance(BatchSendActivity.this).signTransaction(tx);
        final String hexTx = new String(Hex.encode(tx.bitcoinSerialize()));
        final String strTxHash = tx.getHashAsString();
        // Log.d("BatchSendActivity", "tx hash:" + tx.getHashAsString());
        // Log.d("BatchSendActivity", "hex signed tx:" + hexTx);
        AlertDialog.Builder dlg = new AlertDialog.Builder(BatchSendActivity.this).setTitle(R.string.app_name).setMessage(strMessage).setCancelable(false).setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {

            public void onClick(final DialogInterface dialog, int whichButton) {
                dialog.dismiss();
                if (PrefsUtil.getInstance(BatchSendActivity.this).getValue(PrefsUtil.BROADCAST_TX, true) == false) {
                    doShowTx(hexTx, strTxHash);
                    return;
                }
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        Looper.prepare();
                        boolean isOK = false;
                        String response = null;
                        try {
                            if (PrefsUtil.getInstance(BatchSendActivity.this).getValue(PrefsUtil.USE_TRUSTED_NODE, false) == true) {
                                if (TrustedNodeUtil.getInstance().isSet()) {
                                    response = PushTx.getInstance(BatchSendActivity.this).trustedNode(hexTx);
                                    JSONObject jsonObject = new org.json.JSONObject(response);
                                    if (jsonObject.has("result")) {
                                        if (jsonObject.getString("result").matches("^[A-Za-z0-9]{64}$")) {
                                            isOK = true;
                                        } else {
                                            Toast.makeText(BatchSendActivity.this, R.string.trusted_node_tx_error, Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                } else {
                                    Toast.makeText(BatchSendActivity.this, R.string.trusted_node_not_valid, Toast.LENGTH_SHORT).show();
                                }
                            } else {
                                response = PushTx.getInstance(BatchSendActivity.this).samourai(hexTx);
                                if (response != null) {
                                    JSONObject jsonObject = new org.json.JSONObject(response);
                                    if (jsonObject.has("status")) {
                                        if (jsonObject.getString("status").equals("ok")) {
                                            isOK = true;
                                        }
                                    }
                                } else {
                                    Toast.makeText(BatchSendActivity.this, R.string.pushtx_returns_null, Toast.LENGTH_SHORT).show();
                                }
                            }
                            if (isOK) {
                                BatchSendUtil.getInstance().clear();
                                if (PrefsUtil.getInstance(BatchSendActivity.this).getValue(PrefsUtil.USE_TRUSTED_NODE, false) == false) {
                                    Toast.makeText(BatchSendActivity.this, R.string.tx_sent, Toast.LENGTH_SHORT).show();
                                } else {
                                    Toast.makeText(BatchSendActivity.this, R.string.trusted_node_tx_sent, Toast.LENGTH_SHORT).show();
                                }
                                if (_change > 0L) {
                                    BIP49Util.getInstance(BatchSendActivity.this).getWallet().getAccount(0).getChange().incAddrIdx();
                                }
                                if (PrefsUtil.getInstance(BatchSendActivity.this).getValue(PrefsUtil.RBF_OPT_IN, false) == true) {
                                    if (_change > 0L && _change_address != null) {
                                        rbf.addChangeAddr(_change_address);
                                    }
                                    rbf.setHash(strTxHash);
                                    rbf.setSerializedTx(hexTx);
                                    RBFUtil.getInstance().add(rbf);
                                }
                                for (BatchSendUtil.BatchSend d : data) {
                                    String address = d.addr;
                                    String pcode = d.pcode;
                                    // increment counter if BIP47 spend
                                    if (pcode != null && pcode.length() > 0) {
                                        BIP47Meta.getInstance().getPCode4AddrLookup().put(address, pcode);
                                        BIP47Meta.getInstance().inc(pcode);
                                        SimpleDateFormat sd = new SimpleDateFormat("dd MMM");
                                        String strTS = sd.format(currentTimeMillis());
                                        String event = strTS + " " + BatchSendActivity.this.getString(R.string.sent) + " " + MonetaryUtil.getInstance().getBTCFormat().format((double) d.amount / 1e8) + " BTC";
                                        BIP47Meta.getInstance().setLatestEvent(strPCode, event);
                                    }
                                }
                                /*
                            if(strPrivacyWarning.length() > 0 && cbShowAgain != null)    {
                                SendAddressUtil.getInstance().add(address, cbShowAgain.isChecked() ? false : true);
                            }
                            else if(SendAddressUtil.getInstance().get(address) == 0)    {
                                SendAddressUtil.getInstance().add(address, false);
                            }
                            else    {
                                SendAddressUtil.getInstance().add(address, true);
                            }
                            */
                                /*
                                            Intent intent = new Intent("com.samourai.wallet.BalanceFragment.REFRESH");
                                            intent.putExtra("notifTx", false);
                                            intent.putExtra("fetch", true);
                                            LocalBroadcastManager.getInstance(BatchSendActivity.this).sendBroadcast(intent);
                                            */
                                View view = BatchSendActivity.this.getCurrentFocus();
                                if (view != null) {
                                    InputMethodManager imm = (InputMethodManager) BatchSendActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE);
                                    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                                }
                                Intent _intent = new Intent(BatchSendActivity.this, BalanceActivity.class);
                                _intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                                startActivity(_intent);
                            } else {
                                Toast.makeText(BatchSendActivity.this, R.string.tx_failed, Toast.LENGTH_SHORT).show();
                                // reset change index upon tx fail
                                BIP49Util.getInstance(BatchSendActivity.this).getWallet().getAccount(0).getChange().setAddrIdx(_change_idx);
                            }
                        } catch (JSONException je) {
                            Toast.makeText(BatchSendActivity.this, "pushTx:" + je.getMessage(), Toast.LENGTH_SHORT).show();
                        } catch (DecoderException de) {
                            Toast.makeText(BatchSendActivity.this, "pushTx:" + de.getMessage(), Toast.LENGTH_SHORT).show();
                        } finally {
                        /*
                        BatchSendActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                btSend.setActivated(true);
                                btSend.setClickable(true);
                                progress.dismiss();
                                dialog.dismiss();
                            }
                        });
                        */
                        }
                        Looper.loop();
                    }
                }).start();
            }
        }).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.dismiss();
            }
        });
        if (!isFinishing()) {
            dlg.show();
        }
    } else {
        // Log.d("SendActivity", "tx error");
        Toast.makeText(BatchSendActivity.this, "tx error", Toast.LENGTH_SHORT).show();
    }
}
Also used : AlertDialog(android.app.AlertDialog) Address(org.bitcoinj.core.Address) PaymentAddress(com.samourai.wallet.bip47.rpc.PaymentAddress) HashMap(java.util.HashMap) BatchSendUtil(com.samourai.wallet.util.BatchSendUtil) DialogInterface(android.content.DialogInterface) ArrayList(java.util.ArrayList) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) InputMethodManager(android.view.inputmethod.InputMethodManager) TransactionInput(org.bitcoinj.core.TransactionInput) RBFSpend(com.samourai.wallet.send.RBFSpend) JSONException(org.json.JSONException) Intent(android.content.Intent) ImageView(android.widget.ImageView) View(android.view.View) AdapterView(android.widget.AdapterView) TextView(android.widget.TextView) ListView(android.widget.ListView) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) Point(android.graphics.Point) BigInteger(java.math.BigInteger) UTXO(com.samourai.wallet.send.UTXO) BlockedUTXO(com.samourai.wallet.send.BlockedUTXO) DecoderException(org.bouncycastle.util.encoders.DecoderException) Transaction(org.bitcoinj.core.Transaction) JSONObject(org.json.JSONObject) BigInteger(java.math.BigInteger) SimpleDateFormat(java.text.SimpleDateFormat)

Example 9 with TransactionInput

use of org.bitcoinj.core.TransactionInput in project samourai-wallet-android by Samourai-Wallet.

the class BatchSendActivity method markUTXOAsUnspendable.

private void markUTXOAsUnspendable(String hexTx) {
    HashMap<String, Long> utxos = new HashMap<String, Long>();
    for (UTXO utxo : APIFactory.getInstance(BatchSendActivity.this).getUtxos(true)) {
        for (MyTransactionOutPoint outpoint : utxo.getOutpoints()) {
            utxos.put(outpoint.getTxHash().toString() + "-" + outpoint.getTxOutputN(), outpoint.getValue().longValue());
        }
    }
    Transaction tx = new Transaction(SamouraiWallet.getInstance().getCurrentNetworkParams(), Hex.decode(hexTx));
    for (TransactionInput input : tx.getInputs()) {
        BlockedUTXO.getInstance().add(input.getOutpoint().getHash().toString(), (int) input.getOutpoint().getIndex(), utxos.get(input.getOutpoint().getHash().toString() + "-" + (int) input.getOutpoint().getIndex()));
    }
}
Also used : UTXO(com.samourai.wallet.send.UTXO) BlockedUTXO(com.samourai.wallet.send.BlockedUTXO) Transaction(org.bitcoinj.core.Transaction) HashMap(java.util.HashMap) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) TransactionInput(org.bitcoinj.core.TransactionInput)

Example 10 with TransactionInput

use of org.bitcoinj.core.TransactionInput in project samourai-wallet-android by Samourai-Wallet.

the class RicochetMeta method getHopTx.

private Transaction getHopTx(String prevTxHash, int prevTxN, String scriptPubKey, int prevIndex, long spendAmount, String destination) {
    Transaction tx = null;
    HD_Address address = null;
    try {
        address = HD_WalletFactory.getInstance(context).get().getAccountAt(RICOCHET_ACCOUNT).getChain(0).getAddressAt(prevIndex);
        ECKey ecKey = address.getECKey();
        // Log.d("RicochetMeta", "getHopTx address:" + ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString());
        byte[] hashBytes = Hex.decode(prevTxHash);
        Sha256Hash txHash = new Sha256Hash(hashBytes);
        TransactionOutPoint outpoint = new TransactionOutPoint(SamouraiWallet.getInstance().getCurrentNetworkParams(), prevTxN, txHash);
        TransactionInput input = new TransactionInput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, Hex.decode(scriptPubKey), outpoint);
        Script outputScript = null;
        TransactionOutput output = null;
        if (destination.toLowerCase().startsWith("tb") || destination.toLowerCase().startsWith("bc")) {
            byte[] bScriptPubKey = null;
            try {
                Pair<Byte, byte[]> pair = Bech32Segwit.decode(SamouraiWallet.getInstance().isTestNet() ? "tb" : "bc", destination);
                bScriptPubKey = Bech32Segwit.getScriptPubkey(pair.getLeft(), pair.getRight());
            } catch (Exception e) {
                return null;
            }
            output = new TransactionOutput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, Coin.valueOf(spendAmount), bScriptPubKey);
        } else {
            outputScript = ScriptBuilder.createOutputScript(org.bitcoinj.core.Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), destination));
            output = new TransactionOutput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, Coin.valueOf(spendAmount), outputScript.getProgram());
        }
        tx = new Transaction(SamouraiWallet.getInstance().getCurrentNetworkParams());
        tx.addInput(input);
        tx.addOutput(output);
        TransactionSignature sig = tx.calculateSignature(0, ecKey, Hex.decode(scriptPubKey), Transaction.SigHash.ALL, false);
        tx.getInput(0).setScriptSig(ScriptBuilder.createInputScript(sig, ecKey));
    } catch (IOException ioe) {
        return null;
    } catch (MnemonicException.MnemonicLengthException mle) {
        return null;
    }
    return tx;
}
Also used : Script(org.bitcoinj.script.Script) TransactionOutput(org.bitcoinj.core.TransactionOutput) HD_Address(com.samourai.wallet.hd.HD_Address) Sha256Hash(org.bitcoinj.core.Sha256Hash) ECKey(org.bitcoinj.core.ECKey) TransactionSignature(org.bitcoinj.crypto.TransactionSignature) IOException(java.io.IOException) TransactionInput(org.bitcoinj.core.TransactionInput) MnemonicException(org.bitcoinj.crypto.MnemonicException) JSONException(org.json.JSONException) IOException(java.io.IOException) MnemonicException(org.bitcoinj.crypto.MnemonicException) Transaction(org.bitcoinj.core.Transaction) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint)

Aggregations

TransactionInput (org.bitcoinj.core.TransactionInput)36 Transaction (org.bitcoinj.core.Transaction)29 TransactionOutput (org.bitcoinj.core.TransactionOutput)20 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)18 Script (org.bitcoinj.script.Script)16 ECKey (org.bitcoinj.core.ECKey)11 HashMap (java.util.HashMap)10 Address (org.bitcoinj.core.Address)9 Coin (org.bitcoinj.core.Coin)9 ArrayList (java.util.ArrayList)7 AddressFormatException (org.bitcoinj.core.AddressFormatException)7 RawTransactionInput (bisq.core.btc.data.RawTransactionInput)6 TransactionSignature (org.bitcoinj.crypto.TransactionSignature)6 ScriptException (org.bitcoinj.script.ScriptException)6 MyTransactionOutPoint (com.samourai.wallet.send.MyTransactionOutPoint)5 IOException (java.io.IOException)5 Sha256Hash (org.bitcoinj.core.Sha256Hash)5 MnemonicException (org.bitcoinj.crypto.MnemonicException)5 SendRequest (org.bitcoinj.wallet.SendRequest)5 BlockedUTXO (com.samourai.wallet.send.BlockedUTXO)4