Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: update java version of examples #1

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions java-hello-world/00-create-fund-account/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,8 @@ repositories {
}

dependencies {
implementation 'com.hedera.hashgraph:sdk:2.32.0'
implementation 'org.bouncycastle:bcprov-jdk15on:1.68'
implementation 'com.hedera.hashgraph:sdk:2.33.0'
implementation 'io.github.cdimascio:java-dotenv:5.2.2'
implementation 'org.web3j:core:4.8.7'
implementation 'org.json:json:20211205'
testImplementation 'junit:junit:4.13.1'
}

tasks.named('test') {
useJUnitPlatform()
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'org.slf4j:slf4j-nop:2.0.13'
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
package createfundaccount;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.hedera.hashgraph.sdk.Hbar;
import com.hedera.hashgraph.sdk.Mnemonic;
import com.hedera.hashgraph.sdk.PrivateKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.json.JSONArray;
import org.json.JSONObject;
import org.web3j.crypto.Bip32ECKeyPair;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.MnemonicUtils;
import com.hedera.hashgraph.sdk.PublicKey;
import io.github.cdimascio.dotenv.Dotenv;

import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.Scanner;
import java.security.Security;
import java.text.NumberFormat;
import java.util.Locale;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ScriptCreateFundAccount {
public static void main(String[] args) throws Exception {

// Generate seed phrase
// Mnemonic seedPhraseMnemonic = Mnemonic.generate12();
// System.out.println("Seed phrase: " + seedPhraseMnemonic.toString());

// Load environment variables from .env file
Dotenv dotenv = Dotenv.load();

Expand All @@ -27,76 +28,36 @@ public static void main(String[] args) throws Exception {
throw new IllegalArgumentException("Please set required keys in .env file.");
}

// Create an ECSDA secp256k1 private key based on a BIP-39 seed phrase,
// plus the default BIP-32/BIP-44 HD Wallet derivation path used by Metamask.
Security.addProvider(new BouncyCastleProvider());

// BIP-39 Generate seed from seed phrase
byte[] seed = MnemonicUtils.generateSeed(seedPhrase, null);

// BIP-32 Derive master key
Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed);
final int[] path = {
44 | Bip32ECKeyPair.HARDENED_BIT,
60 | Bip32ECKeyPair.HARDENED_BIT,
0 | Bip32ECKeyPair.HARDENED_BIT,
0,
0
};

// BIP-44 Derive private key of single account from BIP-32 master key + BIP-44 HD path
// Using m/44'/60'/0'/0/0 for compatibility with Metamask hardcoded default
Bip32ECKeyPair derivedKeypair = Bip32ECKeyPair.deriveKeyPair(masterKeypair, path);
Credentials credentials = Credentials.create(derivedKeypair);
String privateKeyString = credentials.getEcKeyPair().getPrivateKey().toString(16);
final int privateKeyStringMissingCharCount = 64 - privateKeyString.length();
if (privateKeyStringMissingCharCount > 0) {
privateKeyString = ("0").repeat(privateKeyStringMissingCharCount) + privateKeyString;
}
PrivateKey privateKey = PrivateKey.fromStringECDSA(privateKeyString);
// Derive private key
PrivateKey privateKey = Mnemonic.fromString(seedPhrase).toStandardECDSAsecp256k1PrivateKey("", 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not equivalent to the code that it replaces, as it does not use the custom derivation path m/44'/60'/0'/0/0

Suggested change
PrivateKey privateKey = Mnemonic.fromString(seedPhrase).toStandardECDSAsecp256k1PrivateKey("", 0);
PrivateKey privateKey = Mnemonic.fromString(seedPhrase).toStandardECDSAsecp256k1PrivateKeyCustomDerivationPath("", "m/44'/60'/0'/0/" + accountIndex);

(where accountIndex can be hardcoded as 0 if that's the only one we need)

PublicKey publicKey = privateKey.getPublicKey();

// At this point the account technically does not yet exist,
// and will need to be created when it receives its first transaction (later).
// Convert the private key to string format as well as an EVM address.
String privateKeyHex = "0x" + privateKey.toStringRaw();
String evmAddress = credentials.getAddress();

// Derive EVM address
String evmAddress = "0x" + publicKey.toEvmAddress().toString();
String accountExplorerUrl = "https://hashscan.io/testnet/account/" + evmAddress;
String accountBalanceFetchApiUrl = "https://testnet.mirrornode.hedera.com/api/v1/balances?account.id=" + evmAddress + "&limit=1&order=asc";

// Query account ID and balance using mirror node API
Long accountBalanceTinybar = null;
String accountBalanceHbar = null;
String accountId = null;
try {
URL url = URI.create(accountBalanceFetchApiUrl).toURL();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.connect();
int responseCode = conn.getResponseCode();
if (responseCode < 200 || responseCode >= 400) {
throw new RuntimeException("HTTP response code: " + responseCode);
}
String inline = "";
Scanner scanner = new Scanner(url.openStream());
while (scanner.hasNext()) {
inline += scanner.nextLine();
}
scanner.close();
final HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(accountBalanceFetchApiUrl))
.build();

JSONObject jsonResponse = new JSONObject(inline);
JSONArray balancesArray = jsonResponse.getJSONArray("balances");
JSONObject balanceObject = balancesArray.getJSONObject(0);
accountId = balanceObject.getString("account");
accountBalanceTinybar = balanceObject.getLong("balance");
} catch (Exception e) {
// do nothing
}
final HttpClient httpClient = HttpClient.newHttpClient();

if (accountBalanceTinybar != null) {
accountBalanceHbar = NumberFormat
.getNumberInstance(Locale.UK)
.format(accountBalanceTinybar * Math.pow(10, -8));
}
final var mirrorNodeResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()).body();

JsonObject jsonResponse = JsonParser.parseString(mirrorNodeResponse).getAsJsonObject();
JsonArray balancesArray = jsonResponse.getAsJsonArray("balances");
JsonObject balanceObject = balancesArray.get(0).getAsJsonObject();
String accountId = balanceObject.get("account").getAsString();
long accountBalanceTinybar = balanceObject.get("balance").getAsLong();

Hbar accountBalanceHbar = Hbar.fromTinybars(accountBalanceTinybar);

// Output results
System.out.println("privateKeyHex: " + privateKeyHex);
Expand Down
13 changes: 4 additions & 9 deletions java-hello-world/01-hfs-files/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,9 @@ repositories {
}

dependencies {
implementation 'com.hedera.hashgraph:sdk:2.32.0'
implementation 'io.github.cdimascio:dotenv-java:2.3.2'
implementation 'com.hedera.hashgraph:sdk:2.33.0'
implementation 'io.grpc:grpc-netty-shaded:1.57.2'
implementation 'org.slf4j:slf4j-nop:2.0.9'
implementation 'com.google.code.gson:gson:2.8.8'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
useJUnitPlatform()
implementation 'io.github.cdimascio:java-dotenv:5.2.2'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'org.slf4j:slf4j-nop:2.0.13'
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package hfsfiles;

import com.hedera.hashgraph.sdk.*;
import com.hedera.hashgraph.sdk.AccountId;
import com.hedera.hashgraph.sdk.Client;
import com.hedera.hashgraph.sdk.FileContentsQuery;
import com.hedera.hashgraph.sdk.FileCreateTransaction;
import com.hedera.hashgraph.sdk.FileId;
import com.hedera.hashgraph.sdk.PrivateKey;
import com.hedera.hashgraph.sdk.TransactionId;
import com.hedera.hashgraph.sdk.TransactionReceipt;
import com.hedera.hashgraph.sdk.TransactionResponse;
import io.github.cdimascio.dotenv.Dotenv;

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Objects;

public class ScriptHfsFiles {
public static void main(String[] args) throws Exception {
Expand All @@ -26,9 +33,9 @@ public static void main(String[] args) throws Exception {
Client client = Client.forTestnet().setOperator(accountId, accountKey);

// Read file from disk
String localFileContents = new String(Files.readAllBytes(Paths.get("my-file.txt")), StandardCharsets.UTF_8);
String localFileContents = Files.readString(Paths.get("my-file.txt"));

// Write file onto Hedera Testnet, using HFS FileCreateTransaction
// Write file onto Hedera Testnet, using HFS FileCreateTransaction
FileCreateTransaction fileCreateTx = new FileCreateTransaction()
// NOTE: File create transaction
// Step (1) in the accompanying tutorial
Expand All @@ -39,7 +46,7 @@ public static void main(String[] args) throws Exception {
TransactionResponse fileCreateTxSubmitted = fileCreateTxSigned.execute(client);
TransactionId fileCreateTxId = fileCreateTxSubmitted.transactionId;
TransactionReceipt fileCreateTxReceipt = fileCreateTxSubmitted.getReceipt(client);
FileId fileId = fileCreateTxReceipt.fileId;
FileId fileId = Objects.requireNonNull(fileCreateTxReceipt.fileId);

// Read file from Hedera Testnet, using HFS FileContentsQuery
FileContentsQuery fileReadQuery = new FileContentsQuery()
Expand Down
13 changes: 4 additions & 9 deletions java-hello-world/02-hscs-smart-contract-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,9 @@ repositories {
}

dependencies {
implementation 'com.hedera.hashgraph:sdk:2.32.0'
implementation 'io.github.cdimascio:dotenv-java:2.3.2'
implementation 'com.hedera.hashgraph:sdk:2.33.0'
implementation 'io.grpc:grpc-netty-shaded:1.57.2'
implementation 'org.slf4j:slf4j-nop:2.0.9'
implementation 'com.google.code.gson:gson:2.8.8'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
useJUnitPlatform()
implementation 'io.github.cdimascio:java-dotenv:5.2.2'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'org.slf4j:slf4j-nop:2.0.13'
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package hscssmartcontract;

import com.hedera.hashgraph.sdk.*;
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.ContractExecuteTransaction;
import com.hedera.hashgraph.sdk.ContractFunctionParameters;
import com.hedera.hashgraph.sdk.ContractFunctionResult;
import com.hedera.hashgraph.sdk.ContractId;
import com.hedera.hashgraph.sdk.FileCreateTransaction;
import com.hedera.hashgraph.sdk.FileId;
import com.hedera.hashgraph.sdk.PrivateKey;
import com.hedera.hashgraph.sdk.TransactionId;
import com.hedera.hashgraph.sdk.TransactionReceipt;
import com.hedera.hashgraph.sdk.TransactionResponse;
import io.github.cdimascio.dotenv.Dotenv;

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.TimeoutException;
import java.util.Objects;

public class ScriptHscsSmartContract {
public static void main(String[] args) throws Exception {
Expand Down Expand Up @@ -37,15 +48,15 @@ public static void main(String[] args) throws Exception {
.setContents(evmBytecode)
.execute(client);
TransactionReceipt fileReceipt = fileCreateTransaction.getReceipt(client);
FileId bytecodeFileId = fileReceipt.fileId;
FileId bytecodeFileId = Objects.requireNonNull(fileReceipt.fileId);

// Deploy smart contract
TransactionResponse contractCreateTransaction = new ContractCreateTransaction()
.setBytecodeFileId(bytecodeFileId)
.setGas(100000)
.setGas(100_000)
.execute(client);
TransactionReceipt contractReceipt = contractCreateTransaction.getReceipt(client);
ContractId myContractId = contractReceipt.contractId;
ContractId myContractId = Objects.requireNonNull(contractReceipt.contractId);
String myContractExplorerUrl = "https://hashscan.io/testnet/address/" + myContractId;

// Write data to smart contract
Expand All @@ -54,7 +65,7 @@ public static void main(String[] args) throws Exception {
// .setFunction("introduce", new ContractFunctionParameters().addString(/* ... */))
TransactionResponse contractExecuteTransaction = new ContractExecuteTransaction()
.setContractId(myContractId)
.setGas(100000)
.setGas(100_000)
.setFunction("introduce", new ContractFunctionParameters().addString("bguiz"))
.execute(client);
TransactionReceipt executeReceipt = contractExecuteTransaction.getReceipt(client);
Expand All @@ -69,7 +80,7 @@ public static void main(String[] args) throws Exception {
// .setFunction(/* ... */);
ContractCallQuery contractCallQuery = new ContractCallQuery()
.setContractId(myContractId)
.setGas(100000)
.setGas(100_000)
.setFunction("greet", new ContractFunctionParameters());
ContractFunctionResult greetResult = contractCallQuery.execute(client);
String myContractQueryResult = greetResult.getString(0);
Expand Down
14 changes: 4 additions & 10 deletions java-hello-world/04-hts-ft/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,9 @@ repositories {
}

dependencies {
implementation 'com.hedera.hashgraph:sdk:2.32.0'
implementation 'io.github.cdimascio:dotenv-java:2.3.2'
implementation 'com.hedera.hashgraph:sdk:2.33.0'
implementation 'io.grpc:grpc-netty-shaded:1.57.2'
implementation 'org.slf4j:slf4j-nop:2.0.9'
implementation 'com.google.code.gson:gson:2.8.8'
implementation 'org.json:json:20211205'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
useJUnitPlatform()
implementation 'io.github.cdimascio:java-dotenv:5.2.2'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'org.slf4j:slf4j-nop:2.0.13'
}
Loading