import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.hedera.hashgraph.sdk.*;
import io.github.cdimascio.dotenv.Dotenv;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;
public static void main(String[] args) throws TimeoutException, PrecheckStatusException, ReceiptStatusException, InterruptedException, IOException {
AccountId accountIdTest = AccountId.fromString(Dotenv.load().get("PREVIEWNET_ACCOUNT_ID"));
PrivateKey privateKeyTest = PrivateKey.fromString(Dotenv.load().get("PREVIEWNET_PRIVATE_KEY"));
Client client = Client.forPreviewnet();
client.setOperator(accountIdTest, privateKeyTest);
//Import the HTS.json file from the resources folder
ClassLoader cl = HTS.class.getClassLoader();
InputStream jsonStream = cl.getResourceAsStream("HTS.json");
jsonObject = gson.fromJson(new InputStreamReader(jsonStream, StandardCharsets.UTF_8), JsonObject.class);
//Store the "object" field from the HTS.json file as hex-encoded bytecode
String object = jsonObject.getAsJsonObject("data").getAsJsonObject("bytecode").get("object").getAsString();
byte[] bytecode = object.getBytes(StandardCharsets.UTF_8);
PrivateKey treasuryKey = PrivateKey.generateED25519();
//Create a treasury account
AccountCreateTransaction treasuryAccount = new AccountCreateTransaction()
.setInitialBalance(new Hbar(100))
.setAccountMemo("treasury account");
//Submit the account create transaction
TransactionResponse submitAccountCreateTx = treasuryAccount.execute(client);
//Get the receipt of the transaction
TransactionReceipt newAccountReceipt = submitAccountCreateTx.getReceipt(client);
//Get the treasury account ID
AccountId treasuryAccountId = newAccountReceipt.accountId;
System.out.println("The new account ID is " +treasuryAccountId);
//Create a token to interact with
TokenCreateTransaction createToken = new TokenCreateTransaction()
.setTokenName("HSCS demo")
.setTokenType(TokenType.FUNGIBLE_COMMON)
.setTreasuryAccountId(treasuryAccountId)
//Submit the token create transaction
TransactionResponse submitTokenTx = createToken.freezeWith(client).sign(treasuryKey).execute(client);
TokenId tokenId = submitTokenTx.getReceipt(client).tokenId;
System.out.println("The new token ID is " +tokenId);
//Create a file on Hedera and store the hex-encoded bytecode
FileCreateTransaction fileCreateTx = new FileCreateTransaction()
//Submit the file to the Hedera test network
TransactionResponse submitTx = fileCreateTx.execute(client);
//Get the receipt of the file create transaction
TransactionReceipt fileReceipt = submitTx.getReceipt(client);
FileId newFileId = fileReceipt.fileId;
System.out.println("The smart contract byte code file ID is " + newFileId);
ContractCreateTransaction contractTx = new ContractCreateTransaction()
//The contract bytecode file
.setBytecodeFileId(newFileId)
//The max gas to reserve for this transaction
//Submit the transaction to the Hedera test network
TransactionResponse contractResponse = contractTx.execute(client);
//Get the receipt of the file create transaction
TransactionReceipt contractReceipt = contractResponse.getReceipt(client);
//Get the smart contract ID
ContractId newContractId = contractReceipt.contractId;
//Log the smart contract ID
System.out.println("The smart contract ID is " + newContractId);
//Associate the token to an account using the HTS contract
ContractExecuteTransaction associateToken = new ContractExecuteTransaction()
.setContractId(newContractId)
//The gas for the transaction
//The contract function to call and parameters to pass
.setFunction("tokenAssociate", new ContractFunctionParameters()
//The account ID to associate the token to
.addAddress(accountIdTest.toSolidityAddress())
//The token ID to associate to the account
.addAddress(tokenId.toSolidityAddress()));
//Sign with the account key to associate and submit to the Hedera network
TransactionResponse associateTokenResponse = associateToken.freezeWith(client).sign(privateKeyTest).execute(client);
System.out.println("The transaction status: " +associateTokenResponse.getReceipt(client).status);
//Get the child token associate transaction record
TransactionRecord childRecords = new TransactionRecordQuery()
//Set the bool flag equal to true
.setIncludeChildren(true)
//The transaction ID of th parent contract execute transaction
.setTransactionId(associateTokenResponse.transactionId)
System.out.println("The transaction record for the associate transaction" +childRecords.children.get(0));
//The balance of the account
AccountBalance accountBalance3 = new AccountBalanceQuery()
.setAccountId(accountIdTest)
System.out.println("The " + tokenId + " should now be associated to my account: " + accountBalance3.tokens);
//Transfer the new token to the account
//Contract function params need to be in the order of the paramters provided in the tokenTransfer contract function
ContractExecuteTransaction tokenTransfer = new ContractExecuteTransaction()
.setContractId(newContractId)
.setFunction("tokenTransfer", new ContractFunctionParameters()
.addAddress(tokenId.toSolidityAddress())
//The account to transfer the tokens from
.addAddress(treasuryAccountId.toSolidityAddress())
//The account to transfer the tokens to
.addAddress(accountIdTest.toSolidityAddress())
//The number of tokens to transfer
//Sign the token transfer transaction with the treasury account to authorize the transfer and submit
ContractExecuteTransaction signTokenTransfer = tokenTransfer.freezeWith(client).sign(treasuryKey);
//Submit transfer transaction
TransactionResponse submitTransfer = signTokenTransfer.execute(client);
Status txStatus = submitTransfer.getReceipt(client).status;
//Get the transaction status
System.out.println("The transfer transaction status " +txStatus);
//Verify your account received the 100 tokens
AccountBalance newAccountBalance = new AccountBalanceQuery()
.setAccountId(accountIdTest)
System.out.println("My new account balance is " +newAccountBalance.tokens);