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;
}
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());
}
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;
}
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;
}
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;
}
Aggregations