From 26343b2a38ff310c6dd44d5854a48101773e3d78 Mon Sep 17 00:00:00 2001 From: AZ Date: Fri, 9 Dec 2016 22:46:43 +0100 Subject: [PATCH] [WIP ] --- src/main/java/jota/IotaAPIProxy.java | 89 +++++++++++++++++++- src/main/java/jota/model/Transaction.java | 12 ++- src/main/java/jota/utils/Converter.java | 45 +++++++++- src/main/java/jota/utils/InputValidator.java | 21 +++++ 4 files changed, 160 insertions(+), 7 deletions(-) diff --git a/src/main/java/jota/IotaAPIProxy.java b/src/main/java/jota/IotaAPIProxy.java index dff33f0..d8122d5 100644 --- a/src/main/java/jota/IotaAPIProxy.java +++ b/src/main/java/jota/IotaAPIProxy.java @@ -1,10 +1,13 @@ package jota; +import com.sun.org.apache.xpath.internal.Arg; import jota.dto.request.*; import jota.dto.response.*; import jota.error.ArgumentException; import jota.error.NotEnoughBalanceException; import jota.model.*; +import jota.utils.Converter; +import jota.utils.InputValidator; import jota.utils.IotaAPIUtils; import okhttp3.OkHttpClient; import org.apache.commons.lang3.NotImplementedException; @@ -332,8 +335,92 @@ public class IotaAPIProxy { } } + public Bundle[] getTransfers(String seed, Integer start, Integer end, Boolean inclusionStates) throws ArgumentException { + start = start != null ? 0 : start; + end = end == null ? null : end; + inclusionStates = inclusionStates != null ? inclusionStates : null; - public Transaction[] SendTransfer(String seed, int depth, int minWeightMagnitude, Transfer[] transfers, Input[] inputs, String address) throws NotEnoughBalanceException, ArgumentException { + if (start > end || end > (start + 500)) { + throw new ArgumentException(); + } + + GetNewAddressResponse gnr = getNewAddress(seed, start, false, end == null ? end - start : end, true); + if (gnr != null && gnr.getAddresses() != null) { + return bundlesFromAddresses(gnr.getAddresses().toArray(new String[gnr.getAddresses().size()]), inclusionStates); + } + return null; + } + + public Bundle[] bundlesFromAddresses(String[] addresses, Boolean inclusionStates) { + return null; + + Transaction[] trxs = findTransactionObjects(addresses); + // set of tail transactions + var tailTransactions = new Set(); + var nonTailBundleHashes = new Set(); + + transactionObjects.forEach(function(thisTransaction) { + + // Sort tail and nonTails + if (thisTransaction.currentIndex === 0) { + + tailTransactions.add(thisTransaction.hash); + } else { + + nonTailBundleHashes.add(thisTransaction.bundle) + } + }) +/* + // Get tail transactions for each nonTail via the bundle hash + self.findTransactionObjects({'bundles': Array.from(nonTailBundleHashes)}, function(error, bundleObjects) { + + if (error) return callback(error); + + bundleObjects.forEach(function(thisTransaction) { + + if (thisTransaction.currentIndex === 0) { + + tailTransactions.add(thisTransaction.hash); + } + }) + + var finalBundles = []; + var tailTxArray = Array.from(tailTransactions);*/ + } + + public Transaction[] findTransactionObjects(String[] input) throws ArgumentException { + FindTransactionResponse ftr = findTransactions(input, null, null, null); + if (ftr == null || ftr.getHashes() == null) return null; + // get the transaction objects of the transactions + return getTransactionsObjects(ftr.getHashes()); + } + + public Transaction[] getTransactionsObjects(String[] hashes) throws ArgumentException { + + // If not array of hashes, return error + if (!InputValidator.isArrayOfHashes(hashes)) { + throw new ArgumentException(); + } + + // get the trytes of the transaction hashes + GetTrytesResponse gtr = getTrytes(hashes); + if (gtr == null || gtr.getTrytes() == null) return null; + List transactionObjects = new ArrayList<>(); + + // call transactionObjects for each trytes + for (String transactionInTrytes : gtr.getTrytes()) { + + // If no trytes returned, simply push null as placeholder + if (transactionInTrytes == null) { + transactionObjects.add(null); + } else { + transactionObjects.add(Converter.transactionObject(transactionInTrytes)); + } + } + return transactionObjects.toArray(new Transaction[transactionObjects.size()]); + } + + public Transaction[] sendTransfer(String seed, int depth, int minWeightMagnitude, Transfer[] transfers, Input[] inputs, String address) throws NotEnoughBalanceException, ArgumentException { String[] trytes = prepareTransfers(seed, transfers, inputs, address); return sendTrytes(trytes, depth, minWeightMagnitude); } diff --git a/src/main/java/jota/model/Transaction.java b/src/main/java/jota/model/Transaction.java index f8f45fa..36140a9 100644 --- a/src/main/java/jota/model/Transaction.java +++ b/src/main/java/jota/model/Transaction.java @@ -20,6 +20,10 @@ public class Transaction { private String branchTransaction; private String nonce; + public Transaction() { + + } + public Transaction(String signatureMessageChunk, String currentIndex, String lastIndex, String nonce, String hash, String tag, String timestamp, String trunkTransaction, String branchTransaction, String address, String value, String bundle) { this.hash = hash; @@ -118,16 +122,16 @@ public class Transaction { return currentIndex; } - public void setCurrentIndex(String currentIndex) { - this.currentIndex = currentIndex; + public String setCurrentIndex(String currentIndex) { + return this.currentIndex = currentIndex; } public String getLastIndex() { return lastIndex; } - public void setLastIndex(String lastIndex) { - this.lastIndex = lastIndex; + public String setLastIndex(String lastIndex) { + return this.lastIndex = lastIndex; } public String getNonce() { diff --git a/src/main/java/jota/utils/Converter.java b/src/main/java/jota/utils/Converter.java index c10792b..818fe7b 100644 --- a/src/main/java/jota/utils/Converter.java +++ b/src/main/java/jota/utils/Converter.java @@ -1,5 +1,8 @@ package jota.utils; +import jota.model.Transaction; +import jota.pow.Curl; + import java.util.Arrays; public class Converter { @@ -94,7 +97,7 @@ public class Converter { public static int[] copyTrits(final String input, final int[] destination) { for (int i = 0; i < input.length(); i++) { int index = Constants.TRYTE_ALPHABET.indexOf(input.charAt(i)); - destination[i * 3] = TRYTE_TO_TRITS_MAPPINGS [index][0]; + destination[i * 3] = TRYTE_TO_TRITS_MAPPINGS[index][0]; destination[i * 3 + 1] = TRYTE_TO_TRITS_MAPPINGS[index][1]; destination[i * 3 + 2] = TRYTE_TO_TRITS_MAPPINGS[index][2]; } @@ -130,7 +133,8 @@ public class Converter { for (int i = trits.length; i-- > 0; ) { value = value * 3 + trits[i]; } - return value; } + return value; + } public static void increment(final int[] trits, final int size) { @@ -142,4 +146,41 @@ public class Converter { } } } + + public static Transaction transactionObject(String trytes) { + if (trytes == null) return null; + + // validity check + for (int i = 2279; i < 2295; i++) { + if (trytes.charAt(i) != '9') { + return null; + } + } + int[] transactionTrits = Converter.trits(trytes); + int[] hash = new int[90]; + + Curl curl = new Curl(); + + // generate the correct transaction hash + curl.reset(); + curl.absorb(transactionTrits, 0, transactionTrits.length); + curl.squeeze(hash, 0, hash.length); + + Transaction trx = new Transaction(); + + trx.setHash(Converter.trytes(hash)); + trx.setSignatureMessageChunk(trytes.substring(0, 2187)); + trx.setAddress(trytes.substring(2187, 2268)); + trx.setValue("" + Converter.value(Arrays.copyOfRange(transactionTrits, 6804, 6837))); + trx.setTag(trytes.substring(2295, 2322)); + trx.setTimestamp("" + Converter.value(Arrays.copyOfRange(transactionTrits, 6966, 6993))); + trx.setCurrentIndex("" + Converter.value(Arrays.copyOfRange(transactionTrits, 6993, 7020))); + trx.setLastIndex("" + Converter.value(Arrays.copyOfRange(transactionTrits, 7020, 7047))); + trx.setBundle(trytes.substring(2349, 2430)); + trx.setTrunkTransaction(trytes.substring(2430, 2511)); + trx.setBranchTransaction(trytes.substring(2511, 2592)); + trx.setNonce(trytes.substring(2592, 2673)); + + return trx; + } } \ No newline at end of file diff --git a/src/main/java/jota/utils/InputValidator.java b/src/main/java/jota/utils/InputValidator.java index c1ddd2a..bddfff7 100644 --- a/src/main/java/jota/utils/InputValidator.java +++ b/src/main/java/jota/utils/InputValidator.java @@ -20,4 +20,25 @@ public class InputValidator { public static boolean isTrytes(final String trytes, final int length) { return trytes.matches("^[A-Z9]{" + (length == 0 ? "0," : length) + "}$"); } + + public static boolean isArrayOfHashes(String[] hashes) { + if (hashes == null) return false; + + for (int i = 0; i < hashes.length; i++) { + String hash = hashes[i]; + + // Check if address with checksum + if (hash.length() == 90) { + if (!isTrytes(hash, 90)) { + return false; + } + } else { + if (!isTrytes(hash, 81)) { + return false; + } + } + } + return true; + + } }