Search in sources :

Example 1 with TestNet3Params

use of org.bitcoinj.params.TestNet3Params in project samourai-wallet-android by Samourai-Wallet.

the class Cahoots method toJSON.

public JSONObject toJSON() {
    JSONObject cObj = new JSONObject();
    try {
        JSONObject obj = new JSONObject();
        obj.put("version", version);
        obj.put("ts", ts);
        obj.put("id", strID);
        obj.put("type", type);
        obj.put("step", step);
        obj.put("spend_amount", spendAmount);
        obj.put("fee_amount", feeAmount);
        JSONArray _outpoints = new JSONArray();
        for (String outpoint : outpoints.keySet()) {
            JSONObject entry = new JSONObject();
            entry.put("outpoint", outpoint);
            entry.put("value", outpoints.get(outpoint));
            _outpoints.put(entry);
        }
        obj.put("outpoints", _outpoints);
        obj.put("dest", strDestination == null ? "" : strDestination);
        // obj.put("paynym_init", strPayNymInit == null ? "" : strPayNymInit);
        if (params instanceof TestNet3Params) {
            obj.put("params", "testnet");
        }
        obj.put("account", account);
        obj.put("cpty_account", cptyAccount);
        if (fingerprint != null) {
            obj.put("fingerprint", Hex.toHexString(fingerprint));
        }
        if (fingerprintCollab != null) {
            obj.put("fingerprint_collab", Hex.toHexString(fingerprintCollab));
        }
        obj.put("psbt", psbt == null ? "" : Z85.getInstance().encode(psbt.toGZIP()));
        obj.put("collabChange", strCollabChange == null ? "" : strCollabChange);
        cObj.put("cahoots", obj);
    } catch (JSONException je) {
        je.printStackTrace();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    return cObj;
}
Also used : TestNet3Params(org.bitcoinj.params.TestNet3Params) JSONObject(org.json.JSONObject) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) JSONException(org.json.JSONException)

Example 2 with TestNet3Params

use of org.bitcoinj.params.TestNet3Params in project samourai-wallet-android by Samourai-Wallet.

the class WhirlpoolTx0 method make.

public void make() throws Exception {
    tx0 = null;
    debug("WhirlpoolTx0", "make: ");
    // 
    if (getChange() < 0L) {
        debug("WhirlpoolTx0", "Cannot make premix: negative change:" + getAmountSelected());
        throw new Exception("Cannot make premix: negative change:" + getAmountSelected());
    }
    if (nbPossiblePremix() < 1) {
        debug("WhirlpoolTx0", "Cannot make premix: insufficient selected amount:" + getAmountSelected());
        throw new Exception("Cannot make premix: insufficient selected amount:" + getAmountSelected());
    }
    debug("WhirlpoolTx0", "amount selected:" + getAmountSelected() / 1e8);
    debug("WhirlpoolTx0", "amount requested:" + ((getPremixRequested() * getPool()) / 1e8));
    debug("WhirlpoolTx0", "nb premix possible:" + nbPossiblePremix());
    debug("WhirlpoolTx0", "amount after Whirlpool fee:" + getAmountAfterWhirlpoolFee() / 1e8);
    debug("WhirlpoolTx0", "fee samourai:" + new DecimalFormat("0.########").format(getFeeSamourai() / 1e8));
    debug("WhirlpoolTx0", "fee miners:" + new DecimalFormat("0.########").format(getFee() / 1e8));
    debug("WhirlpoolTx0", "change amount:" + getChange() / 1e8);
    // [WIP] stub;
    tx0 = new Transaction(SamouraiWallet.getInstance().getCurrentNetworkParams() instanceof TestNet3Params ? TestNet3Params.get() : MainNetParams.get());
}
Also used : TestNet3Params(org.bitcoinj.params.TestNet3Params) Transaction(org.bitcoinj.core.Transaction) DecimalFormat(java.text.DecimalFormat)

Example 3 with TestNet3Params

use of org.bitcoinj.params.TestNet3Params in project samourai-wallet-android by Samourai-Wallet.

the class Stowaway method doStep1.

// 
// receiver
// 
public boolean doStep1(HashMap<_TransactionOutPoint, Triple<byte[], byte[], String>> inputs, HashMap<_TransactionOutput, Triple<byte[], byte[], String>> outputs) throws Exception {
    if (this.getStep() != 0 || this.getSpendAmount() == 0L) {
        return false;
    }
    if (this.getType() == Cahoots.CAHOOTS_STONEWALLx2 && outputs == null) {
        return false;
    }
    Transaction transaction = new Transaction(params);
    for (_TransactionOutPoint outpoint : inputs.keySet()) {
        TransactionInput input = new TransactionInput(params, null, new byte[0], outpoint, outpoint.getValue());
        Log.d("Stowaway", "input value:" + input.getValue().longValue());
        transaction.addInput(input);
        outpoints.put(outpoint.getTxHash().toString() + "-" + outpoint.getTxOutputN(), outpoint.getValue().longValue());
    }
    for (_TransactionOutput output : outputs.keySet()) {
        transaction.addOutput(output);
    }
    PSBT psbt = new PSBT(transaction);
    for (_TransactionOutPoint outpoint : inputs.keySet()) {
        Triple triple = inputs.get(outpoint);
        // input type 1
        SegwitAddress segwitAddress = new SegwitAddress((byte[]) triple.getLeft(), params);
        psbt.addInput(PSBT.PSBT_IN_WITNESS_UTXO, null, PSBT.writeSegwitInputUTXO(outpoint.getValue().longValue(), segwitAddress.segWitRedeemScript().getProgram()));
        // input type 6
        String[] s = ((String) triple.getRight()).split("/");
        psbt.addInput(PSBT.PSBT_IN_BIP32_DERIVATION, (byte[]) triple.getLeft(), PSBT.writeBIP32Derivation((byte[]) triple.getMiddle(), 84, params instanceof TestNet3Params ? 1 : 0, account, Integer.valueOf(s[1]), Integer.valueOf(s[2])));
    }
    for (_TransactionOutput output : outputs.keySet()) {
        Triple triple = outputs.get(output);
        // output type 2
        String[] s = ((String) triple.getRight()).split("/");
        psbt.addOutput(PSBT.PSBT_OUT_BIP32_DERIVATION, (byte[]) triple.getLeft(), PSBT.writeBIP32Derivation((byte[]) triple.getMiddle(), 84, params instanceof TestNet3Params ? 1 : 0, account, Integer.valueOf(s[1]), Integer.valueOf(s[2])));
    }
    this.psbt = psbt;
    Log.d("Stowaway", "input value:" + psbt.getTransaction().getInputs().get(0).getValue().longValue());
    this.setStep(1);
    return true;
}
Also used : PSBT(com.samourai.wallet.cahoots.psbt.PSBT) Triple(org.apache.commons.lang3.tuple.Triple) TestNet3Params(org.bitcoinj.params.TestNet3Params) SegwitAddress(com.samourai.wallet.segwit.SegwitAddress)

Example 4 with TestNet3Params

use of org.bitcoinj.params.TestNet3Params in project samourai-wallet-android by Samourai-Wallet.

the class Stowaway method doStep2.

// 
// sender
// 
public boolean doStep2(HashMap<_TransactionOutPoint, Triple<byte[], byte[], String>> inputs, HashMap<_TransactionOutput, Triple<byte[], byte[], String>> outputs) throws Exception {
    Transaction transaction = psbt.getTransaction();
    Log.d("Stowaway", "step2 tx:" + transaction.toString());
    Log.d("Stowaway", "step2 tx:" + Hex.toHexString(transaction.bitcoinSerialize()));
    // tx: modify spend output
    long contributedAmount = 0L;
    /*
        for(TransactionInput input : transaction.getInputs())   {
//            Log.d("Stowaway", input.getOutpoint().toString());
            contributedAmount += input.getOutpoint().getValue().longValue();
        }
        */
    for (String outpoint : outpoints.keySet()) {
        contributedAmount += outpoints.get(outpoint);
    }
    long outputAmount = transaction.getOutput(0).getValue().longValue();
    TransactionOutput spendOutput = transaction.getOutput(0);
    spendOutput.setValue(Coin.valueOf(outputAmount + contributedAmount));
    transaction.clearOutputs();
    transaction.addOutput(spendOutput);
    for (_TransactionOutPoint outpoint : inputs.keySet()) {
        Log.d("Stowaway", "outpoint value:" + outpoint.getValue().longValue());
        TransactionInput input = new TransactionInput(params, null, new byte[0], outpoint, outpoint.getValue());
        transaction.addInput(input);
        outpoints.put(outpoint.getTxHash().toString() + "-" + outpoint.getTxOutputN(), outpoint.getValue().longValue());
    }
    for (_TransactionOutput output : outputs.keySet()) {
        transaction.addOutput(output);
    }
    // psbt: modify spend output
    List<PSBTEntry> updatedEntries = new ArrayList<PSBTEntry>();
    for (PSBTEntry entry : psbt.getPsbtInputs()) {
        if (entry.getKeyType()[0] == PSBT.PSBT_IN_WITNESS_UTXO) {
            byte[] data = entry.getData();
            byte[] scriptPubKey = new byte[data.length - Long.BYTES];
            System.arraycopy(data, Long.BYTES, scriptPubKey, 0, scriptPubKey.length);
            entry.setData(PSBT.writeSegwitInputUTXO(outputAmount + contributedAmount, scriptPubKey));
        }
        updatedEntries.add(entry);
    }
    psbt.setPsbtInputs(updatedEntries);
    for (_TransactionOutPoint outpoint : inputs.keySet()) {
        Triple triple = inputs.get(outpoint);
        // input type 1
        SegwitAddress segwitAddress = new SegwitAddress((byte[]) triple.getLeft(), params);
        psbt.addInput(PSBT.PSBT_IN_WITNESS_UTXO, null, PSBT.writeSegwitInputUTXO(outpoint.getValue().longValue(), segwitAddress.segWitRedeemScript().getProgram()));
        // input type 6
        String[] s = ((String) triple.getRight()).split("/");
        psbt.addInput(PSBT.PSBT_IN_BIP32_DERIVATION, (byte[]) triple.getLeft(), PSBT.writeBIP32Derivation((byte[]) triple.getMiddle(), 84, params instanceof TestNet3Params ? 1 : 0, account, Integer.valueOf(s[1]), Integer.valueOf(s[2])));
    }
    for (_TransactionOutput output : outputs.keySet()) {
        Triple triple = outputs.get(output);
        // output type 2
        String[] s = ((String) triple.getRight()).split("/");
        psbt.addOutput(PSBT.PSBT_OUT_BIP32_DERIVATION, (byte[]) triple.getLeft(), PSBT.writeBIP32Derivation((byte[]) triple.getMiddle(), 84, params instanceof TestNet3Params ? 1 : 0, account, Integer.valueOf(s[1]), Integer.valueOf(s[2])));
    }
    psbt.setTransaction(transaction);
    this.setStep(2);
    return true;
}
Also used : SegwitAddress(com.samourai.wallet.segwit.SegwitAddress) PSBTEntry(com.samourai.wallet.cahoots.psbt.PSBTEntry) Triple(org.apache.commons.lang3.tuple.Triple) TestNet3Params(org.bitcoinj.params.TestNet3Params)

Example 5 with TestNet3Params

use of org.bitcoinj.params.TestNet3Params in project samourai-wallet-android by Samourai-Wallet.

the class RicochetMeta method script.

public JSONObject script(long spendAmount, long feePerKBAmount, String strDestination, int nbHops, String strPCode, boolean samouraiFeeViaBIP47, boolean useTimeLock) {
    JSONObject jObj = new JSONObject();
    try {
        BigInteger biSpend = BigInteger.valueOf(spendAmount);
        // default 4 hops min. for base fee, each additional hop 0.001
        BigInteger biSamouraiFee = BigInteger.valueOf(samouraiFeeAmountV2.longValue() * ((nbHops - defaultNbHops) + 1));
        BigInteger biFeePerKB = BigInteger.valueOf(feePerKBAmount);
        long latestBlock = APIFactory.getInstance(context).getLatestBlockHeight();
        long nTimeLock = 0L;
        if (useTimeLock && latestBlock > 0L) {
            nTimeLock = latestBlock;
        }
        jObj.put("ts", System.currentTimeMillis() / 1000L);
        jObj.put("hops", nbHops);
        jObj.put("spend_amount", biSpend.longValue());
        jObj.put("samourai_fee", biSamouraiFee.longValue());
        jObj.put("samourai_fee_via_bip47", samouraiFeeViaBIP47);
        jObj.put("feeKB", biFeePerKB.longValue());
        jObj.put("destination", strDestination);
        if (strPCode != null) {
            jObj.put("pcode", strPCode);
        }
        if (useTimeLock) {
            jObj.put("nTimeLock", nTimeLock);
        }
        JSONObject jHop = new JSONObject();
        JSONArray jHops = new JSONArray();
        int hopSz = 0;
        if (samouraiFeeViaBIP47) {
            hopSz = FeeUtil.getInstance().estimatedSize(1, 2);
        } else {
            hopSz = FeeUtil.getInstance().estimatedSize(1, 1);
        }
        BigInteger biFeePerHop = FeeUtil.getInstance().calculateFee(hopSz, biFeePerKB);
        Pair<List<UTXO>, BigInteger> pair = getHop0UTXO(spendAmount, nbHops, biFeePerHop.longValue(), samouraiFeeViaBIP47);
        List<UTXO> utxos = pair.getLeft();
        long totalValueSelected = 0L;
        for (UTXO u : utxos) {
            totalValueSelected += u.getValue();
        }
        // Log.d("RicochetMeta", "totalValueSelected (return):" + totalValueSelected);
        // hop0 'leaves' wallet, change returned to wallet
        BigInteger hop0 = biSpend.add(biSamouraiFee).add(biFeePerHop.multiply(BigInteger.valueOf((long) nbHops)));
        // BigInteger hop0Fee = FeeUtil.getInstance().calculateFee(hop0sz, biFeePerKB);
        BigInteger hop0Fee = pair.getRight();
        // Log.d("RicochetMeta", "hop0Fee (return):" + hop0Fee.longValue());
        Transaction txHop0 = getHop0Tx(utxos, hop0.longValue(), getDestinationAddress(index), hop0Fee.longValue(), samouraiFeeViaBIP47, nTimeLock);
        if (txHop0 == null) {
            return null;
        }
        // Log.d("RicochetMeta", "searching for:" + getDestinationAddress(index));
        int prevTxN = 0;
        for (int i = 0; i < txHop0.getOutputs().size(); i++) {
            Script script = txHop0.getOutputs().get(i).getScriptPubKey();
            // Log.d("RicochetMeta", "script:" + Hex.toHexString(script.getProgram()));
            String address = null;
            if (Hex.toHexString(script.getProgram()).startsWith("0014")) {
                String hrp = null;
                if (SamouraiWallet.getInstance().getCurrentNetworkParams() instanceof TestNet3Params) {
                    hrp = "tb";
                } else {
                    hrp = "bc";
                }
                try {
                    String _script = Hex.toHexString(script.getProgram());
                    address = Bech32Segwit.encode(hrp, (byte) 0x00, Hex.decode(_script.substring(4).getBytes()));
                } catch (Exception e) {
                    ;
                }
            // Log.d("RicochetMeta", "bech32:" + address);
            } else {
                address = new Script(script.getProgram()).getToAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
            // Log.d("RicochetMeta", "address from script:" + address);
            }
            if (address.equals(getDestinationAddress(index))) {
                prevTxN = i;
                // Log.d("RicochetMeta", "tx output n:" + prevTxN);
                break;
            }
        }
        jHop.put("seq", 0);
        jHop.put("spend_amount", hop0.longValue());
        jHop.put("fee", hop0Fee.longValue());
        jHop.put("fee_per_hop", biFeePerHop.longValue());
        jHop.put("index", index);
        jHop.put("destination", getDestinationAddress(index));
        // Log.d("RicochetMeta", "destination:" + getDestinationAddress(index));
        int prevIndex = index;
        index++;
        jHop.put("tx", new String(Hex.encode(txHop0.bitcoinSerialize())));
        jHop.put("hash", txHop0.getHash().toString());
        if (useTimeLock) {
            jHop.put("nTimeLock", nTimeLock);
        }
        jHops.put(jHop);
        List<Pair<String, Long>> samouraiFees = new ArrayList<Pair<String, Long>>();
        if (samouraiFeeViaBIP47) {
            long baseVal = samouraiFeeAmountV2.longValue() / 4L;
            long totalVal = 0L;
            SecureRandom random = new SecureRandom();
            int _outgoingIdx = BIP47Meta.getInstance().getOutgoingIdx(BIP47Meta.strSamouraiDonationPCode);
            for (int i = 0; i < 4; i++) {
                int val = random.nextInt(25000);
                int sign = random.nextInt(1);
                if (sign == 0) {
                    val *= -1L;
                }
                long feeVal = 0L;
                if (i == 3) {
                    feeVal = samouraiFeeAmountV2.longValue() - totalVal;
                } else {
                    feeVal = baseVal + val;
                    totalVal += feeVal;
                }
                // 
                try {
                    PaymentCode pcode = new PaymentCode(BIP47Meta.strSamouraiDonationPCode);
                    PaymentAddress paymentAddress = BIP47Util.getInstance(context).getSendAddress(pcode, _outgoingIdx + i);
                    // String strAddress = paymentAddress.getSendECKey().toAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).toString();
                    // 
                    // derive as bech32
                    // 
                    SegwitAddress segwitAddress = new SegwitAddress(paymentAddress.getSendECKey().getPubKey(), SamouraiWallet.getInstance().getCurrentNetworkParams());
                    String strAddress = segwitAddress.getBech32AsString();
                    samouraiFees.add(Pair.of(strAddress, feeVal));
                // samouraiFees.add(Pair.of(strAddress, 200000L / 4L));
                } catch (Exception e) {
                    samouraiFees.add(Pair.of(SendNotifTxFactory.SAMOURAI_NOTIF_TX_FEE_ADDRESS, feeVal));
                }
            }
        }
        Transaction txHop = null;
        String prevTxHash = txHop0.getHash().toString();
        String prevScriptPubKey = Hex.toHexString(txHop0.getOutput(prevTxN).getScriptPubKey().getProgram());
        BigInteger remainingSamouraiFee = BigInteger.ZERO;
        long prevSpendValue = hop0.longValue();
        if (!samouraiFeeViaBIP47) {
            prevSpendValue -= biSamouraiFee.longValue();
        } else {
            remainingSamouraiFee = samouraiFeeAmountV2;
        }
        int _hop = 0;
        for (int i = (nbHops - 1); i >= 0; i--) {
            _hop++;
            BigInteger hopx = null;
            if (samouraiFeeViaBIP47) {
                remainingSamouraiFee = remainingSamouraiFee.subtract(BigInteger.valueOf(samouraiFees.get(_hop - 1).getRight()));
                hopx = biSpend.add(biFeePerHop.multiply(BigInteger.valueOf((long) i))).add(remainingSamouraiFee);
            } else {
                hopx = biSpend.add(biFeePerHop.multiply(BigInteger.valueOf((long) i)));
            }
            if (useTimeLock && latestBlock > 0L) {
                nTimeLock = latestBlock + _hop;
            }
            // Log.d("RicochetMeta", "doing hop:" + _hop);
            if (samouraiFeeViaBIP47 && ((_hop - 1) < 4)) {
                txHop = getHopTx(prevTxHash, prevTxN, prevIndex, prevSpendValue, hopx.longValue(), _hop < nbHops ? getDestinationAddress(index) : strDestination, samouraiFees.get(_hop - 1), nTimeLock);
            } else {
                txHop = getHopTx(prevTxHash, prevTxN, prevIndex, prevSpendValue, hopx.longValue(), _hop < nbHops ? getDestinationAddress(index) : strDestination, null, nTimeLock);
            }
            if (txHop == null) {
                return null;
            }
            jHop = new JSONObject();
            jHop.put("seq", (nbHops - i));
            jHop.put("spend_amount", hopx.longValue());
            jHop.put("fee", biFeePerHop.longValue());
            jHop.put("prev_tx_hash", prevTxHash);
            jHop.put("prev_tx_n", prevTxN);
            jHop.put("prev_spend_value", prevSpendValue);
            jHop.put("script", prevScriptPubKey);
            jHop.put("tx", new String(Hex.encode(txHop.bitcoinSerialize())));
            jHop.put("hash", txHop.getHash().toString());
            if (useTimeLock) {
                jHop.put("nTimeLock", nTimeLock);
            }
            if (_hop < nbHops) {
                jHop.put("index", index);
                jHop.put("destination", getDestinationAddress(index));
                // Log.d("RicochetMeta", "destination:" + getDestinationAddress(index));
                prevIndex = index;
                index++;
            } else {
                jHop.put("destination", strDestination);
            // Log.d("RicochetMeta", "destination:" + strDestination);
            }
            if (samouraiFeeViaBIP47) {
                jObj.put("samourai_fee_address", samouraiFees.get(_hop - 1).getLeft());
                jObj.put("samourai_fee_amount", samouraiFees.get(_hop - 1).getRight());
            }
            jHops.put(jHop);
            prevTxHash = txHop.getHash().toString();
            prevTxN = 0;
            prevSpendValue = hopx.longValue();
            prevScriptPubKey = Hex.toHexString(txHop.getOutputs().get(0).getScriptPubKey().getProgram());
        }
        jObj.put("hops", jHops);
        BigInteger totalAmount = hop0.add(hop0Fee);
        jObj.put("total_spend", totalAmount.longValue());
    } catch (JSONException je) {
        return null;
    }
    System.out.println("RicochetMeta:" + jObj.toString());
    return jObj;
}
Also used : Script(org.bitcoinj.script.Script) PaymentCode(com.samourai.wallet.bip47.rpc.PaymentCode) SegwitAddress(com.samourai.wallet.segwit.SegwitAddress) JSONArray(org.json.JSONArray) ArrayList(java.util.ArrayList) SecureRandom(java.security.SecureRandom) JSONException(org.json.JSONException) PaymentAddress(com.samourai.wallet.bip47.rpc.PaymentAddress) MyTransactionOutPoint(com.samourai.wallet.send.MyTransactionOutPoint) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint) JSONException(org.json.JSONException) ScriptException(org.bitcoinj.script.ScriptException) MnemonicException(org.bitcoinj.crypto.MnemonicException) IOException(java.io.IOException) UTXO(com.samourai.wallet.send.UTXO) TestNet3Params(org.bitcoinj.params.TestNet3Params) JSONObject(org.json.JSONObject) Transaction(org.bitcoinj.core.Transaction) BigInteger(java.math.BigInteger) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Pair(org.apache.commons.lang3.tuple.Pair)

Aggregations

TestNet3Params (org.bitcoinj.params.TestNet3Params)7 SegwitAddress (com.samourai.wallet.segwit.SegwitAddress)5 Triple (org.apache.commons.lang3.tuple.Triple)4 PSBT (com.samourai.wallet.cahoots.psbt.PSBT)2 Transaction (org.bitcoinj.core.Transaction)2 Script (org.bitcoinj.script.Script)2 JSONArray (org.json.JSONArray)2 JSONException (org.json.JSONException)2 JSONObject (org.json.JSONObject)2 PaymentAddress (com.samourai.wallet.bip47.rpc.PaymentAddress)1 PaymentCode (com.samourai.wallet.bip47.rpc.PaymentCode)1 PSBTEntry (com.samourai.wallet.cahoots.psbt.PSBTEntry)1 MyTransactionOutPoint (com.samourai.wallet.send.MyTransactionOutPoint)1 UTXO (com.samourai.wallet.send.UTXO)1 IOException (java.io.IOException)1 BigInteger (java.math.BigInteger)1 SecureRandom (java.security.SecureRandom)1 DecimalFormat (java.text.DecimalFormat)1 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1