diff --git a/examples/src/main/java/com/hedera/hashgraph/sdk/examples/MirrorNodeContractQueriesExample.java b/examples/src/main/java/com/hedera/hashgraph/sdk/examples/MirrorNodeContractQueriesExample.java
new file mode 100644
index 000000000..0180cc224
--- /dev/null
+++ b/examples/src/main/java/com/hedera/hashgraph/sdk/examples/MirrorNodeContractQueriesExample.java
@@ -0,0 +1,176 @@
+/*-
+ *
+ * Hedera Java SDK
+ *
+ * Copyright (C) 2023 - 2024 Hedera Hashgraph, LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.hedera.hashgraph.sdk.examples;
+
+import com.hedera.hashgraph.sdk.AccountId;
+import com.hedera.hashgraph.sdk.Client;
+import com.hedera.hashgraph.sdk.ContractCallQuery;
+import com.hedera.hashgraph.sdk.ContractCreateTransaction;
+import com.hedera.hashgraph.sdk.ContractFunctionParameters;
+import com.hedera.hashgraph.sdk.FileCreateTransaction;
+import com.hedera.hashgraph.sdk.FileId;
+import com.hedera.hashgraph.sdk.Hbar;
+import com.hedera.hashgraph.sdk.MirrorNodeContractCallQuery;
+import com.hedera.hashgraph.sdk.MirrorNodeContractEstimateGasQuery;
+import com.hedera.hashgraph.sdk.MirrorNodeContractQuery;
+import com.hedera.hashgraph.sdk.PrivateKey;
+import com.hedera.hashgraph.sdk.PublicKey;
+import com.hedera.hashgraph.sdk.TransactionReceipt;
+import com.hedera.hashgraph.sdk.TransactionResponse;
+import com.hedera.hashgraph.sdk.logger.LogLevel;
+import com.hedera.hashgraph.sdk.logger.Logger;
+import io.github.cdimascio.dotenv.Dotenv;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+
+public class MirrorNodeContractQueriesExample {
+ /*
+ * See .env.sample in the examples folder root for how to specify values below
+ * or set environment variables with the same names.
+ */
+
+ /**
+ * Operator's account ID.
+ * Used to sign and pay for operations on Hedera.
+ */
+ private static final AccountId OPERATOR_ID = AccountId.fromString(Objects.requireNonNull(Dotenv.load().get("OPERATOR_ID")));
+
+ /**
+ * Operator's private key.
+ */
+ private static final PrivateKey OPERATOR_KEY = PrivateKey.fromString(Objects.requireNonNull(Dotenv.load().get("OPERATOR_KEY")));
+
+ /**
+ * HEDERA_NETWORK defaults to testnet if not specified in dotenv file.
+ * Network can be: localhost, testnet, previewnet or mainnet.
+ */
+ private static final String HEDERA_NETWORK = Dotenv.load().get("HEDERA_NETWORK", "testnet");
+
+ /**
+ * SDK_LOG_LEVEL defaults to SILENT if not specified in dotenv file.
+ * Log levels can be: TRACE, DEBUG, INFO, WARN, ERROR, SILENT.
+ *
+ * Important pre-requisite: set simple logger log level to same level as the SDK_LOG_LEVEL,
+ * for example via VM options: -Dorg.slf4j.simpleLogger.log.com.hedera.hashgraph=trace
+ */
+ private static final String SDK_LOG_LEVEL = Dotenv.load().get("SDK_LOG_LEVEL", "SILENT");
+
+ private static final String SMART_CONTRACT_BYTECODE = "608060405234801561001057600080fd5b506040516104d73803806104d78339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825164010000000081118282018810171561008257600080fd5b82525081516020918201929091019080838360005b838110156100af578181015183820152602001610097565b50505050905090810190601f1680156100dc5780820380516001836020036101000a031916815260200191505b506040525050600080546001600160a01b0319163317905550805161010890600190602084019061010f565b50506101aa565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061015057805160ff191683800117855561017d565b8280016001018555821561017d579182015b8281111561017d578251825591602001919060010190610162565b5061018992915061018d565b5090565b6101a791905b808211156101895760008155600101610193565b90565b61031e806101b96000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063368b87721461004657806341c0e1b5146100ee578063ce6d41de146100f6575b600080fd5b6100ec6004803603602081101561005c57600080fd5b81019060208101813564010000000081111561007757600080fd5b82018360208201111561008957600080fd5b803590602001918460018302840111640100000000831117156100ab57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610173945050505050565b005b6100ec6101a2565b6100fe6101ba565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610138578181015183820152602001610120565b50505050905090810190601f1680156101655780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000546001600160a01b0316331461018a5761019f565b805161019d906001906020840190610250565b505b50565b6000546001600160a01b03163314156101b85733ff5b565b60018054604080516020601f600260001961010087891615020190951694909404938401819004810282018101909252828152606093909290918301828280156102455780601f1061021a57610100808354040283529160200191610245565b820191906000526020600020905b81548152906001019060200180831161022857829003601f168201915b505050505090505b90565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061029157805160ff19168380011785556102be565b828001600101855582156102be579182015b828111156102be5782518255916020019190600101906102a3565b506102ca9291506102ce565b5090565b61024d91905b808211156102ca57600081556001016102d456fea264697066735822122084964d4c3f6bc912a9d20e14e449721012d625aa3c8a12de41ae5519752fc89064736f6c63430006000033";
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("Mirror node contract query Example Start!");
+
+ /*
+ * Step 0:
+ * Create and configure the SDK Client.
+ */
+ Client client = ClientHelper.forName(HEDERA_NETWORK);
+ // All generated transactions will be paid by this account and signed by this key.
+ client.setOperator(OPERATOR_ID, OPERATOR_KEY);
+ // Attach logger to the SDK Client.
+ client.setLogger(new Logger(LogLevel.valueOf(SDK_LOG_LEVEL)));
+
+ var operatorPublicKey = OPERATOR_KEY.getPublicKey();
+
+ /*
+ * Step 1:
+ * Create the contract
+ */
+ System.out.println("Creating new file...");
+ TransactionResponse fileCreateTxResponse = new FileCreateTransaction()
+ // Use the same key as the operator to "own" this file.
+ .setKeys(operatorPublicKey)
+ .setContents(SMART_CONTRACT_BYTECODE)
+ // The default max fee of 1 Hbar is not enough to create a file (starts around ~1.1 Hbar).
+ .setMaxTransactionFee(Hbar.from(2))
+ .execute(client);
+
+ TransactionReceipt fileCreateTxReceipt = fileCreateTxResponse.getReceipt(client);
+ FileId newFileId = fileCreateTxReceipt.fileId;
+
+ Objects.requireNonNull(newFileId);
+ System.out.println("Created new file with ID: " + newFileId);
+
+ var response = new ContractCreateTransaction()
+ .setAdminKey(client.getOperatorPublicKey())
+ .setGas(200000)
+ .setConstructorParameters(new ContractFunctionParameters().addString("Hello from Hedera."))
+ .setBytecodeFileId(newFileId)
+ .setContractMemo("Simple contract with string field")
+ .execute(client);
+
+ var contractId = Objects.requireNonNull(response.getReceipt(client).contractId);
+
+ /*
+ * Step 3:
+ * Wait for mirror node to import data
+ */
+ Thread.sleep(4000);
+
+ /*
+ * Step 4:
+ * Estimate the gas needed
+ */
+ var gas = new MirrorNodeContractEstimateGasQuery()
+ .setContractId(contractId)
+ .setFunction("getMessage")
+ .execute(client);
+
+ System.out.println("Gas needed for this query: " + gas);
+
+ /*
+ * Step 5:
+ * Do the query against the consensus node using the estimated gas
+ */
+ var callQuery = new ContractCallQuery()
+ .setContractId(contractId)
+ .setGas(gas)
+ .setFunction("getMessage")
+ .setQueryPayment(new Hbar(1));
+
+ var result = callQuery
+ .execute(client);
+
+ /*
+ * Step 5:
+ * Simulate the transaction for free, using the mirror node
+ */
+ var simulationResult = new MirrorNodeContractCallQuery()
+ .setContractId(contractId)
+ .setFunction("getMessage")
+ .execute(client);
+
+ System.out.println("Simulation result: " + decodeABIHex(simulationResult.substring(2)));
+ System.out.println("Contract call result: " + result.getString(0));
+ }
+ private static String decodeABIHex(String hex) {
+ int length = Integer.parseInt(hex.substring(64, 128), 16);
+
+ String hexStringData = hex.substring(128, 128 + length * 2);
+
+ byte[] bytes = new byte[length];
+ for (int i = 0; i < length; i++) {
+ bytes[i] = (byte) Integer.parseInt(hexStringData.substring(i * 2, i * 2 + 2), 16);
+ }
+
+ return new String(bytes, StandardCharsets.UTF_8);
+ }
+}
diff --git a/sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractCallQuery.java b/sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractCallQuery.java
new file mode 100644
index 000000000..7601f683c
--- /dev/null
+++ b/sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractCallQuery.java
@@ -0,0 +1,42 @@
+/*-
+ *
+ * Hedera Java SDK
+ *
+ * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.hedera.hashgraph.sdk;
+
+import java.util.concurrent.ExecutionException;
+
+public class MirrorNodeContractCallQuery extends MirrorNodeContractQuery {
+ /**
+ * Does transient simulation of read-write operations and returns the result in hexadecimal string format.
+ *
+ * @param client The Client instance to perform the operation with
+ * @return The result of the contract call
+ * @throws ExecutionException
+ * @throws InterruptedException
+ */
+ public String execute(Client client) throws ExecutionException, InterruptedException {
+ return call(client);
+ }
+
+ @Override
+ public String toString() {
+ return "MirrorNodeContractCallQuery" + super.toString();
+ }
+}
diff --git a/sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractEstimateGasQuery.java b/sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractEstimateGasQuery.java
new file mode 100644
index 000000000..2c9562c95
--- /dev/null
+++ b/sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractEstimateGasQuery.java
@@ -0,0 +1,43 @@
+/*-
+ *
+ * Hedera Java SDK
+ *
+ * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.hedera.hashgraph.sdk;
+
+import java.util.concurrent.ExecutionException;
+
+public class MirrorNodeContractEstimateGasQuery extends MirrorNodeContractQuery {
+
+ /**
+ * Returns gas estimation for the EVM execution.
+ *
+ * @param client The Client instance to perform the operation with
+ * @return The estimated gas cost
+ * @throws ExecutionException
+ * @throws InterruptedException
+ */
+ public long execute(Client client) throws ExecutionException, InterruptedException {
+ return estimate(client);
+ }
+
+ @Override
+ public String toString() {
+ return "MirrorNodeContractEstimateGasQuery" + super.toString();
+ }
+}
diff --git a/sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractQuery.java b/sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractQuery.java
index c49032c38..6047ea64c 100644
--- a/sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractQuery.java
+++ b/sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractQuery.java
@@ -38,7 +38,7 @@
* MirrorNodeContractQuery returns a result from EVM execution such as cost-free execution of read-only smart contract
* queries, gas estimation, and transient simulation of read-write operations.
*/
-public class MirrorNodeContractQuery {
+public abstract class MirrorNodeContractQuery> {
// The contract we are sending the transaction to
private ContractId contractId = null;
private String contractEvmAddress = null;
@@ -56,6 +56,11 @@ public class MirrorNodeContractQuery {
// The block number for the simulation
private long blockNumber;
+ @SuppressWarnings("unchecked")
+ protected T self() {
+ return (T) this;
+ }
+
public ContractId getContractId() {
return this.contractId;
}
@@ -66,10 +71,10 @@ public ContractId getContractId() {
* @param contractId The ContractId to be set
* @return {@code this}
*/
- public MirrorNodeContractQuery setContractId(ContractId contractId) {
+ public T setContractId(ContractId contractId) {
Objects.requireNonNull(contractId);
this.contractId = contractId;
- return this;
+ return self();
}
public String getContractEvmAddress() {
@@ -82,11 +87,11 @@ public String getContractEvmAddress() {
* @param contractEvmAddress
* @return {@code this}
*/
- public MirrorNodeContractQuery setContractEvmAddress(String contractEvmAddress) {
+ public T setContractEvmAddress(String contractEvmAddress) {
Objects.requireNonNull(contractEvmAddress);
this.contractEvmAddress = contractEvmAddress;
this.contractId = null;
- return this;
+ return self();
}
public AccountId getSender() {
@@ -99,10 +104,10 @@ public AccountId getSender() {
* @param sender The AccountId to be set
* @return {@code this}
*/
- public MirrorNodeContractQuery setSender(AccountId sender) {
+ public T setSender(AccountId sender) {
Objects.requireNonNull(sender);
this.sender = sender;
- return this;
+ return self();
}
public String getSenderEvmAddress() {
@@ -115,11 +120,11 @@ public String getSenderEvmAddress() {
* @param senderEvmAddress
* @return {@code this}
*/
- public MirrorNodeContractQuery setSenderEvmAddress(String senderEvmAddress) {
+ public T setSenderEvmAddress(String senderEvmAddress) {
Objects.requireNonNull(senderEvmAddress);
this.senderEvmAddress = senderEvmAddress;
this.sender = null;
- return this;
+ return self();
}
public byte[] getCallData() {
@@ -133,7 +138,7 @@ public byte[] getCallData() {
* @param params The function parameters to be set
* @return {@code this}
*/
- public MirrorNodeContractQuery setFunction(String name, ContractFunctionParameters params) {
+ public T setFunction(String name, ContractFunctionParameters params) {
Objects.requireNonNull(params);
return setFunctionParameters(params.toBytes(name));
}
@@ -147,7 +152,7 @@ public MirrorNodeContractQuery setFunction(String name, ContractFunctionParamete
* @param name The String to be set as the function name
* @return {@code this}
*/
- public MirrorNodeContractQuery setFunction(String name) {
+ public T setFunction(String name) {
return setFunction(name, new ContractFunctionParameters());
}
@@ -160,10 +165,10 @@ public MirrorNodeContractQuery setFunction(String name) {
* @param functionParameters The function parameters to be set
* @return {@code this}
*/
- public MirrorNodeContractQuery setFunctionParameters(ByteString functionParameters) {
+ public T setFunctionParameters(ByteString functionParameters) {
Objects.requireNonNull(functionParameters);
this.callData = functionParameters.toByteArray();
- return this;
+ return self();
}
public long getValue() {
@@ -178,9 +183,9 @@ public long getValue() {
* @param value the amount of value to send, in tinybars or wei
* @return {@code this}
*/
- public MirrorNodeContractQuery setValue(long value) {
+ public T setValue(long value) {
this.value = value;
- return this;
+ return self();
}
public long getGasLimit() {
@@ -195,9 +200,9 @@ public long getGasLimit() {
* @param gasLimit the maximum gas allowed for the transaction
* @return {@code this}
*/
- public MirrorNodeContractQuery setGasLimit(long gasLimit) {
+ public T setGasLimit(long gasLimit) {
this.gasLimit = gasLimit;
- return this;
+ return self();
}
public long getGasPrice() {
@@ -212,9 +217,9 @@ public long getGasPrice() {
* @param gasPrice the gas price, in tinybars or wei, for each unit of gas
* @return {@code this}
*/
- public MirrorNodeContractQuery setGasPrice(long gasPrice) {
+ public T setGasPrice(long gasPrice) {
this.gasPrice = gasPrice;
- return this;
+ return self();
}
public long getBlockNumber() {
@@ -229,9 +234,9 @@ public long getBlockNumber() {
* @param blockNumber the block number at which to simulate the contract call
* @return {@code this}
*/
- public MirrorNodeContractQuery setBlockNumber(long blockNumber) {
+ public T setBlockNumber(long blockNumber) {
this.blockNumber = blockNumber;
- return this;
+ return self();
}
/**
@@ -241,7 +246,7 @@ public MirrorNodeContractQuery setBlockNumber(long blockNumber) {
* @throws ExecutionException
* @throws InterruptedException
*/
- public long estimate(Client client) throws ExecutionException, InterruptedException {
+ protected long estimate(Client client) throws ExecutionException, InterruptedException {
fillEvmAddresses(client);
return getEstimateGasFromMirrorNodeAsync(client).get();
}
@@ -254,7 +259,7 @@ public long estimate(Client client) throws ExecutionException, InterruptedExcept
* @throws ExecutionException
* @throws InterruptedException
*/
- public String call(Client client) throws ExecutionException, InterruptedException {
+ protected String call(Client client) throws ExecutionException, InterruptedException {
fillEvmAddresses(client);
var blockNum = this.blockNumber == 0 ? "latest" : String.valueOf(this.blockNumber);
return getContractCallResultFromMirrorNodeAsync(client, blockNum).get();
@@ -276,7 +281,7 @@ private CompletableFuture getContractCallResultFromMirrorNodeAsync(Clien
.thenApply(MirrorNodeContractQuery::parseContractCallResult);
}
- public CompletableFuture getEstimateGasFromMirrorNodeAsync(Client client) {
+ private CompletableFuture getEstimateGasFromMirrorNodeAsync(Client client) {
return executeMirrorNodeRequest(client, "latest", true)
.thenApply(MirrorNodeContractQuery::parseHexEstimateToLong);
}
@@ -331,7 +336,7 @@ static long parseHexEstimateToLong(String responseBody) {
@Override
public String toString() {
- return "MirrorNodeContractQuery{" +
+ return "{" +
"contractId=" + contractId +
", contractEvmAddress='" + contractEvmAddress + '\'' +
", sender=" + sender +
diff --git a/sdk/src/test/java/com/hedera/hashgraph/sdk/MirrorNodeContractQueryTest.java b/sdk/src/test/java/com/hedera/hashgraph/sdk/MirrorNodeContractQueryTest.java
index 1f612aa8c..888672bd1 100644
--- a/sdk/src/test/java/com/hedera/hashgraph/sdk/MirrorNodeContractQueryTest.java
+++ b/sdk/src/test/java/com/hedera/hashgraph/sdk/MirrorNodeContractQueryTest.java
@@ -36,7 +36,8 @@
class MirrorNodeContractQueryTest {
- private MirrorNodeContractQuery query;
+ private MirrorNodeContractEstimateGasQuery mirrorNodeContractEstimateGasQuery;
+ private MirrorNodeContractCallQuery mirrorNodeContractCallQuery;
private ContractId mockContractId;
@BeforeAll
@@ -51,81 +52,108 @@ public static void afterAll() {
@BeforeEach
void setUp() {
- query = new MirrorNodeContractQuery();
+ mirrorNodeContractEstimateGasQuery = new MirrorNodeContractEstimateGasQuery();
+ mirrorNodeContractCallQuery = new MirrorNodeContractCallQuery();
mockContractId = Mockito.mock(ContractId.class);
}
@Test
void testSetAndGetContractId() {
- query.setContractId(mockContractId);
- assertEquals(mockContractId, query.getContractId());
+ mirrorNodeContractEstimateGasQuery.setContractId(mockContractId);
+ assertEquals(mockContractId, mirrorNodeContractEstimateGasQuery.getContractId());
+
+ mirrorNodeContractCallQuery.setContractId(mockContractId);
+ assertEquals(mockContractId, mirrorNodeContractCallQuery.getContractId());
}
@Test
void testSetContractIdWithNullThrowsException() {
- assertThrows(NullPointerException.class, () -> query.setContractId(null));
+ assertThrows(NullPointerException.class, () -> mirrorNodeContractEstimateGasQuery.setContractId(null));
+ assertThrows(NullPointerException.class, () -> mirrorNodeContractCallQuery.setContractId(null));
}
@Test
void testSetAndGetContractEvmAddress() {
String evmAddress = "0x1234567890abcdef1234567890abcdef12345678";
- query.setContractEvmAddress(evmAddress);
- assertEquals(evmAddress, query.getContractEvmAddress());
- assertNull(query.getContractId());
+ mirrorNodeContractEstimateGasQuery.setContractEvmAddress(evmAddress);
+ assertEquals(evmAddress, mirrorNodeContractEstimateGasQuery.getContractEvmAddress());
+ assertNull(mirrorNodeContractEstimateGasQuery.getContractId());
+
+ mirrorNodeContractCallQuery.setContractEvmAddress(evmAddress);
+ assertEquals(evmAddress, mirrorNodeContractCallQuery.getContractEvmAddress());
+ assertNull(mirrorNodeContractCallQuery.getContractId());
}
@Test
void testSetContractEvmAddressWithNullThrowsException() {
- assertThrows(NullPointerException.class, () -> query.setContractEvmAddress(null));
+ assertThrows(NullPointerException.class, () -> mirrorNodeContractEstimateGasQuery.setContractEvmAddress(null));
+ assertThrows(NullPointerException.class, () -> mirrorNodeContractCallQuery.setContractEvmAddress(null));
}
@Test
void testSetAndGetcallData() {
ByteString params = ByteString.copyFromUtf8("test");
- query.setFunctionParameters(params);
- assertArrayEquals(params.toByteArray(), query.getCallData());
+ mirrorNodeContractEstimateGasQuery.setFunctionParameters(params);
+ assertArrayEquals(params.toByteArray(), mirrorNodeContractEstimateGasQuery.getCallData());
+
+ mirrorNodeContractCallQuery.setFunctionParameters(params);
+ assertArrayEquals(params.toByteArray(), mirrorNodeContractCallQuery.getCallData());
}
@Test
void testSetFunctionWithoutParameters() {
- query.setFunction("myFunction");
- assertNotNull(query.getCallData());
+ mirrorNodeContractEstimateGasQuery.setFunction("myFunction");
+ assertNotNull(mirrorNodeContractEstimateGasQuery.getCallData());
}
@Test
void testSetAndGetBlockNumber() {
long blockNumber = 123456;
- query.setBlockNumber(blockNumber);
- assertEquals(blockNumber, query.getBlockNumber());
+ mirrorNodeContractEstimateGasQuery.setBlockNumber(blockNumber);
+ assertEquals(blockNumber, mirrorNodeContractEstimateGasQuery.getBlockNumber());
+
+ mirrorNodeContractCallQuery.setBlockNumber(blockNumber);
+ assertEquals(blockNumber, mirrorNodeContractCallQuery.getBlockNumber());
}
@Test
void testSetAndGetValue() {
long value = 1000;
- query.setValue(value);
- assertEquals(value, query.getValue());
+ mirrorNodeContractEstimateGasQuery.setValue(value);
+ assertEquals(value, mirrorNodeContractEstimateGasQuery.getValue());
+
+ mirrorNodeContractCallQuery.setValue(value);
+ assertEquals(value, mirrorNodeContractCallQuery.getValue());
}
@Test
void testSetAndGetGas() {
long gas = 50000;
- query.setGasLimit(gas);
- assertEquals(gas, query.getGasLimit());
+ mirrorNodeContractEstimateGasQuery.setGasLimit(gas);
+ assertEquals(gas, mirrorNodeContractEstimateGasQuery.getGasLimit());
+
+ mirrorNodeContractCallQuery.setGasLimit(gas);
+ assertEquals(gas, mirrorNodeContractCallQuery.getGasLimit());
}
@Test
void testSetAndGetGasPrice() {
long gasPrice = 200;
- query.setGasPrice(gasPrice);
- assertEquals(gasPrice, query.getGasPrice());
+ mirrorNodeContractEstimateGasQuery.setGasPrice(gasPrice);
+ assertEquals(gasPrice, mirrorNodeContractEstimateGasQuery.getGasPrice());
+
+ mirrorNodeContractCallQuery.setGasPrice(gasPrice);
+ assertEquals(gasPrice, mirrorNodeContractCallQuery.getGasPrice());
}
@Test
void testEstimateGasWithMissingContractIdOrEvmAddressThrowsException() {
ByteString params = ByteString.copyFromUtf8("gasParams");
- query.setFunctionParameters(params);
+ mirrorNodeContractEstimateGasQuery.setFunctionParameters(params);
+ assertThrows(NullPointerException.class, () -> mirrorNodeContractEstimateGasQuery.estimate(null));
- assertThrows(NullPointerException.class, () -> query.estimate(null));
+ mirrorNodeContractCallQuery.setFunctionParameters(params);
+ assertThrows(NullPointerException.class, () -> mirrorNodeContractCallQuery.estimate(null));
}
@Test
@@ -256,7 +284,7 @@ void shouldSerialize() {
long testGasPrice = 20L;
long testBlockNumber = 123456L;
- var query = new MirrorNodeContractQuery()
+ var mirrorNodeContractEstimateGasQuery = new MirrorNodeContractEstimateGasQuery()
.setContractId(testContractId)
.setContractEvmAddress(testEvmAddress)
.setSender(testSenderId)
@@ -268,7 +296,20 @@ void shouldSerialize() {
.setGasPrice(testGasPrice)
.setBlockNumber(testBlockNumber);
- SnapshotMatcher.expect(query.toString()
+ var mirrorNodeContractCallQuery = new MirrorNodeContractCallQuery()
+ .setContractId(testContractId)
+ .setContractEvmAddress(testEvmAddress)
+ .setSender(testSenderId)
+ .setSenderEvmAddress(testSenderEvmAddress)
+ .setFunction(testFunctionName, testParams)
+ .setFunctionParameters(testCallData)
+ .setValue(testValue)
+ .setGasLimit(testGasLimit)
+ .setGasPrice(testGasPrice)
+ .setBlockNumber(testBlockNumber);
+
+
+ SnapshotMatcher.expect(mirrorNodeContractEstimateGasQuery.toString() + mirrorNodeContractCallQuery.toString()
).toMatchSnapshot();
}
}
diff --git a/sdk/src/test/java/com/hedera/hashgraph/sdk/MirrorNodeContractQueryTest.snap b/sdk/src/test/java/com/hedera/hashgraph/sdk/MirrorNodeContractQueryTest.snap
index 6f22e4bfe..2394e7ccf 100644
--- a/sdk/src/test/java/com/hedera/hashgraph/sdk/MirrorNodeContractQueryTest.snap
+++ b/sdk/src/test/java/com/hedera/hashgraph/sdk/MirrorNodeContractQueryTest.snap
@@ -1,3 +1,3 @@
com.hedera.hashgraph.sdk.MirrorNodeContractQueryTest.shouldSerialize=[
- "MirrorNodeContractQuery{contractId=null, contractEvmAddress='0x1234567890abcdef1234567890abcdef12345678', sender=null, senderEvmAddress='0xabcdefabcdefabcdefabcdefabcdefabcdef', callData=[116, 101, 115, 116, 68, 97, 116, 97], value=1000, gasLimit=500000, gasPrice=20, blockNumber=123456}"
+ "MirrorNodeContractEstimateGasQuery{contractId=null, contractEvmAddress='0x1234567890abcdef1234567890abcdef12345678', sender=null, senderEvmAddress='0xabcdefabcdefabcdefabcdefabcdefabcdef', callData=[116, 101, 115, 116, 68, 97, 116, 97], value=1000, gasLimit=500000, gasPrice=20, blockNumber=123456}MirrorNodeContractCallQuery{contractId=null, contractEvmAddress='0x1234567890abcdef1234567890abcdef12345678', sender=null, senderEvmAddress='0xabcdefabcdefabcdefabcdefabcdefabcdef', callData=[116, 101, 115, 116, 68, 97, 116, 97], value=1000, gasLimit=500000, gasPrice=20, blockNumber=123456}"
]
\ No newline at end of file
diff --git a/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractCallIntegrationTest.java b/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractCallIntegrationTest.java
index 192fcb17b..141bf9467 100644
--- a/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractCallIntegrationTest.java
+++ b/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractCallIntegrationTest.java
@@ -27,6 +27,7 @@
import com.hedera.hashgraph.sdk.FileDeleteTransaction;
import com.hedera.hashgraph.sdk.Hbar;
import com.hedera.hashgraph.sdk.MaxQueryPaymentExceededException;
+import com.hedera.hashgraph.sdk.MirrorNodeContractEstimateGasQuery;
import com.hedera.hashgraph.sdk.MirrorNodeContractQuery;
import com.hedera.hashgraph.sdk.PrecheckStatusException;
import com.hedera.hashgraph.sdk.Status;
@@ -66,10 +67,10 @@ void canCallContractFunction() throws Exception {
// Wait for mirror node to import data
Thread.sleep(2000);
- var gas = new MirrorNodeContractQuery()
+ var gas = new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setFunction("getMessage")
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var callQuery = new ContractCallQuery()
.setContractId(contractId)
@@ -256,10 +257,10 @@ void getCostBigMaxContractCallFunction() throws Exception {
// Wait for mirror node to import data
Thread.sleep(2000);
- var gas = new MirrorNodeContractQuery()
+ long gas = new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setFunction("getMessage")
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var callQuery = new ContractCallQuery()
.setContractId(contractId)
@@ -311,10 +312,10 @@ void getCostSmallMaxContractCallFunction() throws Exception {
// Wait for mirror node to import data
Thread.sleep(2000);
- var gas = new MirrorNodeContractQuery()
+ var gas = new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setFunction("getMessage")
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var callQuery = new ContractCallQuery()
.setContractId(contractId)
@@ -365,10 +366,10 @@ void getCostInsufficientTxFeeContractCallFunction() throws Exception {
// Wait for mirror node to import data
Thread.sleep(2000);
- var gas = new MirrorNodeContractQuery()
+ var gas = new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setFunction("getMessage")
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var callQuery = new ContractCallQuery()
.setContractId(contractId)
diff --git a/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractExecuteIntegrationTest.java b/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractExecuteIntegrationTest.java
index 8ab6bc419..9f2b099bd 100644
--- a/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractExecuteIntegrationTest.java
+++ b/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractExecuteIntegrationTest.java
@@ -28,6 +28,7 @@
import com.hedera.hashgraph.sdk.ContractFunctionParameters;
import com.hedera.hashgraph.sdk.FileCreateTransaction;
import com.hedera.hashgraph.sdk.FileDeleteTransaction;
+import com.hedera.hashgraph.sdk.MirrorNodeContractEstimateGasQuery;
import com.hedera.hashgraph.sdk.MirrorNodeContractQuery;
import com.hedera.hashgraph.sdk.PrecheckStatusException;
import com.hedera.hashgraph.sdk.ReceiptStatusException;
@@ -64,10 +65,10 @@ void canExecuteContractMethods() throws Exception {
// Wait for mirror node to import data
Thread.sleep(2000);
- var gas = new MirrorNodeContractQuery()
+ var gas = new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setFunction("setMessage", new ContractFunctionParameters().addString("new message"))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var receipt = new ContractExecuteTransaction()
.setContractId(contractId)
.setGas(gas + 10000)
diff --git a/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractFunctionParametersIntegrationTest.java b/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractFunctionParametersIntegrationTest.java
index e51b82c4d..3ef94829b 100644
--- a/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractFunctionParametersIntegrationTest.java
+++ b/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/ContractFunctionParametersIntegrationTest.java
@@ -32,6 +32,7 @@
import com.hedera.hashgraph.sdk.FileDeleteTransaction;
import com.hedera.hashgraph.sdk.FileId;
import com.hedera.hashgraph.sdk.Hbar;
+import com.hedera.hashgraph.sdk.MirrorNodeContractEstimateGasQuery;
import com.hedera.hashgraph.sdk.MirrorNodeContractQuery;
import java.math.BigInteger;
import java.util.Arrays;
@@ -85,9 +86,9 @@ public void afterEach() throws InterruptedException {
@Test
@DisplayName("Can receive uint8 min value from contract call")
void canCallContractFunctionUint8Min() throws Exception {
- var gas = new MirrorNodeContractQuery().setContractId(contractId)
+ var gas = new MirrorNodeContractEstimateGasQuery().setContractId(contractId)
.setFunction("returnUint8", new ContractFunctionParameters().addUint8((byte) 0x0))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var response = new ContractCallQuery().setContractId(contractId).setGas(gas)
.setFunction("returnUint8", new ContractFunctionParameters().addUint8((byte) 0x0))
@@ -102,9 +103,9 @@ void canCallContractFunctionUint8Max() throws Exception {
int uint8Max = 255;
byte uint8MaxByte = (byte) uint8Max;
- var gas = new MirrorNodeContractQuery().setContractId(contractId)
+ var gas = new MirrorNodeContractEstimateGasQuery().setContractId(contractId)
.setFunction("returnUint8", new ContractFunctionParameters().addUint8(uint8MaxByte))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var response = new ContractCallQuery().setContractId(contractId).setGas(gas)
.setFunction("returnUint8", new ContractFunctionParameters().addUint8(uint8MaxByte))
@@ -123,9 +124,9 @@ void canCallContractFunctionUint8Array() throws Exception {
byte uint8MaxByte = (byte) uint8Max;
byte[] uint8Array = {uint8MinByte, uint8MaxByte};
- var gas = new MirrorNodeContractQuery().setContractId(contractId)
+ var gas = new MirrorNodeContractEstimateGasQuery().setContractId(contractId)
.setFunction("returnUint8Arr", new ContractFunctionParameters().addUint8Array(uint8Array))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var response = new ContractCallQuery().setContractId(contractId).setGas(gas)
.setFunction("returnUint8Arr", new ContractFunctionParameters().addUint8Array(uint8Array))
@@ -153,9 +154,9 @@ void canCallContractFunctionUint16Max() throws Exception {
var uint16Max = "65535";
int uint16MaxInt = Integer.parseUnsignedInt(uint16Max);
- var gas = new MirrorNodeContractQuery().setContractId(contractId)
+ var gas = new MirrorNodeContractEstimateGasQuery().setContractId(contractId)
.setFunction("returnUint16", new ContractFunctionParameters().addUint16(uint16MaxInt))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var response = new ContractCallQuery().setContractId(contractId).setGas(gas)
.setFunction("returnUint16", new ContractFunctionParameters().addUint16(uint16MaxInt))
@@ -174,9 +175,9 @@ void canCallContractFunctionUint16Array() throws Exception {
int uint16MaxInt = Integer.parseUnsignedInt(uint16Max);
int[] uint16Array = {uint16MinInt, uint16MaxInt};
- var gas = new MirrorNodeContractQuery().setContractId(contractId)
+ var gas = new MirrorNodeContractEstimateGasQuery().setContractId(contractId)
.setFunction("returnUint16Arr", new ContractFunctionParameters().addUint16Array(uint16Array))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var response = new ContractCallQuery().setContractId(contractId).setGas(gas)
.setFunction("returnUint16Arr", new ContractFunctionParameters().addUint16Array(uint16Array))
@@ -190,9 +191,9 @@ void canCallContractFunctionUint16Array() throws Exception {
@Test
@DisplayName("Can receive uint24 min value from contract call")
void canCallContractFunctionUint24Min() throws Exception {
- var gas = new MirrorNodeContractQuery().setContractId(contractId)
+ var gas = new MirrorNodeContractEstimateGasQuery().setContractId(contractId)
.setFunction("returnUint24", new ContractFunctionParameters().addUint24(0))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var response = new ContractCallQuery().setContractId(contractId).setGas(gas)
.setFunction("returnUint24", new ContractFunctionParameters().addUint24(0)).setQueryPayment(new Hbar(10))
@@ -207,9 +208,9 @@ void canCallContractFunctionUint24Max() throws Exception {
var uint24Max = "16777215";
int uint24MaxInt = Integer.parseUnsignedInt(uint24Max);
- var gas = new MirrorNodeContractQuery().setContractId(contractId)
+ var gas = new MirrorNodeContractEstimateGasQuery().setContractId(contractId)
.setFunction("returnUint24", new ContractFunctionParameters().addUint24(uint24MaxInt))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var response = new ContractCallQuery().setContractId(contractId).setGas(gas)
.setFunction("returnUint24", new ContractFunctionParameters().addUint24(uint24MaxInt))
@@ -228,9 +229,9 @@ void canCallContractFunctionUint24Array() throws Exception {
int uint24MaxInt = Integer.parseUnsignedInt(uint24Max);
int[] uint24Array = {uint24MinInt, uint24MaxInt};
- var gas = new MirrorNodeContractQuery().setContractId(contractId)
+ var gas = new MirrorNodeContractEstimateGasQuery().setContractId(contractId)
.setFunction("returnUint24Arr", new ContractFunctionParameters().addUint24Array(uint24Array))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var response = new ContractCallQuery().setContractId(contractId).setGas(gas)
.setFunction("returnUint24Arr", new ContractFunctionParameters().addUint24Array(uint24Array))
diff --git a/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/MirrorNodeContractQueryIntegrationTest.java b/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/MirrorNodeContractQueryIntegrationTest.java
index a161d802e..d542df7e4 100644
--- a/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/MirrorNodeContractQueryIntegrationTest.java
+++ b/sdk/src/testIntegration/java/com/hedera/hashgraph/sdk/test/integration/MirrorNodeContractQueryIntegrationTest.java
@@ -34,6 +34,8 @@
import com.hedera.hashgraph.sdk.FileCreateTransaction;
import com.hedera.hashgraph.sdk.FileDeleteTransaction;
import com.hedera.hashgraph.sdk.Hbar;
+import com.hedera.hashgraph.sdk.MirrorNodeContractCallQuery;
+import com.hedera.hashgraph.sdk.MirrorNodeContractEstimateGasQuery;
import com.hedera.hashgraph.sdk.MirrorNodeContractQuery;
import com.hedera.hashgraph.sdk.PrivateKey;
import java.util.Objects;
@@ -67,10 +69,10 @@ void canSimulateTransaction() throws Exception {
// Wait for mirror node to import data
Thread.sleep(2000);
- var gas = new MirrorNodeContractQuery()
+ var gas = new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setFunction("getOwner")
- .estimate(testEnv.client);
+ .execute(testEnv.client);
var result = new ContractCallQuery()
.setContractId(contractId)
@@ -79,17 +81,18 @@ void canSimulateTransaction() throws Exception {
.setQueryPayment(new Hbar(1))
.execute(testEnv.client);
- var simulationResult = new MirrorNodeContractQuery()
+ var simulationResult = new MirrorNodeContractCallQuery()
+ .setContractEvmAddress("asdf")
.setContractId(contractId)
.setFunction("getOwner")
- .call(testEnv.client);
+ .execute(testEnv.client);
assertThat(result.getAddress(0)).isEqualTo(simulationResult.substring(26));
- gas = new MirrorNodeContractQuery()
+ gas = new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setFunction("addOwner", new ContractFunctionParameters().addAddress(ADDRESS))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
new ContractExecuteTransaction()
.setContractId(contractId)
@@ -98,10 +101,10 @@ void canSimulateTransaction() throws Exception {
.execute(testEnv.client)
.getReceipt(testEnv.client);
- new MirrorNodeContractQuery()
+ new MirrorNodeContractCallQuery()
.setContractId(contractId)
.setFunction("addOwner", new ContractFunctionParameters().addAddress(ADDRESS))
- .call(testEnv.client);
+ .execute(testEnv.client);
new ContractDeleteTransaction()
.setTransferAccountId(testEnv.operatorId)
@@ -123,17 +126,17 @@ void failsWhenContractIsNotDeployed() throws Exception {
var contractId = new ContractId(1231456);
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> {
- new MirrorNodeContractQuery()
+ new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setFunction("getOwner")
- .estimate(testEnv.client);
+ .execute(testEnv.client);
}).withMessageContaining("Received non-200 response from Mirror Node");
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> {
- new MirrorNodeContractQuery()
+ new MirrorNodeContractCallQuery()
.setContractId(contractId)
.setFunction("getOwner")
- .call(testEnv.client);
+ .execute(testEnv.client);
}).withMessageContaining("Received non-200 response from Mirror Node");
}
}
@@ -161,21 +164,20 @@ void failsWhenGasLimitIsLow() throws Exception {
Thread.sleep(2000);
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> {
- new MirrorNodeContractQuery()
+ new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setGasLimit(100)
.setFunction("addOwnerAndTransfer", new ContractFunctionParameters().addAddress(ADDRESS))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
}).withMessageContaining("Received non-200 response from Mirror Node");
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> {
- new MirrorNodeContractQuery()
+ new MirrorNodeContractCallQuery()
.setContractId(contractId)
.setGasLimit(100)
.setFunction("addOwnerAndTransfer", new ContractFunctionParameters().addAddress(ADDRESS))
- .call(testEnv.client);
+ .execute(testEnv.client);
}).withMessageContaining("Received non-200 response from Mirror Node");
-
}
}
@@ -202,17 +204,17 @@ void failsWhenSenderIsNotSet() throws Exception {
Thread.sleep(2000);
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> {
- new MirrorNodeContractQuery()
+ new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setFunction("addOwnerAndTransfer", new ContractFunctionParameters().addAddress(ADDRESS))
- .estimate(testEnv.client);
+ .execute(testEnv.client);
}).withMessageContaining("Received non-200 response from Mirror Node");
assertThatExceptionOfType(ExecutionException.class).isThrownBy(() -> {
- new MirrorNodeContractQuery()
+ new MirrorNodeContractCallQuery()
.setContractId(contractId)
.setFunction("addOwnerAndTransfer", new ContractFunctionParameters().addAddress(ADDRESS))
- .call(testEnv.client);
+ .execute(testEnv.client);
}).withMessageContaining("Received non-200 response from Mirror Node");
}
@@ -249,19 +251,19 @@ void canSimulateWithSenderSet() throws Exception {
var receiverEvmAddress = getEvmAddressFromMirrorNodeAsync(testEnv.client, receiverAccountId.num).get()
.toString();
- var owner = new MirrorNodeContractQuery()
+ var owner = new MirrorNodeContractCallQuery()
.setContractId(contractId)
.setFunction("getOwner")
- .call(testEnv.client)
+ .execute(testEnv.client)
.substring(26);
- var gas = new MirrorNodeContractQuery()
+ var gas = new MirrorNodeContractEstimateGasQuery()
.setContractId(contractId)
.setGasLimit(1_000_000)
.setFunction("addOwnerAndTransfer", new ContractFunctionParameters().addAddress(receiverEvmAddress))
.setSenderEvmAddress(owner)
.setValue(123)
- .estimate(testEnv.client);
+ .execute(testEnv.client);
new ContractExecuteTransaction()
.setContractId(contractId)
@@ -271,13 +273,13 @@ void canSimulateWithSenderSet() throws Exception {
.execute(testEnv.client)
.getReceipt(testEnv.client);
- new MirrorNodeContractQuery()
+ new MirrorNodeContractCallQuery()
.setContractId(contractId)
.setGasLimit(1_000_000)
.setFunction("addOwnerAndTransfer", new ContractFunctionParameters().addAddress(receiverEvmAddress))
.setSenderEvmAddress(owner)
.setValue(123)
- .call(testEnv.client);
+ .execute(testEnv.client);
}
}
}