Search in sources :

Example 11 with HD_Address

use of com.samourai.wallet.hd.HD_Address in project samourai-wallet-android by Samourai-Wallet.

the class RBFTask method signTx.

private Transaction signTx(Transaction tx) {
    HashMap<String, ECKey> keyBag = new HashMap<String, ECKey>();
    HashMap<String, ECKey> keyBag49 = new HashMap<String, ECKey>();
    HashMap<String, ECKey> keyBag84 = new HashMap<String, ECKey>();
    HashMap<String, String> keys = rbf.getKeyBag();
    for (String outpoint : keys.keySet()) {
        ECKey ecKey = null;
        String[] s = keys.get(outpoint).split("/");
        Log.i("RBF", "path length:" + s.length);
        if (s.length == 4) {
            if (s[3].equals("84")) {
                HD_Address addr = BIP84Util.getInstance(activity).getWallet().getAccount(0).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
                ecKey = addr.getECKey();
            } else {
                HD_Address addr = BIP49Util.getInstance(activity).getWallet().getAccount(0).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
                ecKey = addr.getECKey();
            }
        } else if (s.length == 3) {
            HD_Address hd_address = AddressFactory.getInstance(activity).get(0, Integer.parseInt(s[1]), Integer.parseInt(s[2]));
            String strPrivKey = hd_address.getPrivateKeyString();
            DumpedPrivateKey pk = new DumpedPrivateKey(SamouraiWallet.getInstance().getCurrentNetworkParams(), strPrivKey);
            ecKey = pk.getKey();
        } else if (s.length == 2) {
            try {
                PaymentAddress address = BIP47Util.getInstance(activity).getReceiveAddress(new PaymentCode(s[0]), Integer.parseInt(s[1]));
                ecKey = address.getReceiveECKey();
            } catch (Exception e) {
                ;
            }
        } else {
            ;
        }
        Log.i("RBF", "outpoint:" + outpoint);
        Log.i("RBF", "path:" + keys.get(outpoint));
        if (ecKey != null) {
            if (s.length == 4) {
                if (s[3].equals("84")) {
                    keyBag84.put(outpoint, ecKey);
                } else {
                    keyBag49.put(outpoint, ecKey);
                }
            } else {
                keyBag.put(outpoint, ecKey);
            }
        } else {
            throw new RuntimeException("ECKey error: cannot process private key");
        // Log.i("ECKey error", "cannot process private key");
        }
    }
    List<TransactionInput> inputs = tx.getInputs();
    for (int i = 0; i < inputs.size(); i++) {
        ECKey ecKey = null;
        String address = null;
        if (inputs.get(i).getValue() != null || keyBag49.containsKey(inputs.get(i).getOutpoint().toString()) || keyBag84.containsKey(inputs.get(i).getOutpoint().toString())) {
            if (keyBag84.containsKey(inputs.get(i).getOutpoint().toString())) {
                ecKey = keyBag84.get(inputs.get(i).getOutpoint().toString());
                SegwitAddress segwitAddress = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
                address = segwitAddress.getBech32AsString();
            } else {
                ecKey = keyBag49.get(inputs.get(i).getOutpoint().toString());
                SegwitAddress segwitAddress = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
                address = segwitAddress.getAddressAsString();
            }
        } else {
            ecKey = keyBag.get(inputs.get(i).getOutpoint().toString());
            address = ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
        }
        Log.d("RBF", "pubKey:" + Hex.toHexString(ecKey.getPubKey()));
        Log.d("RBF", "address:" + address);
        if (inputs.get(i).getValue() != null || keyBag49.containsKey(inputs.get(i).getOutpoint().toString()) || keyBag84.containsKey(inputs.get(i).getOutpoint().toString())) {
            final SegwitAddress segwitAddress = new SegwitAddress(ecKey.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
            Script scriptPubKey = segwitAddress.segWitOutputScript();
            final Script redeemScript = segwitAddress.segWitRedeemScript();
            System.out.println("redeem script:" + Hex.toHexString(redeemScript.getProgram()));
            final Script scriptCode = redeemScript.scriptCode();
            System.out.println("script code:" + Hex.toHexString(scriptCode.getProgram()));
            TransactionSignature sig = tx.calculateWitnessSignature(i, ecKey, scriptCode, Coin.valueOf(input_values.get(inputs.get(i).getOutpoint().toString())), Transaction.SigHash.ALL, false);
            final TransactionWitness witness = new TransactionWitness(2);
            witness.setPush(0, sig.encodeToBitcoin());
            witness.setPush(1, ecKey.getPubKey());
            tx.setWitness(i, witness);
            if (!FormatsUtil.getInstance().isValidBech32(address) && Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
                final ScriptBuilder sigScript = new ScriptBuilder();
                sigScript.data(redeemScript.getProgram());
                tx.getInput(i).setScriptSig(sigScript.build());
                tx.getInput(i).getScriptSig().correctlySpends(tx, i, scriptPubKey, Coin.valueOf(input_values.get(inputs.get(i).getOutpoint().toString())), Script.ALL_VERIFY_FLAGS);
            }
        } else {
            Log.i("RBF", "sign outpoint:" + inputs.get(i).getOutpoint().toString());
            Log.i("RBF", "ECKey address from keyBag:" + ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString());
            Log.i("RBF", "script:" + ScriptBuilder.createOutputScript(ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams())));
            Log.i("RBF", "script:" + Hex.toHexString(ScriptBuilder.createOutputScript(ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams())).getProgram()));
            TransactionSignature sig = tx.calculateSignature(i, ecKey, ScriptBuilder.createOutputScript(ecKey.toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams())).getProgram(), Transaction.SigHash.ALL, false);
            tx.getInput(i).setScriptSig(ScriptBuilder.createInputScript(sig, ecKey));
        }
    }
    return tx;
}
Also used : Script(org.bitcoinj.script.Script) PaymentCode(com.samourai.wallet.bip47.rpc.PaymentCode) TransactionWitness(org.bitcoinj.core.TransactionWitness) HD_Address(com.samourai.wallet.hd.HD_Address) HashMap(java.util.HashMap) SegwitAddress(com.samourai.wallet.segwit.SegwitAddress) ECKey(org.bitcoinj.core.ECKey) TransactionSignature(org.bitcoinj.crypto.TransactionSignature) ScriptBuilder(org.bitcoinj.script.ScriptBuilder) PaymentAddress(com.samourai.wallet.bip47.rpc.PaymentAddress) JSONException(org.json.JSONException) DecoderException(org.bouncycastle.util.encoders.DecoderException) MnemonicException(org.bitcoinj.crypto.MnemonicException) IOException(java.io.IOException) MyTransactionInput(com.samourai.wallet.send.MyTransactionInput) TransactionInput(org.bitcoinj.core.TransactionInput) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) DumpedPrivateKey(org.bitcoinj.core.DumpedPrivateKey)

Example 12 with HD_Address

use of com.samourai.wallet.hd.HD_Address in project samourai-wallet-android by Samourai-Wallet.

the class SendFactory method getPrivKey.

public static ECKey getPrivKey(String address, int account) {
    // debug("SendFactory", "get privkey for:" + address);
    ECKey ecKey = null;
    try {
        String path = APIFactory.getInstance(context).getUnspentPaths().get(address);
        debug("SendFactory", "address path:" + path);
        if (path != null) {
            String[] s = path.split("/");
            if (FormatsUtil.getInstance().isValidBech32(address)) {
                debug("SendFactory", "address type:" + "bip84");
                HD_Address addr = null;
                if (account == 0) {
                    addr = BIP84Util.getInstance(context).getWallet().getAccount(account).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
                } else {
                    addr = BIP84Util.getInstance(context).getWallet().getAccountAt(account).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
                }
                ecKey = addr.getECKey();
            } else if (Address.fromBase58(SamouraiWallet.getInstance().getCurrentNetworkParams(), address).isP2SHAddress()) {
                debug("SendFactory", "address type:" + "bip49");
                HD_Address addr = BIP49Util.getInstance(context).getWallet().getAccount(0).getChain(Integer.parseInt(s[1])).getAddressAt(Integer.parseInt(s[2]));
                ecKey = addr.getECKey();
            } else {
                debug("SendFactory", "address type:" + "bip44");
                int account_no = APIFactory.getInstance(context).getUnspentAccounts().get(address);
                HD_Address hd_address = AddressFactory.getInstance(context).get(account_no, Integer.parseInt(s[1]), Integer.parseInt(s[2]));
                String strPrivKey = hd_address.getPrivateKeyString();
                DumpedPrivateKey pk = new DumpedPrivateKey(SamouraiWallet.getInstance().getCurrentNetworkParams(), strPrivKey);
                ecKey = pk.getKey();
            }
        } else {
            debug("SendFactory", "address type:" + "bip47");
            debug("SendFactory", "address:" + address);
            String pcode = BIP47Meta.getInstance().getPCode4Addr(address);
            debug("SendFactory", "pcode:" + pcode);
            int idx = BIP47Meta.getInstance().getIdx4Addr(address);
            PaymentAddress addr = BIP47Util.getInstance(context).getReceiveAddress(new PaymentCode(pcode), idx);
            ecKey = addr.getReceiveECKey();
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
    return ecKey;
}
Also used : PaymentCode(com.samourai.wallet.bip47.rpc.PaymentCode) HD_Address(com.samourai.wallet.hd.HD_Address) ECKey(org.bitcoinj.core.ECKey) PaymentAddress(com.samourai.wallet.bip47.rpc.PaymentAddress) DumpedPrivateKey(org.bitcoinj.core.DumpedPrivateKey) ScriptException(org.bitcoinj.script.ScriptException) AddressFormatException(org.bitcoinj.core.AddressFormatException) MnemonicException(org.bitcoinj.crypto.MnemonicException) IOException(java.io.IOException)

Example 13 with HD_Address

use of com.samourai.wallet.hd.HD_Address in project samourai-wallet-android by Samourai-Wallet.

the class RicochetMeta method getDestinationAddress.

private String getDestinationAddress(int idx) {
    HD_Address hd_addr = BIP84Util.getInstance(context).getWallet().getAccountAt(RICOCHET_ACCOUNT).getChain(AddressFactory.RECEIVE_CHAIN).getAddressAt(idx);
    SegwitAddress segwitAddress = new SegwitAddress(hd_addr.getECKey().getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
    String address = segwitAddress.getBech32AsString();
    return address;
}
Also used : HD_Address(com.samourai.wallet.hd.HD_Address) SegwitAddress(com.samourai.wallet.segwit.SegwitAddress)

Example 14 with HD_Address

use of com.samourai.wallet.hd.HD_Address 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 15 with HD_Address

use of com.samourai.wallet.hd.HD_Address in project samourai-wallet-android by Samourai-Wallet.

the class BIP49Util method getAddressAt.

public SegwitAddress getAddressAt(int chain, int idx) {
    HD_Address addr = getWallet().getAccount(0).getChain(chain).getAddressAt(idx);
    SegwitAddress p2shp2wpkh = new SegwitAddress(addr.getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
    return p2shp2wpkh;
}
Also used : HD_Address(com.samourai.wallet.hd.HD_Address)

Aggregations

HD_Address (com.samourai.wallet.hd.HD_Address)17 ECKey (org.bitcoinj.core.ECKey)11 SegwitAddress (com.samourai.wallet.segwit.SegwitAddress)10 IOException (java.io.IOException)9 MnemonicException (org.bitcoinj.crypto.MnemonicException)9 JSONException (org.json.JSONException)7 HashMap (java.util.HashMap)5 AddressFormatException (org.bitcoinj.core.AddressFormatException)5 MyTransactionOutPoint (com.samourai.wallet.send.MyTransactionOutPoint)4 DumpedPrivateKey (org.bitcoinj.core.DumpedPrivateKey)4 JSONObject (org.json.JSONObject)4 PaymentAddress (com.samourai.wallet.bip47.rpc.PaymentAddress)3 PaymentCode (com.samourai.wallet.bip47.rpc.PaymentCode)3 HD_Wallet (com.samourai.wallet.hd.HD_Wallet)3 Transaction (org.bitcoinj.core.Transaction)3 TransactionInput (org.bitcoinj.core.TransactionInput)3 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)3 TransactionSignature (org.bitcoinj.crypto.TransactionSignature)3 Script (org.bitcoinj.script.Script)3 ScriptException (org.bitcoinj.script.ScriptException)3