-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: create separate classes for estimate and call
Signed-off-by: Ivan Ivanov <[email protected]>
- Loading branch information
Showing
10 changed files
with
416 additions
and
104 deletions.
There are no files selected for viewing
176 changes: 176 additions & 0 deletions
176
...les/src/main/java/com/hedera/hashgraph/sdk/examples/MirrorNodeContractQueriesExample.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
* <p> | ||
* 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); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractCallQuery.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<MirrorNodeContractCallQuery> { | ||
/** | ||
* 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(); | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
sdk/src/main/java/com/hedera/hashgraph/sdk/MirrorNodeContractEstimateGasQuery.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<MirrorNodeContractEstimateGasQuery> { | ||
|
||
/** | ||
* 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(); | ||
} | ||
} |
Oops, something went wrong.