diff --git a/pom.xml b/pom.xml index 439204e5..b9851749 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.iota jota - 0.9.5-SNAPSHOT + 0.9.6-SNAPSHOT JOTA JOTA library is a simple Java wrapper around IOTA Node's JSON-REST HTTP interface. diff --git a/src/main/java/jota/IotaAPIService.java b/src/main/java/jota/IotaAPIService.java index 29463071..bc3ca50d 100644 --- a/src/main/java/jota/IotaAPIService.java +++ b/src/main/java/jota/IotaAPIService.java @@ -16,6 +16,7 @@ public interface IotaAPIService { String CONTENT_TYPE_HEADER = "Content-Type: application/json"; String USER_AGENT_HEADER = "User-Agent: JOTA-API wrapper"; + String X_IOTA_API_VERSION_HEADER = "X-IOTA-API-Version: 1"; /** * Returns information about your node. @@ -25,7 +26,7 @@ public interface IotaAPIService { * * @return a {@code NodeInfoResponse} object, if succesfull. */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call getNodeInfo(@Body IotaCommandRequest request); @@ -35,7 +36,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "getNeighbors"}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call getNeighbors(@Body IotaCommandRequest request); @@ -45,7 +46,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "addNeighbors", "uris": ["udp://8.8.8.8:14265", "udp://8.8.8.5:14265"]}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call addNeighbors(@Body IotaNeighborsRequest request); @@ -55,7 +56,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "removeNeighbors", "uris": ["udp://8.8.8.8:14265", "udp://8.8.8.5:14265"]}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call removeNeighbors(@Body IotaNeighborsRequest request); @@ -65,7 +66,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "getTips"}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call getTips(@Body IotaCommandRequest request); @@ -75,7 +76,7 @@ public interface IotaAPIService { * curl http://localhost:14265 \ -X POST \ -H 'Content-Type: application/json' \ * -d '{"command": "findTransactions", "addresses": ["RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFWYWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAZETAIRPTM"]}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call findTransactions(@Body IotaFindTransactionsRequest request); @@ -86,7 +87,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "getInclusionStates", "transactions"Q9HZWYKFWYWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAZETAIRPTM"], "tips" : []}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call getInclusionStates(@Body IotaGetInclusionStateRequest request); @@ -96,7 +97,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "getTrytes", "hashes": ["OAATQS9VQLSXCLDJVJJVYUGONXAXOFMJOZNSYWRZSWECMXAQQURHQBJNLD9IOFEPGZEPEMPXCIVRX9999"]}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call getTrytes(@Body IotaGetTrytesRequest request); @@ -106,7 +107,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "getTransactionsToApprove", "depth": 27}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call getTransactionsToApprove(@Body IotaGetTransactionsToApproveRequest request); @@ -116,7 +117,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "getBalances", "addresses": ["HBBYKAKTILIPVUKFOTSLHGENPTXYBNKXZFQFR9VQFWNBMTQNRVOUKPVPRNBSZVVILMAFBKOTBLGLWLOHQ"], "threshold": 100}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call getBalances(@Body IotaGetBalancesRequest request); @@ -126,7 +127,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "attachToTangle", "trunkTransaction": "JVMTDGDPDFYHMZPMWEKKANBQSLSDTIIHAYQUMZOKHXXXGJHJDQPOMDOMNRDKYCZRUFZROZDADTHZC9999", "branchTransaction": "P9KFSJVGSPLXAEBJSHWFZLGP9GGJTIO9YITDEHATDTGAFLPLBZ9FOFWWTKMAZXZHFGQHUOXLXUALY9999", "minWeightMagnitude": 18, "trytes": ["TRYTVALUEHERE"]}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call attachToTangle(@Body IotaAttachToTangleRequest request); @@ -136,7 +137,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "interruptAttachingToTangle" } */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call interruptAttachingToTangle(@Body IotaCommandRequest request); @@ -146,7 +147,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "broadcastTransactions", "trytes": ["BYSWEAUTWXHXZ9YBZISEK9LUHWGMHXCGEVNZHRLUWQFCUSDXZHOFHWHL9MQPVJXXZLIXPXPXF9KYEREFSKCPKYIIKPZVLHUTDFQKKVVBBN9ATTLPCNPJDWDEVIYYLGPZGCWXOBDXMLJC9VO9QXTTBLAXTTBFUAROYEGQIVB9MJWJKXJMCUPTWAUGFZBTZCSJVRBGMYXTVBDDS9MYUJCPZ9YDWWQNIPUAIJXXSNLKUBSCOIJPCLEFPOXFJREXQCUVUMKSDOVQGGHRNILCO9GNCLWFM9APMNMWYASHXQAYBEXF9QRIHIBHYEJOYHRQJAOKAQ9AJJFQ9WEIWIJOTZATIBOXQLBMIJU9PCGBLVDDVFP9CFFSXTDUXMEGOOFXWRTLFGV9XXMYWEMGQEEEDBTIJ9OJOXFAPFQXCDAXOUDMLVYRMRLUDBETOLRJQAEDDLNVIRQJUBZBO9CCFDHIX9MSQCWYAXJVWHCUPTRSXJDESISQPRKZAFKFRULCGVRSBLVFOPEYLEE99JD9SEBALQINPDAZHFAB9RNBH9AZWIJOTLBZVIEJIAYGMC9AZGNFWGRSWAXTYSXVROVNKCOQQIWGPNQZKHUNODGYADPYLZZZUQRTJRTODOUKAOITNOMWNGHJBBA99QUMBHRENGBHTH9KHUAOXBVIVDVYYZMSEYSJWIOGGXZVRGN999EEGQMCOYVJQRIRROMPCQBLDYIGQO9AMORPYFSSUGACOJXGAQSPDY9YWRRPESNXXBDQ9OZOXVIOMLGTSWAMKMTDRSPGJKGBXQIVNRJRFRYEZ9VJDLHIKPSKMYC9YEGHFDS9SGVDHRIXBEMLFIINOHVPXIFAZCJKBHVMQZEVWCOSNWQRDYWVAIBLSCBGESJUIBWZECPUCAYAWMTQKRMCHONIPKJYYTEGZCJYCT9ABRWTJLRQXKMWY9GWZMHYZNWPXULNZAPVQLPMYQZCYNEPOCGOHBJUZLZDPIXVHLDMQYJUUBEDXXPXFLNRGIPWBRNQQZJSGSJTTYHIGGFAWJVXWL9THTPWOOHTNQWCNYOYZXALHAZXVMIZE9WMQUDCHDJMIBWKTYH9AC9AFOT9DPCADCV9ZWUTE9QNOMSZPTZDJLJZCJGHXUNBJFUBJWQUEZDMHXGBPTNSPZBR9TGSKVOHMOQSWPGFLSWNESFKSAZY9HHERAXALZCABFYPOVLAHMIHVDBGKUMDXC9WHHTIRYHZVWNXSVQUWCR9M9RAGMFEZZKZ9XEOQGOSLFQCHHOKLDSA9QCMDGCGMRYJZLBVIFOLBIJPROKMHOYTBTJIWUZWJMCTKCJKKTR9LCVYPVJI9AHGI9JOWMIWZAGMLDFJA9WU9QAMEFGABIBEZNNAL9OXSBFLOEHKDGHWFQSHMPLYFCNXAAZYJLMQDEYRGL9QKCEUEJ9LLVUOINVSZZQHCIKPAGMT9CAYIIMTTBCPKWTYHOJIIY9GYNPAJNUJ9BKYYXSV9JSPEXYMCFAIKTGNRSQGUNIYZCRT9FOWENSZQPD9ALUPYYAVICHVYELYFPUYDTWUSWNIYFXPX9MICCCOOZIWRNJIDALWGWRATGLJXNAYTNIZWQ9YTVDBOFZRKO9CFWRPAQQRXTPACOWCPRLYRYSJARRKSQPR9TCFXDVIXLP9XVL99ERRDSOHBFJDJQQGGGCZNDQ9NYCTQJWVZIAELCRBJJFDMCNZU9FIZRPGNURTXOCDSQGXTQHKHUECGWFUUYS9J9NYQ9U9P9UUP9YMZHWWWCIASCFLCMSKTELZWUGCDE9YOKVOVKTAYPHDF9ZCCQAYPJIJNGSHUIHHCOSSOOBUDOKE9CJZGYSSGNCQJVBEFTZFJ9SQUHOASKRRGBSHWKBCBWBTJHOGQ9WOMQFHWJVEG9NYX9KWBTCAIXNXHEBDIOFO9ALYMFGRICLCKKLG9FOBOX9PDWNQRGHBKHGKKRLWTBEQMCWQRLHAVYYZDIIPKVQTHYTWQMTOACXZOQCDTJTBAAUWXSGJF9PNQIJ9AJRUMUVCPWYVYVARKR9RKGOUHHNKNVGGPDDLGKPQNOYHNKAVVKCXWXOQPZNSLATUJT9AUWRMPPSWHSTTYDFAQDXOCYTZHOYYGAIM9CELMZ9AZPWB9MJXGHOKDNNSZVUDAGXTJJSSZCPZVPZBYNNTUQABSXQWZCHDQSLGK9UOHCFKBIBNETK999999999999999999999999999999999999999999999999999999999999999999999999999999999NOXDXXKUDWLOFJLIPQIBRBMGDYCPGDNLQOLQS99EQYKBIU9VHCJVIPFUYCQDNY9APGEVYLCENJIOBLWNB999999999XKBRHUD99C99999999NKZKEKWLDKMJCI9N9XQOLWEPAYWSH9999999999999999999999999KDDTGZLIPBNZKMLTOLOXQVNGLASESDQVPTXALEKRMIOHQLUHD9ELQDBQETS9QFGTYOYWLNTSKKMVJAUXSIROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X9999IROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X9999"]} */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call broadcastTransactions(@Body IotaBroadcastTransactionRequest request); @@ -156,7 +157,7 @@ public interface IotaAPIService { * curl http://localhost:14265 -X POST -H 'Content-Type: application/json' * -d '{"command": "storeTransactions", "trytes": ["BYSWEAUTWXHXZ9YBZISEK9LUHWGMHXCGEVNZHRLUWQFCUSDXZHOFHWHL9MQPVJXXZLIXPXPXF9KYEREFSKCPKYIIKPZVLHUTDFQKKVVBBN9ATTLPCNPJDWDEVIYYLGPZGCWXOBDXMLJC9VO9QXTTBLAXTTBFUAROYEGQIVB9MJWJKXJMCUPTWAUGFZBTZCSJVRBGMYXTVBDDS9MYUJCPZ9YDWWQNIPUAIJXXSNLKUBSCOIJPCLEFPOXFJREXQCUVUMKSDOVQGGHRNILCO9GNCLWFM9APMNMWYASHXQAYBEXF9QRIHIBHYEJOYHRQJAOKAQ9AJJFQ9WEIWIJOTZATIBOXQLBMIJU9PCGBLVDDVFP9CFFSXTDUXMEGOOFXWRTLFGV9XXMYWEMGQEEEDBTIJ9OJOXFAPFQXCDAXOUDMLVYRMRLUDBETOLRJQAEDDLNVIRQJUBZBO9CCFDHIX9MSQCWYAXJVWHCUPTRSXJDESISQPRKZAFKFRULCGVRSBLVFOPEYLEE99JD9SEBALQINPDAZHFAB9RNBH9AZWIJOTLBZVIEJIAYGMC9AZGNFWGRSWAXTYSXVROVNKCOQQIWGPNQZKHUNODGYADPYLZZZUQRTJRTODOUKAOITNOMWNGHJBBA99QUMBHRENGBHTH9KHUAOXBVIVDVYYZMSEYSJWIOGGXZVRGN999EEGQMCOYVJQRIRROMPCQBLDYIGQO9AMORPYFSSUGACOJXGAQSPDY9YWRRPESNXXBDQ9OZOXVIOMLGTSWAMKMTDRSPGJKGBXQIVNRJRFRYEZ9VJDLHIKPSKMYC9YEGHFDS9SGVDHRIXBEMLFIINOHVPXIFAZCJKBHVMQZEVWCOSNWQRDYWVAIBLSCBGESJUIBWZECPUCAYAWMTQKRMCHONIPKJYYTEGZCJYCT9ABRWTJLRQXKMWY9GWZMHYZNWPXULNZAPVQLPMYQZCYNEPOCGOHBJUZLZDPIXVHLDMQYJUUBEDXXPXFLNRGIPWBRNQQZJSGSJTTYHIGGFAWJVXWL9THTPWOOHTNQWCNYOYZXALHAZXVMIZE9WMQUDCHDJMIBWKTYH9AC9AFOT9DPCADCV9ZWUTE9QNOMSZPTZDJLJZCJGHXUNBJFUBJWQUEZDMHXGBPTNSPZBR9TGSKVOHMOQSWPGFLSWNESFKSAZY9HHERAXALZCABFYPOVLAHMIHVDBGKUMDXC9WHHTIRYHZVWNXSVQUWCR9M9RAGMFEZZKZ9XEOQGOSLFQCHHOKLDSA9QCMDGCGMRYJZLBVIFOLBIJPROKMHOYTBTJIWUZWJMCTKCJKKTR9LCVYPVJI9AHGI9JOWMIWZAGMLDFJA9WU9QAMEFGABIBEZNNAL9OXSBFLOEHKDGHWFQSHMPLYFCNXAAZYJLMQDEYRGL9QKCEUEJ9LLVUOINVSZZQHCIKPAGMT9CAYIIMTTBCPKWTYHOJIIY9GYNPAJNUJ9BKYYXSV9JSPEXYMCFAIKTGNRSQGUNIYZCRT9FOWENSZQPD9ALUPYYAVICHVYELYFPUYDTWUSWNIYFXPX9MICCCOOZIWRNJIDALWGWRATGLJXNAYTNIZWQ9YTVDBOFZRKO9CFWRPAQQRXTPACOWCPRLYRYSJARRKSQPR9TCFXDVIXLP9XVL99ERRDSOHBFJDJQQGGGCZNDQ9NYCTQJWVZIAELCRBJJFDMCNZU9FIZRPGNURTXOCDSQGXTQHKHUECGWFUUYS9J9NYQ9U9P9UUP9YMZHWWWCIASCFLCMSKTELZWUGCDE9YOKVOVKTAYPHDF9ZCCQAYPJIJNGSHUIHHCOSSOOBUDOKE9CJZGYSSGNCQJVBEFTZFJ9SQUHOASKRRGBSHWKBCBWBTJHOGQ9WOMQFHWJVEG9NYX9KWBTCAIXNXHEBDIOFO9ALYMFGRICLCKKLG9FOBOX9PDWNQRGHBKHGKKRLWTBEQMCWQRLHAVYYZDIIPKVQTHYTWQMTOACXZOQCDTJTBAAUWXSGJF9PNQIJ9AJRUMUVCPWYVYVARKR9RKGOUHHNKNVGGPDDLGKPQNOYHNKAVVKCXWXOQPZNSLATUJT9AUWRMPPSWHSTTYDFAQDXOCYTZHOYYGAIM9CELMZ9AZPWB9MJXGHOKDNNSZVUDAGXTJJSSZCPZVPZBYNNTUQABSXQWZCHDQSLGK9UOHCFKBIBNETK999999999999999999999999999999999999999999999999999999999999999999999999999999999NOXDXXKUDWLOFJLIPQIBRBMGDYCPGDNLQOLQS99EQYKBIU9VHCJVIPFUYCQDNY9APGEVYLCENJIOBLWNB999999999XKBRHUD99C99999999NKZKEKWLDKMJCI9N9XQOLWEPAYWSH9999999999999999999999999KDDTGZLIPBNZKMLTOLOXQVNGLASESDQVPTXALEKRMIOHQLUHD9ELQDBQETS9QFGTYOYWLNTSKKMVJAUXSIROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X9999IROUICDOXKSYZTDPEDKOQENTJOWJONDEWROCEJIEWFWLUAACVSJFTMCHHXJBJRKAAPUDXXVXFWP9X9999"]}' */ - @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER}) + @Headers({CONTENT_TYPE_HEADER, USER_AGENT_HEADER, X_IOTA_API_VERSION_HEADER}) @POST("./") Call storeTransactions(@Body IotaStoreTransactionsRequest request); } diff --git a/src/main/java/jota/model/Bundle.java b/src/main/java/jota/model/Bundle.java index 91558214..40c0e42b 100644 --- a/src/main/java/jota/model/Bundle.java +++ b/src/main/java/jota/model/Bundle.java @@ -89,11 +89,17 @@ public void addEntry(int signatureMessageLength, String address, long value, Str * @param customCurl The custom curl. */ public void finalize(ICurl customCurl) { + ICurl curl; + int[] normalizedBundleValue; + int[] hash = new int[243]; + int[] obsoleteTagTrits = new int[81]; + String hashInTrytes; + boolean valid = true; + curl = customCurl == null ? SpongeFactory.create(SpongeFactory.Mode.KERL) : customCurl; + do { + curl.reset(); - ICurl curl = customCurl == null ? SpongeFactory.create(SpongeFactory.Mode.KERL) : customCurl; - curl.reset(); - - for (int i = 0; i < this.getTransactions().size(); i++) { + for (int i = 0; i < this.getTransactions().size(); i++) { int[] valueTrits = Converter.trits(this.getTransactions().get(i).getValue(), 81); @@ -110,11 +116,24 @@ public void finalize(ICurl customCurl) { int[] t = Converter.trits(this.getTransactions().get(i).getAddress() + Converter.trytes(valueTrits) + this.getTransactions().get(i).getObsoleteTag() + Converter.trytes(timestampTrits) + Converter.trytes(currentIndexTrits) + Converter.trytes(lastIndexTrits)); curl.absorb(t, 0, t.length); - } + } + + curl.squeeze(hash, 0, hash.length); + hashInTrytes = Converter.trytes(hash); + normalizedBundleValue = normalizedBundle(hashInTrytes); + + boolean foundValue = false; + for (int i = 0; i < normalizedBundleValue.length; i++) { + if (normalizedBundleValue[i] == 13) { + foundValue = true; + obsoleteTagTrits = Converter.trits(this.getTransactions().get(0).getObsoleteTag()); + Converter.increment(obsoleteTagTrits, 81); + this.getTransactions().get(0).setObsoleteTag(Converter.trytes(obsoleteTagTrits)); + } + } + valid = !foundValue; - int[] hash = new int[243]; - curl.squeeze(hash, 0, hash.length); - String hashInTrytes = Converter.trytes(hash); + } while (!valid); for (int i = 0; i < this.getTransactions().size(); i++) { this.getTransactions().get(i).setBundle(hashInTrytes); @@ -210,4 +229,4 @@ public int[] normalizedBundle(String bundleHash) { public int compareTo(Bundle o) { return Long.compare(this.getTransactions().get(0).getAttachmentTimestamp(), o.getTransactions().get(0).getAttachmentTimestamp()); } -} \ No newline at end of file +} diff --git a/src/main/java/jota/utils/IotaAPIUtils.java b/src/main/java/jota/utils/IotaAPIUtils.java index ae2ea2ac..6ab78308 100644 --- a/src/main/java/jota/utils/IotaAPIUtils.java +++ b/src/main/java/jota/utils/IotaAPIUtils.java @@ -96,21 +96,19 @@ public static List signInputsAndReturn(final String seed, // Because the signature is > 2187 trytes, we need to // find the second transaction to add the remainder of the signature - for (int k = 0; k < bundle.getTransactions().size(); k++) { - // Same address as well as value = 0 (as we already spent the input) - if (bundle.getTransactions().get(k).getAddress().equals(thisAddress) && bundle.getTransactions().get(k).getValue() == 0) { - // Use the second 6562 trits - int[] secondFragment = Arrays.copyOfRange(key, 6561, 6561 * 2); + // Same address as well as value = 0 (as we already spent the input) + if (bundle.getTransactions().get(i + j).getAddress().equals(thisAddress) && bundle.getTransactions().get(i + j).getValue() == 0) { + // Use the second 6562 trits + int[] secondFragment = Arrays.copyOfRange(key, 6561 * j, 6561 * (j + 1)); - // The second 27 to 54 trytes of the bundle hash - int[] secondBundleFragment = Arrays.copyOfRange(normalizedBundleHash, 27, 27 * 2); + // The second 27 to 54 trytes of the bundle hash + int[] secondBundleFragment = Arrays.copyOfRange(normalizedBundleHash, 27 * j, 27 * (j + 1)); - // Calculate the new signature - int[] secondSignedFragment = new Signing(curl).signatureFragment(secondBundleFragment, secondFragment); + // Calculate the new signature + int[] secondSignedFragment = new Signing(curl).signatureFragment(secondBundleFragment, secondFragment); - // Convert signature to trytes and assign it again to this bundle entry - bundle.getTransactions().get(k).setSignatureFragments(Converter.trytes(secondSignedFragment)); - } + // Convert signature to trytes and assign it again to this bundle entry + bundle.getTransactions().get(i+j).setSignatureFragments(Converter.trytes(secondSignedFragment)); } } }