Search in sources :

Example 16 with TransactionSignature

use of org.bitcoinj.crypto.TransactionSignature in project samourai-wallet-android by Samourai-Wallet.

the class RicochetMeta method getHopTx.

private Transaction getHopTx(String prevTxHash, int prevTxN, int prevIndex, long prevSpendAmount, long spendAmount, String destination, Pair<String, Long> samouraiFeePair, long nTimeLock) {
    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 {
        Script outputScript = ScriptBuilder.createOutputScript(org.bitcoinj.core.Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), destination));
        output = new TransactionOutput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, Coin.valueOf(spendAmount), outputScript.getProgram());
    }
    HD_Address address = BIP84Util.getInstance(context).getWallet().getAccountAt(RICOCHET_ACCOUNT).getChain(AddressFactory.RECEIVE_CHAIN).getAddressAt(prevIndex);
    ECKey ecKey = address.getECKey();
    SegwitAddress p2wpkh = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
    Script redeemScript = p2wpkh.segWitRedeemScript();
    Transaction tx = new Transaction(SamouraiWallet.getInstance().getCurrentNetworkParams());
    if (nTimeLock > 0L) {
        tx.setLockTime(nTimeLock);
    }
    tx.addOutput(output);
    if (samouraiFeePair != null) {
        byte[] bScriptPubKey = null;
        try {
            Pair<Byte, byte[]> pair = Bech32Segwit.decode(SamouraiWallet.getInstance().isTestNet() ? "tb" : "bc", samouraiFeePair.getLeft());
            bScriptPubKey = Bech32Segwit.getScriptPubkey(pair.getLeft(), pair.getRight());
        } catch (Exception e) {
            return null;
        }
        TransactionOutput _output = new TransactionOutput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, Coin.valueOf(samouraiFeePair.getRight()), bScriptPubKey);
        tx.addOutput(_output);
    }
    // Log.d("RicochetMeta", "spending from:" + p2wpkh.getBech32AsString());
    // Log.d("RicochetMeta", "pubkey:" + Hex.toHexString(ecKey.getPubKey()));
    Sha256Hash txHash = Sha256Hash.wrap(prevTxHash);
    TransactionOutPoint outPoint = new TransactionOutPoint(SamouraiWallet.getInstance().getCurrentNetworkParams(), prevTxN, txHash, Coin.valueOf(prevSpendAmount));
    TransactionInput txInput = new TransactionInput(SamouraiWallet.getInstance().getCurrentNetworkParams(), null, new byte[] {}, outPoint, Coin.valueOf(prevSpendAmount));
    if (PrefsUtil.getInstance(context).getValue(PrefsUtil.RBF_OPT_IN, false) == true) {
        txInput.setSequenceNumber(SamouraiWallet.RBF_SEQUENCE_VAL.longValue());
    }
    tx.addInput(txInput);
    TransactionSignature sig = tx.calculateWitnessSignature(0, ecKey, redeemScript.scriptCode(), Coin.valueOf(prevSpendAmount), Transaction.SigHash.ALL, false);
    final TransactionWitness witness = new TransactionWitness(2);
    witness.setPush(0, sig.encodeToBitcoin());
    witness.setPush(1, ecKey.getPubKey());
    tx.setWitness(0, witness);
    assert (0 == tx.getInput(0).getScriptBytes().length);
    // Log.d("RicochetMeta", "script sig length:" + tx.getInput(0).getScriptBytes().length);
    tx.verify();
    return tx;
}
Also used : Script(org.bitcoinj.script.Script) TransactionOutput(org.bitcoinj.core.TransactionOutput) TransactionWitness(org.bitcoinj.core.TransactionWitness) HD_Address(com.samourai.wallet.hd.HD_Address) SegwitAddress(com.samourai.wallet.segwit.SegwitAddress) Sha256Hash(org.bitcoinj.core.Sha256Hash) ECKey(org.bitcoinj.core.ECKey) TransactionSignature(org.bitcoinj.crypto.TransactionSignature) JSONException(org.json.JSONException) ScriptException(org.bitcoinj.script.ScriptException) MnemonicException(org.bitcoinj.crypto.MnemonicException) IOException(java.io.IOException) MyTransactionInput(com.samourai.wallet.send.MyTransactionInput) TransactionInput(org.bitcoinj.core.TransactionInput) Transaction(org.bitcoinj.core.Transaction) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint)

Example 17 with TransactionSignature

use of org.bitcoinj.crypto.TransactionSignature in project samourai-wallet-android by Samourai-Wallet.

the class Cahoots method signTx.

protected void signTx(HashMap<String, ECKey> keyBag) {
    Transaction transaction = psbt.getTransaction();
    debug("Cahoots", "signTx:" + transaction.toString());
    for (int i = 0; i < transaction.getInputs().size(); i++) {
        TransactionInput input = transaction.getInput(i);
        TransactionOutPoint outpoint = input.getOutpoint();
        if (keyBag.containsKey(outpoint.toString())) {
            debug("Cahoots", "signTx outpoint:" + outpoint.toString());
            ECKey key = keyBag.get(outpoint.toString());
            SegwitAddress segwitAddress = new SegwitAddress(key.getPubKey(), params);
            debug("Cahoots", "signTx bech32:" + segwitAddress.getBech32AsString());
            final Script redeemScript = segwitAddress.segWitRedeemScript();
            final Script scriptCode = redeemScript.scriptCode();
            long value = outpoints.get(outpoint.getHash().toString() + "-" + outpoint.getIndex());
            debug("Cahoots", "signTx value:" + value);
            TransactionSignature sig = transaction.calculateWitnessSignature(i, key, scriptCode, Coin.valueOf(value), Transaction.SigHash.ALL, false);
            final TransactionWitness witness = new TransactionWitness(2);
            witness.setPush(0, sig.encodeToBitcoin());
            witness.setPush(1, key.getPubKey());
            transaction.setWitness(i, witness);
        }
    }
    psbt.setTransaction(transaction);
}
Also used : Script(org.bitcoinj.script.Script) SegwitAddress(com.samourai.wallet.segwit.SegwitAddress) TransactionSignature(org.bitcoinj.crypto.TransactionSignature)

Example 18 with TransactionSignature

use of org.bitcoinj.crypto.TransactionSignature in project samourai-wallet-android by Samourai-Wallet.

the class AndroidTx0Service method signTx0.

@Override
protected void signTx0(Transaction tx, Collection<UnspentOutputWithKey> inputs, NetworkParameters params) {
    int idx = 0;
    for (UnspentOutputWithKey input : inputs) {
        String address = input.addr;
        ECKey spendFromKey = ECKey.fromPrivate(input.getKey());
        // sign input
        if (FormatsUtil.getInstance().isValidBech32(address) || Address.fromBase58(params, address).isP2SHAddress()) {
            SegwitAddress segwitAddress = new SegwitAddress(spendFromKey.getPubKey(), params);
            final Script redeemScript = segwitAddress.segWitRedeemScript();
            final Script scriptCode = redeemScript.scriptCode();
            TransactionSignature sig = tx.calculateWitnessSignature(idx, spendFromKey, scriptCode, Coin.valueOf(input.value), Transaction.SigHash.ALL, false);
            final TransactionWitness witness = new TransactionWitness(2);
            witness.setPush(0, sig.encodeToBitcoin());
            witness.setPush(1, spendFromKey.getPubKey());
            tx.setWitness(idx, witness);
            if (!FormatsUtil.getInstance().isValidBech32(address) && Address.fromBase58(params, address).isP2SHAddress()) {
                final ScriptBuilder sigScript = new ScriptBuilder();
                sigScript.data(redeemScript.getProgram());
                tx.getInput(idx).setScriptSig(sigScript.build());
            // tx.getInput(idx).getScriptSig().correctlySpends(tx, idx, new Script(Hex.decode(input.script)), Coin.valueOf(input.value), Script.ALL_VERIFY_FLAGS);
            }
        } else {
            TransactionSignature sig = tx.calculateSignature(idx, spendFromKey, new Script(Hex.decode(input.script)), Transaction.SigHash.ALL, false);
            tx.getInput(idx).setScriptSig(ScriptBuilder.createInputScript(sig, spendFromKey));
        }
        idx++;
    }
    super.signTx0(tx, inputs, params);
}
Also used : Script(org.bitcoinj.script.Script) TransactionWitness(org.bitcoinj.core.TransactionWitness) SegwitAddress(com.samourai.wallet.segwit.SegwitAddress) ECKey(org.bitcoinj.core.ECKey) TransactionSignature(org.bitcoinj.crypto.TransactionSignature) ScriptBuilder(org.bitcoinj.script.ScriptBuilder) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint)

Example 19 with TransactionSignature

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

the class WalletService method signTransactionInput.

// /////////////////////////////////////////////////////////////////////////////////////////
// Sign tx
// /////////////////////////////////////////////////////////////////////////////////////////
public static void signTransactionInput(Wallet wallet, KeyParameter aesKey, Transaction tx, TransactionInput txIn, int index) {
    KeyBag maybeDecryptingKeyBag = new DecryptingKeyBag(wallet, aesKey);
    if (txIn.getConnectedOutput() != null) {
        try {
            // We assume if its already signed, its hopefully got a SIGHASH type that will not invalidate when
            // we sign missing pieces (to check this would require either assuming any signatures are signing
            // standard output types or a way to get processed signatures out of script execution)
            txIn.getScriptSig().correctlySpends(tx, index, txIn.getConnectedOutput().getScriptPubKey(), Script.ALL_VERIFY_FLAGS);
            log.warn("Input {} already correctly spends output, assuming SIGHASH type used will be safe and skipping signing.", index);
            return;
        } catch (ScriptException e) {
        // Expected.
        }
        Script scriptPubKey = txIn.getConnectedOutput().getScriptPubKey();
        RedeemData redeemData = txIn.getConnectedRedeemData(maybeDecryptingKeyBag);
        checkNotNull(redeemData, "Transaction exists in wallet that we cannot redeem: %s", txIn.getOutpoint().getHash());
        txIn.setScriptSig(scriptPubKey.createEmptyInputScript(redeemData.keys.get(0), redeemData.redeemScript));
        TransactionSigner.ProposedTransaction propTx = new TransactionSigner.ProposedTransaction(tx);
        Transaction partialTx = propTx.partialTx;
        txIn = partialTx.getInput(index);
        if (txIn.getConnectedOutput() != null) {
            // If we dont have a sig we don't do the check to avoid error reports of failed sig checks
            final List<ScriptChunk> chunks = txIn.getConnectedOutput().getScriptPubKey().getChunks();
            if (!chunks.isEmpty() && chunks.get(0).data != null && chunks.get(0).data.length > 0) {
                try {
                    // We assume if its already signed, its hopefully got a SIGHASH type that will not invalidate when
                    // we sign missing pieces (to check this would require either assuming any signatures are signing
                    // standard output types or a way to get processed signatures out of script execution)
                    txIn.getScriptSig().correctlySpends(tx, index, txIn.getConnectedOutput().getScriptPubKey(), Script.ALL_VERIFY_FLAGS);
                    log.warn("Input {} already correctly spends output, assuming SIGHASH type used will be safe and skipping signing.", index);
                    return;
                } catch (ScriptException e) {
                // Expected.
                }
            }
            redeemData = txIn.getConnectedRedeemData(maybeDecryptingKeyBag);
            scriptPubKey = txIn.getConnectedOutput().getScriptPubKey();
            checkNotNull(redeemData, "redeemData must not be null");
            ECKey pubKey = redeemData.keys.get(0);
            if (pubKey instanceof DeterministicKey)
                propTx.keyPaths.put(scriptPubKey, (((DeterministicKey) pubKey).getPath()));
            ECKey key;
            if ((key = redeemData.getFullKey()) == null) {
                log.warn("No local key found for input {}", index);
                return;
            }
            Script inputScript = txIn.getScriptSig();
            byte[] script = redeemData.redeemScript.getProgram();
            try {
                TransactionSignature signature = partialTx.calculateSignature(index, key, script, Transaction.SigHash.ALL, false);
                inputScript = scriptPubKey.getScriptSigWithSignature(inputScript, signature.encodeToBitcoin(), 0);
                txIn.setScriptSig(inputScript);
            } catch (ECKey.KeyIsEncryptedException e1) {
                throw e1;
            } catch (ECKey.MissingPrivateKeyException e1) {
                log.warn("No private key in keypair for input {}", index);
            }
        } else {
            log.warn("Missing connected output, assuming input {} is already signed.", index);
        }
    } else {
        log.error("Missing connected output, assuming already signed.");
    }
}
Also used : Script(org.bitcoinj.script.Script) TransactionSigner(org.bitcoinj.signers.TransactionSigner) ECKey(org.bitcoinj.core.ECKey) TransactionSignature(org.bitcoinj.crypto.TransactionSignature) KeyBag(org.bitcoinj.wallet.KeyBag) DecryptingKeyBag(org.bitcoinj.wallet.DecryptingKeyBag) RedeemData(org.bitcoinj.wallet.RedeemData) ScriptChunk(org.bitcoinj.script.ScriptChunk) DecryptingKeyBag(org.bitcoinj.wallet.DecryptingKeyBag) ScriptException(org.bitcoinj.core.ScriptException) Transaction(org.bitcoinj.core.Transaction) DeterministicKey(org.bitcoinj.crypto.DeterministicKey)

Aggregations

TransactionSignature (org.bitcoinj.crypto.TransactionSignature)19 Script (org.bitcoinj.script.Script)17 ECKey (org.bitcoinj.core.ECKey)13 TransactionInput (org.bitcoinj.core.TransactionInput)9 Sha256Hash (org.bitcoinj.core.Sha256Hash)8 Transaction (org.bitcoinj.core.Transaction)7 TransactionOutput (org.bitcoinj.core.TransactionOutput)7 SegwitAddress (com.samourai.wallet.segwit.SegwitAddress)5 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)5 TransactionWitness (org.bitcoinj.core.TransactionWitness)5 RawTransactionInput (bisq.core.btc.data.RawTransactionInput)4 MyTransactionOutPoint (com.samourai.wallet.send.MyTransactionOutPoint)4 IOException (java.io.IOException)4 MnemonicException (org.bitcoinj.crypto.MnemonicException)4 ScriptBuilder (org.bitcoinj.script.ScriptBuilder)4 HD_Address (com.samourai.wallet.hd.HD_Address)3 RawTransactionInput (io.bitsquare.btc.data.RawTransactionInput)3 ScriptException (org.bitcoinj.script.ScriptException)3 JSONException (org.json.JSONException)3 MyTransactionInput (com.samourai.wallet.send.MyTransactionInput)2