diff --git a/README.md b/README.md index a65cedd..f62f766 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,14 @@ Library supports all available EtherScan *API* calls for all available *Ethereum com.github.goodforgod java-etherscan-api - 1.0.1 + 1.0.2 ``` **Gradle** ```groovy dependencies { - compile 'com.github.goodforgod:java-etherscan-api:1.0.1' + compile 'com.github.goodforgod:java-etherscan-api:1.0.2' } ``` @@ -165,6 +165,8 @@ Token API methods migrated to [Account](#account-api) & [Stats](#stats-api) resp ## Version History +**1.0.2** - Minor http client improvements. + **1.0.1** - Gorli & TOBALABA networks support. **1.0.0** - Initial project with all API functionality, for all available networks, with tests coverage for all cases. diff --git a/pom.xml b/pom.xml index 3c6548c..a9bcfa8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.github.goodforgod java-etherscan-api - 1.0.1 + 1.0.2 jar ${project.groupId}:${project.artifactId} diff --git a/src/main/java/io/api/etherscan/executor/impl/HttpExecutor.java b/src/main/java/io/api/etherscan/executor/impl/HttpExecutor.java index 6894b0c..3a33515 100644 --- a/src/main/java/io/api/etherscan/executor/impl/HttpExecutor.java +++ b/src/main/java/io/api/etherscan/executor/impl/HttpExecutor.java @@ -6,12 +6,13 @@ import io.api.etherscan.util.BasicUtils; import java.io.BufferedReader; -import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; +import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.SocketTimeoutException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.zip.GZIPInputStream; @@ -103,14 +104,16 @@ public String get(final String urlAsString) { public String post(final String urlAsString, final String dataToPost) { try { final HttpURLConnection connection = buildConnection(urlAsString, "POST"); - final String contentLength = (BasicUtils.isEmpty(dataToPost)) ? "0" : String.valueOf(dataToPost.length()); - connection.setRequestProperty("content-length", contentLength); + final String contentLength = (BasicUtils.isBlank(dataToPost)) ? "0" : String.valueOf(dataToPost.length()); + connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + connection.setRequestProperty("Content-Length", contentLength); + connection.setFixedLengthStreamingMode(dataToPost.length()); connection.setDoOutput(true); - DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); - wr.writeBytes(dataToPost); - wr.flush(); - wr.close(); + connection.connect(); + try (OutputStream os = connection.getOutputStream()) { + os.write(dataToPost.getBytes(StandardCharsets.UTF_8)); + } final int status = connection.getResponseCode(); if (status == HTTP_MOVED_TEMP || status == HTTP_MOVED_PERM) { @@ -141,13 +144,13 @@ private String readData(final HttpURLConnection connection) throws IOException { } private InputStreamReader getStreamReader(final HttpURLConnection connection) throws IOException { - final boolean haveEncoding = connection.getContentEncoding() != null; - - if (haveEncoding && "gzip".equals(connection.getContentEncoding())) - return new InputStreamReader(new GZIPInputStream(connection.getInputStream()), "utf-8"); - else if (haveEncoding && "deflate".equals(connection.getContentEncoding())) - return new InputStreamReader(new InflaterInputStream(connection.getInputStream()), "utf-8"); - else - return new InputStreamReader(connection.getInputStream(), "utf-8"); + switch (String.valueOf(connection.getContentEncoding())) { + case "gzip": + return new InputStreamReader(new GZIPInputStream(connection.getInputStream()), "utf-8"); + case "deflate": + return new InputStreamReader(new InflaterInputStream(connection.getInputStream()), "utf-8"); + default: + return new InputStreamReader(connection.getInputStream(), "utf-8"); + } } } diff --git a/src/main/java/io/api/etherscan/model/BaseTx.java b/src/main/java/io/api/etherscan/model/BaseTx.java index 85b8f83..af2286f 100644 --- a/src/main/java/io/api/etherscan/model/BaseTx.java +++ b/src/main/java/io/api/etherscan/model/BaseTx.java @@ -73,37 +73,26 @@ public BigInteger getGasUsed() { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (!(o instanceof BaseTx)) return false; BaseTx baseTx = (BaseTx) o; if (blockNumber != baseTx.blockNumber) return false; if (timeStamp != null ? !timeStamp.equals(baseTx.timeStamp) : baseTx.timeStamp != null) return false; - if (_timeStamp != null ? !_timeStamp.equals(baseTx._timeStamp) : baseTx._timeStamp != null) return false; if (hash != null ? !hash.equals(baseTx.hash) : baseTx.hash != null) return false; if (from != null ? !from.equals(baseTx.from) : baseTx.from != null) return false; if (to != null ? !to.equals(baseTx.to) : baseTx.to != null) return false; - if (value != null ? !value.equals(baseTx.value) : baseTx.value != null) return false; - if (contractAddress != null ? !contractAddress.equals(baseTx.contractAddress) : baseTx.contractAddress != null) - return false; - if (input != null ? !input.equals(baseTx.input) : baseTx.input != null) return false; - if (gas != null ? !gas.equals(baseTx.gas) : baseTx.gas != null) return false; - return gasUsed != null ? gasUsed.equals(baseTx.gasUsed) : baseTx.gasUsed == null; + return value != null ? value.equals(baseTx.value) : baseTx.value == null; } @Override public int hashCode() { int result = (int) (blockNumber ^ (blockNumber >>> 32)); result = 31 * result + (timeStamp != null ? timeStamp.hashCode() : 0); - result = 31 * result + (_timeStamp != null ? _timeStamp.hashCode() : 0); result = 31 * result + (hash != null ? hash.hashCode() : 0); result = 31 * result + (from != null ? from.hashCode() : 0); result = 31 * result + (to != null ? to.hashCode() : 0); result = 31 * result + (value != null ? value.hashCode() : 0); - result = 31 * result + (contractAddress != null ? contractAddress.hashCode() : 0); - result = 31 * result + (input != null ? input.hashCode() : 0); - result = 31 * result + (gas != null ? gas.hashCode() : 0); - result = 31 * result + (gasUsed != null ? gasUsed.hashCode() : 0); return result; } @@ -112,7 +101,6 @@ public String toString() { return "BaseTx{" + "blockNumber=" + blockNumber + ", timeStamp='" + timeStamp + '\'' + - ", _timeStamp=" + _timeStamp + ", hash='" + hash + '\'' + ", from='" + from + '\'' + ", to='" + to + '\'' + diff --git a/src/main/java/io/api/etherscan/model/Log.java b/src/main/java/io/api/etherscan/model/Log.java index 85479d9..cf485fd 100644 --- a/src/main/java/io/api/etherscan/model/Log.java +++ b/src/main/java/io/api/etherscan/model/Log.java @@ -106,44 +106,20 @@ public boolean equals(Object o) { Log log = (Log) o; if (blockNumber != null ? !blockNumber.equals(log.blockNumber) : log.blockNumber != null) return false; - if (_blockNumber != null ? !_blockNumber.equals(log._blockNumber) : log._blockNumber != null) return false; if (address != null ? !address.equals(log.address) : log.address != null) return false; if (transactionHash != null ? !transactionHash.equals(log.transactionHash) : log.transactionHash != null) return false; - if (transactionIndex != null ? !transactionIndex.equals(log.transactionIndex) : log.transactionIndex != null) - return false; - if (_transactionIndex != null ? !_transactionIndex.equals(log._transactionIndex) : log._transactionIndex != null) - return false; if (timeStamp != null ? !timeStamp.equals(log.timeStamp) : log.timeStamp != null) return false; - if (_timeStamp != null ? !_timeStamp.equals(log._timeStamp) : log._timeStamp != null) return false; - if (data != null ? !data.equals(log.data) : log.data != null) return false; - if (gasPrice != null ? !gasPrice.equals(log.gasPrice) : log.gasPrice != null) return false; - if (_gasPrice != null ? !_gasPrice.equals(log._gasPrice) : log._gasPrice != null) return false; - if (gasUsed != null ? !gasUsed.equals(log.gasUsed) : log.gasUsed != null) return false; - if (_gasUsed != null ? !_gasUsed.equals(log._gasUsed) : log._gasUsed != null) return false; - if (topics != null ? !topics.equals(log.topics) : log.topics != null) return false; - if (logIndex != null ? !logIndex.equals(log.logIndex) : log.logIndex != null) return false; - return _logIndex != null ? _logIndex.equals(log._logIndex) : log._logIndex == null; + return logIndex != null ? logIndex.equals(log.logIndex) : log.logIndex == null; } @Override public int hashCode() { int result = blockNumber != null ? blockNumber.hashCode() : 0; - result = 31 * result + (_blockNumber != null ? _blockNumber.hashCode() : 0); result = 31 * result + (address != null ? address.hashCode() : 0); result = 31 * result + (transactionHash != null ? transactionHash.hashCode() : 0); - result = 31 * result + (transactionIndex != null ? transactionIndex.hashCode() : 0); - result = 31 * result + (_transactionIndex != null ? _transactionIndex.hashCode() : 0); result = 31 * result + (timeStamp != null ? timeStamp.hashCode() : 0); - result = 31 * result + (_timeStamp != null ? _timeStamp.hashCode() : 0); - result = 31 * result + (data != null ? data.hashCode() : 0); - result = 31 * result + (gasPrice != null ? gasPrice.hashCode() : 0); - result = 31 * result + (_gasPrice != null ? _gasPrice.hashCode() : 0); - result = 31 * result + (gasUsed != null ? gasUsed.hashCode() : 0); - result = 31 * result + (_gasUsed != null ? _gasUsed.hashCode() : 0); - result = 31 * result + (topics != null ? topics.hashCode() : 0); result = 31 * result + (logIndex != null ? logIndex.hashCode() : 0); - result = 31 * result + (_logIndex != null ? _logIndex.hashCode() : 0); return result; } diff --git a/src/main/java/io/api/etherscan/model/Price.java b/src/main/java/io/api/etherscan/model/Price.java index dcb9c4c..f9839e2 100644 --- a/src/main/java/io/api/etherscan/model/Price.java +++ b/src/main/java/io/api/etherscan/model/Price.java @@ -49,11 +49,7 @@ public boolean equals(Object o) { if (Double.compare(price.ethbtc, ethbtc) != 0) return false; if (ethusd_timestamp != null ? !ethusd_timestamp.equals(price.ethusd_timestamp) : price.ethusd_timestamp != null) return false; - if (ethbtc_timestamp != null ? !ethbtc_timestamp.equals(price.ethbtc_timestamp) : price.ethbtc_timestamp != null) - return false; - if (_ethusd_timestamp != null ? !_ethusd_timestamp.equals(price._ethusd_timestamp) : price._ethusd_timestamp != null) - return false; - return _ethbtc_timestamp != null ? _ethbtc_timestamp.equals(price._ethbtc_timestamp) : price._ethbtc_timestamp == null; + return (ethbtc_timestamp != null ? !ethbtc_timestamp.equals(price.ethbtc_timestamp) : price.ethbtc_timestamp != null); } @Override @@ -66,8 +62,6 @@ public int hashCode() { result = 31 * result + (int) (temp ^ (temp >>> 32)); result = 31 * result + (ethusd_timestamp != null ? ethusd_timestamp.hashCode() : 0); result = 31 * result + (ethbtc_timestamp != null ? ethbtc_timestamp.hashCode() : 0); - result = 31 * result + (_ethusd_timestamp != null ? _ethusd_timestamp.hashCode() : 0); - result = 31 * result + (_ethbtc_timestamp != null ? _ethbtc_timestamp.hashCode() : 0); return result; } @@ -78,8 +72,6 @@ public String toString() { ", ethbtc=" + ethbtc + ", ethusd_timestamp='" + ethusd_timestamp + '\'' + ", ethbtc_timestamp='" + ethbtc_timestamp + '\'' + - ", _ethusd_timestamp=" + _ethusd_timestamp + - ", _ethbtc_timestamp=" + _ethbtc_timestamp + '}'; } } diff --git a/src/main/java/io/api/etherscan/model/Tx.java b/src/main/java/io/api/etherscan/model/Tx.java index 9bd2faa..68f00f1 100644 --- a/src/main/java/io/api/etherscan/model/Tx.java +++ b/src/main/java/io/api/etherscan/model/Tx.java @@ -65,13 +65,8 @@ public boolean equals(Object o) { if (nonce != tx.nonce) return false; if (transactionIndex != tx.transactionIndex) return false; - if (confirmations != tx.confirmations) return false; if (blockHash != null ? !blockHash.equals(tx.blockHash) : tx.blockHash != null) return false; - if (gasPrice != null ? !gasPrice.equals(tx.gasPrice) : tx.gasPrice != null) return false; - if (cumulativeGasUsed != null ? !cumulativeGasUsed.equals(tx.cumulativeGasUsed) : tx.cumulativeGasUsed != null) - return false; - if (isError != null ? !isError.equals(tx.isError) : tx.isError != null) return false; - return txreceipt_status != null ? txreceipt_status.equals(tx.txreceipt_status) : tx.txreceipt_status == null; + return isError != null ? isError.equals(tx.isError) : tx.isError == null; } @Override @@ -80,11 +75,7 @@ public int hashCode() { result = 31 * result + (int) (nonce ^ (nonce >>> 32)); result = 31 * result + (blockHash != null ? blockHash.hashCode() : 0); result = 31 * result + transactionIndex; - result = 31 * result + (gasPrice != null ? gasPrice.hashCode() : 0); - result = 31 * result + (cumulativeGasUsed != null ? cumulativeGasUsed.hashCode() : 0); - result = 31 * result + (int) (confirmations ^ (confirmations >>> 32)); result = 31 * result + (isError != null ? isError.hashCode() : 0); - result = 31 * result + (txreceipt_status != null ? txreceipt_status.hashCode() : 0); return result; } @@ -99,6 +90,6 @@ public String toString() { ", confirmations=" + confirmations + ", isError='" + isError + '\'' + ", txreceipt_status='" + txreceipt_status + '\'' + - '}'; + "} " + super.toString(); } } diff --git a/src/main/java/io/api/etherscan/model/TxInternal.java b/src/main/java/io/api/etherscan/model/TxInternal.java index f505fd1..1d9d8a8 100644 --- a/src/main/java/io/api/etherscan/model/TxInternal.java +++ b/src/main/java/io/api/etherscan/model/TxInternal.java @@ -34,23 +34,19 @@ public String getErrCode() { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (!(o instanceof TxInternal)) return false; if (!super.equals(o)) return false; TxInternal that = (TxInternal) o; if (traceId != that.traceId) return false; - if (isError != that.isError) return false; - if (type != null ? !type.equals(that.type) : that.type != null) return false; return errCode != null ? errCode.equals(that.errCode) : that.errCode == null; } @Override public int hashCode() { int result = super.hashCode(); - result = 31 * result + (type != null ? type.hashCode() : 0); result = 31 * result + (int) (traceId ^ (traceId >>> 32)); - result = 31 * result + isError; result = 31 * result + (errCode != null ? errCode.hashCode() : 0); return result; } @@ -62,6 +58,6 @@ public String toString() { ", traceId=" + traceId + ", isError=" + isError + ", errCode='" + errCode + '\'' + - '}'; + "} " + super.toString(); } } diff --git a/src/main/java/io/api/etherscan/model/TxToken.java b/src/main/java/io/api/etherscan/model/TxToken.java index 0046e02..985066b 100644 --- a/src/main/java/io/api/etherscan/model/TxToken.java +++ b/src/main/java/io/api/etherscan/model/TxToken.java @@ -56,40 +56,6 @@ public long getConfirmations() { } // - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - - TxToken txToken = (TxToken) o; - - if (nonce != txToken.nonce) return false; - if (transactionIndex != txToken.transactionIndex) return false; - if (gasPrice != txToken.gasPrice) return false; - if (cumulativeGasUsed != txToken.cumulativeGasUsed) return false; - if (confirmations != txToken.confirmations) return false; - if (blockHash != null ? !blockHash.equals(txToken.blockHash) : txToken.blockHash != null) return false; - if (tokenName != null ? !tokenName.equals(txToken.tokenName) : txToken.tokenName != null) return false; - if (tokenSymbol != null ? !tokenSymbol.equals(txToken.tokenSymbol) : txToken.tokenSymbol != null) return false; - return tokenDecimal != null ? tokenDecimal.equals(txToken.tokenDecimal) : txToken.tokenDecimal == null; - } - - @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + (int) (nonce ^ (nonce >>> 32)); - result = 31 * result + (blockHash != null ? blockHash.hashCode() : 0); - result = 31 * result + (tokenName != null ? tokenName.hashCode() : 0); - result = 31 * result + (tokenSymbol != null ? tokenSymbol.hashCode() : 0); - result = 31 * result + (tokenDecimal != null ? tokenDecimal.hashCode() : 0); - result = 31 * result + transactionIndex; - result = 31 * result + (int) (gasPrice ^ (gasPrice >>> 32)); - result = 31 * result + (int) (cumulativeGasUsed ^ (cumulativeGasUsed >>> 32)); - result = 31 * result + (int) (confirmations ^ (confirmations >>> 32)); - return result; - } - @Override public String toString() { return "TxToken{" + @@ -102,6 +68,6 @@ public String toString() { ", gasPrice=" + gasPrice + ", cumulativeGasUsed=" + cumulativeGasUsed + ", confirmations=" + confirmations + - '}'; + "} " + super.toString(); } } diff --git a/src/test/java/io/api/etherscan/account/AccountTxTokenTest.java b/src/test/java/io/api/etherscan/account/AccountTxTokenTest.java index 52fae6e..7bdf2d6 100644 --- a/src/test/java/io/api/etherscan/account/AccountTxTokenTest.java +++ b/src/test/java/io/api/etherscan/account/AccountTxTokenTest.java @@ -20,15 +20,21 @@ public class AccountTxTokenTest extends Assert { @Test public void correct() { - List txs = api.account().txsToken("0x05fBf1E3f105df6a4553f3C7f2ed93070A4BAB46"); + List txs = api.account().txsToken("0xE376F69ED2218076682e2b3B7b9099eC50aD68c4"); assertNotNull(txs); - assertEquals(106, txs.size()); + assertEquals(3, txs.size()); assertTxs(txs); assertNotEquals(0, txs.get(0).getGasPrice()); assertNotEquals(-1, txs.get(0).getNonce()); + assertNotNull(txs.get(0).toString()); + assertNotEquals(txs.get(0).toString(), txs.get(1).toString()); + assertNotEquals(txs.get(0), txs.get(1)); assertNotEquals(txs.get(0).hashCode(), txs.get(1).hashCode()); + + assertEquals(txs.get(1), txs.get(1)); + assertEquals(txs.get(1).hashCode(), txs.get(1).hashCode()); } @Test diff --git a/src/test/java/io/api/etherscan/account/AccountTxsTest.java b/src/test/java/io/api/etherscan/account/AccountTxsTest.java index 7e9e05b..5c0ad48 100644 --- a/src/test/java/io/api/etherscan/account/AccountTxsTest.java +++ b/src/test/java/io/api/etherscan/account/AccountTxsTest.java @@ -38,6 +38,7 @@ public void correct() { assertNotNull(txs.get(0).toString()); assertNotEquals(txs.get(0), txs.get(1)); assertNotEquals(txs.get(0).hashCode(), txs.get(1).hashCode()); + assertEquals(txs.get(1), txs.get(1)); } @Test diff --git a/src/test/java/io/api/etherscan/block/BlockApiTest.java b/src/test/java/io/api/etherscan/block/BlockApiTest.java index 2500d3b..c459b1a 100644 --- a/src/test/java/io/api/etherscan/block/BlockApiTest.java +++ b/src/test/java/io/api/etherscan/block/BlockApiTest.java @@ -28,12 +28,24 @@ public void correct() { assertFalse(uncle.get().getUncles().isEmpty()); assertNotNull(uncle.get().getUncles().get(0).getBlockreward()); assertNotNull(uncle.get().getUncles().get(0).getMiner()); + assertNotEquals(-1, uncle.get().getUncles().get(0).getUnclePosition()); assertNotNull(uncle.get().toString()); UncleBlock empty = new UncleBlock(); assertNotEquals(uncle.get().hashCode(), empty.hashCode()); assertNotEquals(uncle.get(), empty); assertTrue(empty.isEmpty()); + + if(uncle.get().getUncles().size() > 0) { + assertNotEquals(-1, uncle.get().getUncles().get(0).getUnclePosition()); + assertEquals(uncle.get().getUncles().get(0), uncle.get().getUncles().get(0)); + assertEquals(uncle.get().getUncles().get(0).hashCode(), uncle.get().getUncles().get(0).hashCode()); + } + + if(uncle.get().getUncles().size() > 1) { + assertNotEquals(uncle.get().getUncles().get(1), uncle.get().getUncles().get(0)); + assertNotEquals(uncle.get().getUncles().get(1).hashCode(), uncle.get().getUncles().get(0).hashCode()); + } } @Test diff --git a/src/test/java/io/api/etherscan/logs/LogsApiTest.java b/src/test/java/io/api/etherscan/logs/LogsApiTest.java index d562321..4a3f9e1 100644 --- a/src/test/java/io/api/etherscan/logs/LogsApiTest.java +++ b/src/test/java/io/api/etherscan/logs/LogsApiTest.java @@ -86,6 +86,9 @@ public void validateQuery() { assertNotNull(logs.get(0).getLogIndex()); assertNotNull(logs.get(0).getGasPrice()); assertNotNull(logs.get(0).toString()); + + assertEquals(logs.get(0), logs.get(0)); + assertEquals(logs.get(0).hashCode(), logs.get(0).hashCode()); } } }