diff --git a/SUMMARY.md b/SUMMARY.md
index b95672ad4fa1..c13124731e3d 100644
--- a/SUMMARY.md
+++ b/SUMMARY.md
@@ -17,7 +17,7 @@
* [Send and Receive HBAR Using Solidity Smart Contracts](tutorials/smart-contracts/send-and-receive-hbar-using-solidity-smart-contracts.md)
* [Create an HBAR Faucet App Using React and MetaMask](tutorials/smart-contracts/create-an-hbar-faucet-app-using-react-and-metamask.md)
* [Deploy By Leveraging Ethereum Developer Tools On Hedera](tutorials/smart-contracts/deploy-by-leveraging-ethereum-developer-tools-on-hedera.md)
- * [Deploy a Subgraph Using The Graph and JSON-RPC](tutorials/smart-contracts/deploy-a-subgraph-using-the-graph-and-json-rpc.md)
+ * [Deploy a Subgraph Using The Graph and Hedera JSON-RPC Relay](tutorials/smart-contracts/deploy-a-subgraph-using-the-graph-and-json-rpc.md)
* [How to Set Up Foundry to Test Smart Contracts on Hedera](tutorials/smart-contracts/how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md)
* [Deploy Smart Contracts on Hedera Using Truffle](tutorials/smart-contracts/deploy-smart-contracts-on-hedera-using-truffle.md)
* [Hedera Smart Contracts Workshop](tutorials/smart-contracts/hscs-workshop/README.md)
diff --git a/getting-started/try-examples/schedule-your-first-transaction.md b/getting-started/try-examples/schedule-your-first-transaction.md
index aed59224e269..94a12b8ca5d5 100644
--- a/getting-started/try-examples/schedule-your-first-transaction.md
+++ b/getting-started/try-examples/schedule-your-first-transaction.md
@@ -4,11 +4,26 @@
In this tutorial, you'll learn how to create and sign a scheduled transaction. Scheduled Transactions enable multiple parties to easily, inexpensively, and natively schedule and execute any type of Hedera transaction together. Once a transaction is scheduled, additional signatures can be submitted via a ScheduleSign transaction. After the last signature is received within the allotted timeframe, the scheduled transaction will execute.
+***
+
## Prerequisites
We recommend you complete the following introduction to get a basic understanding of Hedera transactions. This example does not build upon the previous examples.
-
+* Get a [Hedera testnet account](../introduction.md).
+* Set up your environment [here](../environment-set-up.md).
+
+***
+
+## Table of Contents
+
+1. [Create Transaction](schedule-your-first-transaction.md#1.-create-a-transaction-to-schedule)
+2. [Schedule Transaction](schedule-your-first-transaction.md#2.-schedule-the-transfer-transaction)
+3. [Submit Signatures](schedule-your-first-transaction.md#3.-submit-signatures)
+4. [Verify Schedule was Triggered](schedule-your-first-transaction.md#4.-verify-the-schedule-was-triggered)
+5. [Verify Scheduled Transaction Executed](schedule-your-first-transaction.md#5.-verify-the-scheduled-transaction-executed)
+
+***
## 1. Create a transaction to schedule
@@ -44,6 +59,8 @@ transaction := hedera.NewTransferTransaction().
{% endtab %}
{% endtabs %}
+***
+
## 2. Schedule the transfer transaction
Next, you will schedule the transfer transaction by submitting a ScheduleCreate transaction to the network. Once the transfer transaction is scheduled, you can obtain the schedule ID from the receipt of the ScheduleCreate transaction. The schedule ID identifies the schedule that scheduled the transfer transaction. The schedule ID can be shared with the three signatories. The schedule is immutable unless the admin key is specified during creation.
@@ -129,7 +146,11 @@ fmt.Printf("The scheduled transaction ID is %v\n", scheduleTxId)
{% endtab %}
{% endtabs %}
-## 3. Submit one of the required signatures for the transfer transaction
+***
+
+## 3. Submit Signatures
+
+### Submit one of the required signatures for the transfer transaction
The signatures are submitted to the network via a [ScheduleSign](../../sdks-and-apis/sdks/schedule-transaction/sign-a-schedule-transaction.md) transaction. The [ScheduleSign ](../../sdks-and-apis/sdks/schedule-transaction/sign-a-schedule-transaction.md)transaction requires the schedule ID of the schedule and the signature of one or more of the required keys. The scheduled transaction has 30 minutes from the time it is scheduled to receive all of its signatures; if the signature requirements are not met, the scheduled transaction will expire.
@@ -215,7 +236,7 @@ fmt.Print(query1)
{% endtab %}
{% endtabs %}
-## 4. Submit the second signature
+### Submit the second signature
Next, you will submit the second signature and verify the transaction was successful by requesting the receipt. For example purposes, you have access to all three signing keys. But the idea here is that each signer can independently submit their signature to the network.
@@ -280,7 +301,9 @@ fmt.Printf("The transaction status is %v\n", status2)
{% endtab %}
{% endtabs %}
-## 5. Verify the schedule was triggered
+***
+
+## 4. Verify the schedule was triggered
The schedule is triggered after it meets its minimum signing requirements. As soon as the last required signature is submitted, the schedule executes the scheduled transaction. To verify the schedule was triggered, query for the schedule info. When the schedule info is returned, you should notice both public keys that signed in the `signatories` field and the timestamp recorded for when the schedule transaction was executed in the `executedAt` field.
@@ -319,7 +342,9 @@ fmt.Print(query2)
{% endtab %}
{% endtabs %}
-## 6. Verify the scheduled transaction executed
+***
+
+## 5. Verify the scheduled transaction executed
When the scheduled transaction (transfer transaction) executes a record is produced that contains the transaction details. The scheduled transaction record can be requested immediately after the transaction has executed and includes the corresponding schedule ID. If you do not know when the scheduled transaction will execute, you can always query a [mirror node](../../core-concepts/mirror-nodes/hedera-mirror-node.md) using the scheduled transaction ID without the `?scheduled` flag to get a copy of the transaction record.
diff --git a/tutorials/consensus/query-messages-with-mirror-node.md b/tutorials/consensus/query-messages-with-mirror-node.md
index b5961a5e4ac2..8c0b6dc02da0 100644
--- a/tutorials/consensus/query-messages-with-mirror-node.md
+++ b/tutorials/consensus/query-messages-with-mirror-node.md
@@ -6,10 +6,23 @@ In the first tutorial, "Submit Your First Message," you have learned how to subm
In this tutorial, you will learn how to query the Hedera Mirror Node API to retrieve and filter messages.
+***
+
## Prerequisites
We recommend that you complete the "Submit Your First Message" tutorial [here](submit-your-first-message.md) to get a basic understanding of the Hedera Consensus Service. **This example does not build upon the previous examples.**
+***
+
+## Table of Contents
+
+1. [Create Topic and Submit Messages](query-messages-with-mirror-node.md#1.-create-a-topic-and-submit-three-messages)
+2. [Query Hedera Mirror Node API](query-messages-with-mirror-node.md#2.-query-the-hedera-mirror-node-api)
+3. [Retrieve Message](query-messages-with-mirror-node.md#3.-retrieve-a-specific-message-by-sequence-number)
+4. [Advanced Filtering](query-messages-with-mirror-node.md#4.-advanced-filtering-methods-for-hcs-messages)
+
+***
+
## 1. Create a topic and submit three messages
For this tutorial, create a new topic and submit three messages to this topic on testnet. You will use the retrieved topic ID to query for messages via the Hedera Mirror Node API.
@@ -147,6 +160,8 @@ Your topic ID is: 0.0.<4603900>
Next, let's query the mirror node to retrieve data.
+***
+
## 2. Query the Hedera Mirror Node API
Now all three messages have been submitted to your topic ID on testnet, let's query the mirror node. Let's use the testnet endpoint for the Hedera Mirror Node API to query for all messages for your topic ID. Make sure to replace the topic ID with the topic ID you've written down and execute the request in your browser or tool of choice.
@@ -201,6 +216,8 @@ The result should look similar to the API result below, with three messages bein
+***
+
## 3. Retrieve a specific message by sequence number
In this section, you'll learn how to query messages by a sequence number. Each message you submit to a topic receives a sequence number starting from 1.
@@ -244,6 +261,8 @@ Only message two is returned by the Hedera Mirror Node.
+***
+
## 4. Advanced filtering methods for HCS messages
This section explores advanced filtering methods using query modifiers. The [OpenAPI specification](https://raw.githubusercontent.com/hashgraph/hedera-mirror-node/main/hedera-mirror-rest/api/v1/openapi.yml) for the Hedera Mirror Node REST API shows all details for query parameters (e.g. `timestampQueryParam`).
@@ -301,4 +320,8 @@ Only message two is returned by the Hedera Mirror Node.
+{% hint style="info" %}
+Have a question? [Ask it on StackOverflow](https://stackoverflow.com/questions/tagged/hedera-hashgraph)
+{% endhint %}
+
diff --git a/tutorials/consensus/submit-message-to-private-topic.md b/tutorials/consensus/submit-message-to-private-topic.md
index 46cb30220536..e2695e6fbfc0 100644
--- a/tutorials/consensus/submit-message-to-private-topic.md
+++ b/tutorials/consensus/submit-message-to-private-topic.md
@@ -6,12 +6,25 @@ In the previous tutorial, "Submit Your First Message," you have learned how to s
When setting a _Submit Key,_ your topic becomes a **private topic** because each message needs to be signed by the Submit Key. Therefore, you can control who can submit messages to your topic. Of course, the data is still public, as is all data on a public ledger, but we say the topic is private because the topic is restricted by who can submit messages to it.
+***
+
## Prerequisites
We recommend you complete the "Submit Your First Message" tutorial [here](submit-your-first-message.md) to get a basic understanding of the Hedera Consensus Service. This example does not build upon the previous examples.
✅ _You can find a full_ [_code check_](submit-message-to-private-topic.md#code-check) _for this tutorial at the bottom of this page._
+***
+
+## Table of Contents
+
+1. [Create Private Topic](submit-message-to-private-topic.md#1.-create-a-private-topic)
+2. [Subscribe to Topic](submit-message-to-private-topic.md#2.-subscribe-to-a-topic)
+3. [Submit Message](submit-message-to-private-topic.md#3.-submit-a-message)
+4. [Code Check](submit-message-to-private-topic.md#code-check)
+
+***
+
## 1. Create a private topic
To create a private topic, you will use [_**`setSubmitKey()`**_](https://docs.hedera.com/hedera/sdks-and-apis/sdks/consensus-service/create-a-topic#methods) to set a Submit Key. This key needs to sign all messages someone sends to the topic. A message will be rejected if you don't sign the message or sign with an incorrect key. The cost of creating a private topic is the same as a public topic: [**$0.01**](https://docs.hedera.com/hedera/networks/mainnet/fees#consensus-service).
@@ -83,6 +96,8 @@ fmt.Printf("topicID: %v\n", topicID)
{% endtab %}
{% endtabs %}
+***
+
## 2. Subscribe to a topic
The code used to subscribe to a public or private topic doesn't change. Anyone can listen to the messages you send to your private topic. You need to provide the [_**`TopicMessageQuery()`**_](../../sdks-and-apis/sdks/consensus-service/get-topic-message.md) with your topic ID to subscribe to it.
@@ -126,6 +141,8 @@ _, err = hedera.NewTopicMessageQuery().
{% endtab %}
{% endtabs %}
+***
+
## 3. Submit a message
Now you are ready to submit a message to your private topic. To do this, you will use [_**`TopicMessageSubmitTransaction()`**_](../../sdks-and-apis/sdks/consensus-service/submit-a-message.md). However, you need to sign this transaction with your Submit Key. The cost for sending a message to a private topic is the same as a public topic: [**$0.0001**](https://docs.hedera.com/hedera/networks/mainnet/fees#consensus-service).
@@ -208,6 +225,8 @@ time.Sleep(30000)
To conclude: The total cost to create a topic and send a message to it is **$0.0101.**
+***
+
## Code Check ✅
@@ -451,4 +470,8 @@ func main() {
+{% hint style="info" %}
+Have a question? [Ask it on StackOverflow](https://stackoverflow.com/questions/tagged/hedera-hashgraph)
+{% endhint %}
+
diff --git a/tutorials/consensus/submit-your-first-message.md b/tutorials/consensus/submit-your-first-message.md
index 621d0f916a1c..7d8ac0f5675b 100644
--- a/tutorials/consensus/submit-your-first-message.md
+++ b/tutorials/consensus/submit-your-first-message.md
@@ -6,7 +6,7 @@ With the Hedera Consensus Service (HCS), you can develop applications like stock
In short, HCS offers the validity of the order of events and transparency into the history of events without requiring a persistent history of transactions. To achieve this, [Mirror nodes](../../core-concepts/mirror-nodes/) store all transaction data so you can retrieve it to audit events.
-
+***
## Prerequisites
@@ -17,6 +17,17 @@ We recommend you complete the following introduction to get a basic understandin
✅ _You can find a full_ [_code check_](submit-your-first-message.md#code-check) _for this tutorial at the bottom of this page._
+***
+
+## Table of Contents
+
+1. Create Topic
+2. Subscribe to Topic
+3. Submit Message
+4. Code Check
+
+***
+
## 1. Create your first topic
To create your first topic, you will use the _**`TopicCreateTransaction()`**_, set its properties, and submit it to the Hedera network. In this tutorial, you will create a **public topic** by not setting any properties on the topic. This means that anyone can send messages to your topic.
@@ -89,6 +100,8 @@ fmt.Printf("topicID: %v\n", topicID)
{% endtab %}
{% endtabs %}
+***
+
## 2. Subscribe to a topic
After you create the topic, you will want to subscribe to the topic via a Hedera mirror node. Subscribing to a topic via a Hedera mirror node allows you to receive the stream of messages that are being submitted to it.
@@ -137,6 +150,8 @@ _, err = hedera.NewTopicMessageQuery().
{% endtab %}
{% endtabs %}
+***
+
## 3. Submit a message
Now you are ready to submit your first message to the topic. To do this, you will use [_**`TopicMessageSubmitTransaction()`**_](../../sdks-and-apis/sdks/consensus-service/submit-a-message.md). For this transaction, you will provide the topic ID and the message to submit to it. Each message you send to a topic costs you [**$0.0001**](https://docs.hedera.com/hedera/networks/mainnet/fees#consensus-service). In other words, you can send 10,000 messages for $1 on the Hedera Network.
@@ -203,6 +218,8 @@ time.Sleep(30000)
To conclude: The total cost to create a topic and send a message to it is **$0.0101.**
+***
+
## Code Check ✅
diff --git a/tutorials/more-tutorials/how-to-auto-create-hedera-accounts-with-hbar-and-token-transfers.md b/tutorials/more-tutorials/how-to-auto-create-hedera-accounts-with-hbar-and-token-transfers.md
index 22ccd1bc6528..ee8b3c4f4fe8 100644
--- a/tutorials/more-tutorials/how-to-auto-create-hedera-accounts-with-hbar-and-token-transfers.md
+++ b/tutorials/more-tutorials/how-to-auto-create-hedera-accounts-with-hbar-and-token-transfers.md
@@ -12,7 +12,7 @@ The figure below highlights the transaction flow before HIP-542 and after.
In this tutorial, a treasury account will be created to transfer HTS tokens to Bob's ECDSA public key alias, involving a transfer of 10 FT and 1 NFT. The tutorial will also cover creating fungible tokens and an NFT collection (1000 FT / 5 NFT), creating Bob's ECDSA public key alias, and returning Bob's new account ID while confirming their ownership of the transferred tokens and NFT.
-
+***
## **Prerequisites**
@@ -28,6 +28,17 @@ In this tutorial, a treasury account will be created to transfer HTS tokens to B
+***
+
+## Table of Contents
+
+1. [Create Treasury Account](how-to-auto-create-hedera-accounts-with-hbar-and-token-transfers.md#create-treasury-account)
+2. [Create FTs and NFT Collection](how-to-auto-create-hedera-accounts-with-hbar-and-token-transfers.md#create-fts-and-an-nft-collection)
+3. [Create Bob's ECDSA Public Key Alias](how-to-auto-create-hedera-accounts-with-hbar-and-token-transfers.md#create-bobs-ecdsa-public-key-alias)
+4. [Return New Account ID](how-to-auto-create-hedera-accounts-with-hbar-and-token-transfers.md#return-new-account-id)
+
+***
+
## Create Treasury Account
We create the treasury account which will be the holder of the fungible and non-fungible tokens. The treasury account will be created with an initial balance of 100 HBAR.
@@ -201,7 +212,9 @@ export const createNewNftCollection = async (
{% endtab %}
{% endtabs %}
-## Create FTs and Create an NFT Collection
+***
+
+## Create FTs and an NFT Collection
Leverage the _**createFungibleToken**_ helper function defined above to create 10000 "Hip-542 example" fungible tokens. Use the code tab switch on the upper left of the code block to see how we use _**createNewNftCollection**_ to create our new NFT collection consisting of 5 NFTs.
@@ -232,6 +245,8 @@ const tokenId = await createFungibleToken(client, treasuryAccId, supplyKey, trea
{% endtab %}
{% endtabs %}
+***
+
## Create Bob's ECDSA Public Key Alias
An alias is an initial public key that will convert into a Hedera account through auto-account creation. An alias consists of \.\.\.
@@ -322,6 +337,8 @@ const nftTokenId = nftCreateTxnResponse.tokenId;
{% endtab %}
{% endtabs %}
+***
+
## Return New Account ID
Create a helper function to return the corresponding account Id to the given an alias.
@@ -421,4 +438,4 @@ Join and collaborate with Hedera Developers on the [Hedera Discord Server](https
\
Happy Building! 🛠️
-
diff --git a/tutorials/more-tutorials/how-to-configure-a-mirror-node-and-query-specific-data.md b/tutorials/more-tutorials/how-to-configure-a-mirror-node-and-query-specific-data.md
index 5d83eee5d80b..35b62fb65a7c 100644
--- a/tutorials/more-tutorials/how-to-configure-a-mirror-node-and-query-specific-data.md
+++ b/tutorials/more-tutorials/how-to-configure-a-mirror-node-and-query-specific-data.md
@@ -10,7 +10,7 @@ Hedera Mirror Node is a useful tool that lets developers and users access past t
This guide provides step-by-step instructions on how to configure and use a Hedera Mirror Node to access past transaction data on the Hedera network. You will learn how to configure your mirror node to store only the latest 90 days of data or data for a specific entity (account, smart contract, etc.) and how to use basic SQL queries to analyze the data.
-
+***
## Prerequisites
@@ -19,6 +19,18 @@ This guide provides step-by-step instructions on how to configure and use a Hede
* [Java](https://www.java.com/en/) (openjdk@17: Java version 17), [Gradle](https://gradle.org/install/) (the latest version), and [PostgreSQL](https://www.postgresql.org/) (the latest version) are installed on your machine.
* [Docker](https://www.docker.com/) (`>= v20.10.x)` installed and open on your machine. Run `docker -v` in your terminal to check the version you have installed.
+***
+
+## Table of Contents
+
+1. [Set Up Mirror Node](how-to-configure-a-mirror-node-and-query-specific-data.md#set-up-mirror-node)
+2. [Configure Mirror Node](how-to-configure-a-mirror-node-and-query-specific-data.md#configure-mirror-node)
+3. [Start Mirror Node](how-to-configure-a-mirror-node-and-query-specific-data.md#start-mirror-node)
+4. [Query Mirror Node](how-to-configure-a-mirror-node-and-query-specific-data.md#query-output-verification)
+5. [Additional Resources](how-to-configure-a-mirror-node-and-query-specific-data.md#additional-resources)
+
+***
+
## Set Up Mirror Node
Clone the Hedera mirror node repository and navigate to the project directory:
@@ -32,6 +44,8 @@ cd hedera-mirror-node
**Note:** Cloning the mirror node repository could require some time to complete.
{% endhint %}
+***
+
## Configure Mirror Node
In this example, we will configure the mirror node to store the last 90 days of data or data for a specific account ID (entity). To achieve this, we will need to create and modify an `application.yml` file. This file contains configuration settings for the mirror node, such as which data to store and how long to store it.
@@ -148,6 +162,8 @@ HEDERA_MIRROR_IMPORTER_RECORD_ENTITY_PERSIST_TOPICS=false
More details about retention [here](https://github.com/hashgraph/hedera-mirror-node/blob/main/docs/database.md#retention) and transaction and entity filtering [here](https://github.com/hashgraph/hedera-mirror-node/blob/main/docs/configuration.md#transaction-and-entity-filtering).
+***
+
## Start Mirror Node
The PostgreSQL container is responsible for creating the database for the mirror node instance, and the REST API container allows you to use the REST APIs to query the mirror node instance. The database stores the transaction data retrieved by the importer component of the mirror node, and the REST API provides an interface for accessing that data using HTTP requests. The importer component is responsible for retrieving the transaction data from the Hedera network and storing it in the database. Let's start up the database!
@@ -205,6 +221,8 @@ Type "help" for help.
mirror_node=>
```
+***
+
## Query Mirror Node
In this section, you can try out multiple queries that show you how to retrieve data from the PostgreSQL database. You need a basic understanding of SQL queries to craft your own queries.
@@ -331,6 +349,12 @@ Lastly, run the following command to stop and remove the created containers:
docker compose down
```
-#### **Congratulations! 🎉 You have successfully learned how to configure the Hedera Mirror Node to query specific data.** Feel free to reach out if you have any questions:
+**Congratulations! 🎉 You have successfully learned how to configure the Hedera Mirror Node to query specific data. Feel free to reach out on** [**Discord**](https://hedera.com/discord) **if you have any questions!**
+
+***
+
+## Additional Resources
+
+**➡** [**Mirror Node Repository**](https://github.com/hashgraph/hedera-mirror-node)
-
diff --git a/tutorials/more-tutorials/how-to-generate-a-random-number-on-hedera.md b/tutorials/more-tutorials/how-to-generate-a-random-number-on-hedera.md
index 3279c63959a3..7e3daa6c3656 100644
--- a/tutorials/more-tutorials/how-to-generate-a-random-number-on-hedera.md
+++ b/tutorials/more-tutorials/how-to-generate-a-random-number-on-hedera.md
@@ -8,9 +8,7 @@ In this tutorial, you will learn how to generate random numbers on Hedera using
This[ resource](https://www.wolfssl.com/true-random-vs-pseudorandom-number-generation/) is helpful if you want to learn more about the difference between pseudorandom and random numbers. For simplicity, we’ll use both terms interchangeably throughout this tutorial.
-
-
-> _**Note: This tutorial requires the use of the following tools: Hedera**_ [_**JavaScript SDK**_](../../sdks-and-apis/sdks/)_**, Solidity with libraries for random number generation (**_[_**HIP-351**_](https://hips.hedera.com/hip/hip-351)_**), and the Mirror Node REST API (**_[_**learn more**_](https://hedera.com/blog/how-to-look-up-transaction-history-on-hedera-using-mirror-nodes-back-to-the-basics)_**) and explorer (**_[_**HashScan**_](https://hashscan.io/#/mainnet/dashboard)_**).**_
+***
## **Prerequisites**
@@ -18,6 +16,22 @@ This[ resource](https://www.wolfssl.com/true-random-vs-pseudorandom-number-gener
* Get the [example code from GitHub](https://github.com/ed-marquez/hedera-example-random-number/blob/master/index.js).
* Set up your environment and create a client [here](../../getting-started/environment-set-up.md).
+_**📣 Note:** This tutorial requires the use of the following tools: Hedera_ [_JavaScript SDK_](../../sdks-and-apis/sdks/)_, Solidity with libraries for random number generation (_[_HIP-351_](https://hips.hedera.com/hip/hip-351)_), and the Mirror Node REST API (_[_learn more_](https://hedera.com/blog/how-to-look-up-transaction-history-on-hedera-using-mirror-nodes-back-to-the-basics)_) and explorer (_[_HashScan_](https://hashscan.io/#/mainnet/dashboard)_)._
+
+***
+
+## Table of Contents
+
+1. [Generate Random Numbers (SDK)](how-to-generate-a-random-number-on-hedera.md#generate-random-numbers-using-the-sdk)
+2. [Generate Random Numbers (Solidity)](how-to-generate-a-random-number-on-hedera.md#generate-random-numbers-using-solidity)
+ 1. [Deploy Contract](how-to-generate-a-random-number-on-hedera.md#deploy-contract)
+ 2. [Execute Contract](how-to-generate-a-random-number-on-hedera.md#execute-contract)
+ 3. [Query Results](how-to-generate-a-random-number-on-hedera.md#query-results)
+3. [Summary](how-to-generate-a-random-number-on-hedera.md#summary)
+4. [Additional Resources](how-to-generate-a-random-number-on-hedera.md#additional-resources)
+
+***
+
## **Generate Random Numbers Using the SDK**
**Step 1:** The Operator is the only account involved in submitting transactions to the Hedera network. Your testnet credentials from the [Hedera portal](https://portal.hedera.com/register) should be used for the operator variables, which are used to initialize the Hedera client that submits transactions to the network and gets confirmations.
@@ -69,6 +83,8 @@ STEP 1 ===================================
+***
+
## **Generate Random Numbers Using Solidity**
**Step 2:** Deploy a Solidity smart contract to generate the random number. After completing all steps, your console should look something like [this](how-to-generate-a-random-number-on-hedera.md#console-output-1).
@@ -315,10 +331,20 @@ STEP 2 ===================================
+***
+
## **Summary**
Now you know how to generate a random number on Hedera using the JavaScript SDK and Solidity libraries. Try this example with the other officially supported [SDKs](../../sdks-and-apis/sdks/#hedera-services-code-sdks) for Java, Go, and Swift (coming soon).
-**Congratulations! 🎉 You have successfully learned how to generate a random number on Hedera. Feel free to reach out if you have any questions:**
+**Congratulations! 🎉 You have successfully learned how to generate a random number on Hedera. Feel free to reach out on** [**Discord**](https://hedera.com/discord) **if you have any questions!**
+
+***
+
+## Additional Resources
+
+**➡** [**Project Repository**](https://github.com/ed-marquez/hedera-example-random-number)
+
+**➡** [**WolfSSL Random Number Guide**](https://www.wolfssl.com/true-random-vs-pseudorandom-number-generation/)
diff --git a/tutorials/more-tutorials/javascript-testing.md b/tutorials/more-tutorials/javascript-testing.md
index 2272040741a5..0bf460120bf6 100644
--- a/tutorials/more-tutorials/javascript-testing.md
+++ b/tutorials/more-tutorials/javascript-testing.md
@@ -14,7 +14,7 @@ Developing [DApps](../../support-and-community/glossary.md#decentralized-applica
Looking at the latter three, suffice it to say that learning testing with JavaScript is a fundamental skill for DApp developers. Unfortunately, it is one that is often overlooked. This tutorial aims to fill that gap. If you're planning to create a DApp on Hedera, but wish to brush up on the basics of testing first, start here!
-### What we will cover
+#### What we will cover
A test runner is a developer tool that helps you to:
@@ -48,7 +48,9 @@ For each scenario, you'll cover what to look out for and how to handle it proper
Let's begin!
-### Prerequisites
+***
+
+## Prerequisites
Prior knowledge
@@ -65,7 +67,9 @@ System
* Recommended setup method for Linux & Mac: [`nvm`](https://github.com/nvm-sh/nvm)
* Recommended setup method for Windows: [`nvm-windows`](https://github.com/coreybutler/nvm-windows)
-### Step 1: Set up the project
+***
+
+## Step 1: Set up the project
This has already been (mostly) done. All that's left for you to do is clone the [accompanying tutorial GitHub repository](https://github.com/hedera-dev/js-testing) and install the dependencies:
@@ -99,7 +103,9 @@ Open this repository in your code editor, and you'll find the following files:
* The tests, also referred to as _the specification._
* These specify what the behavior of the implementation should be.
-### Step 2: Implement the system under test
+***
+
+## Step 2: Implement the system under test
In the `add` function within `my-app.js,` you should see a comment marking _Step 2_. It looks like this:
@@ -129,7 +135,9 @@ It should now look like this:
Now you have completed your system under test!
-### Step 3: Implement the tests
+***
+
+## Step 3: Implement the tests
In `my-app.spec.js`, find the test block with the title `works with known values`, and add the following implementation where indicated with the comment.
@@ -171,7 +179,9 @@ So all the tests have passed: One that you have just added ('known values'), and
You could wrap up here... but you're not quite done yet. This is a **true positive scenario**, where both the implementation and the specification are correct. But there are three other possible scenarios that you're likely to encounter when writing tests, so let's go through them in the next few steps!
-### Step 4: Switch to a true negative scenario
+***
+
+## Step 4: Switch to a true negative scenario
In the **true negative scenario**, the implementation is wrong, and the specification is correct. This is probably the most common test failure scenario you'll encounter during development.
@@ -227,7 +237,9 @@ Interestingly, the tests for associativity and commutativity do not fail, even w
As a developer, at this point, you would typically _fix_ the error in the _implementation_, and then _re-run the tests_ to ensure that they pass once again. You will do so eventually, towards the end of this tutorial. However, for now, you'll move on to another scenario.
-### Step 5: Switch to a false negative scenario
+***
+
+## Step 5: Switch to a false negative scenario
In the **false negative scenario**, the implementation is correct, and the specification is wrong. This is not as common of a scenario that you'll encounter during development as the false positive, but it is nonetheless important to be able to recognize it when it does occur and rectify it accordingly.
@@ -279,7 +291,9 @@ This time, the error shows that the `actual` value was `3`, while the `expected`
As a developer, at this point, you would typically _fix_ the error in the _specification_, and then _re-run the tests_ to see if they pass once again. Instead, let's move on to another scenario.
-### Step 6: Switch to a false positive scenario
+***
+
+## Step 6: Switch to a false positive scenario
In the **false positive scenario**, the implementation is wrong, and the specification is also wrong. This is typically the least common scenario that you'll encounter during development. And it can be extremely tricky to even identify, as you'll see shortly.
@@ -326,7 +340,9 @@ False positive scenarios are typically spotted through manual reviews of the bot
Now let's finally fix the code, and go back to the true positive scenario, where you started off.
-### Step 7: Switch back to a true positive scenario
+***
+
+## Step 7: Switch back to a true positive scenario
In the **true positive scenario**, the implementation is correct, and the specification is correct as well. This is the **ideal** scenario among the 4 possible ones that you've covered thus far. Whenever there are errors identified in either the implementation or specification, the goal is to fix them such that you _return_ to this true positive scenario.
@@ -365,7 +381,9 @@ You should now see some output that looks similar to the following:
Back to all tests passing (for the right reasons)!
-### Step 8: Bonus - Add generative testing
+***
+
+## Step 8: Bonus - Add generative testing
Thus far, all the tests that you have written (in `my-app.spec.js`) are example based tests. Essentially your tests consist of one or more interactions with the system under test actual value, an expected value, and an assertion that the actual value matches the expected value. In this step, we'll add a _different type of tests_ to this project: Generative testing.
@@ -421,7 +439,7 @@ bas
These generative tests are passing as well and form an additional layer of verification of the system under test. You can now be extra sure that the implementation is indeed correct.
-### Congrats!
+#### Congrats!
You've completed this tutorial! :tada: :tada: :tada:
diff --git a/tutorials/smart-contracts/create-an-hbar-faucet-app-using-react-and-metamask.md b/tutorials/smart-contracts/create-an-hbar-faucet-app-using-react-and-metamask.md
index 589d9c1fdb4f..c35ff4703474 100644
--- a/tutorials/smart-contracts/create-an-hbar-faucet-app-using-react-and-metamask.md
+++ b/tutorials/smart-contracts/create-an-hbar-faucet-app-using-react-and-metamask.md
@@ -2,15 +2,6 @@
Enabling the opportunity to connect to a decentralized application (dApp) with different wallets provides more control to the user. Recently, [HIP-583](https://hips.hedera.com/hip/hip-583) added the necessary network infrastructure to support Ethereum Virtual Machine (EVM) wallets on the Hedera network. This added functionality, combined with the auto-create flow described in [HIP-32](https://hips.hedera.com/hip/hip-32), enables developers to transfer native Hedera Token Service (HTS) tokens to EVM addresses that do not yet exist on the Hedera network. In this tutorial, we start out with a Hedera react app, connect our dApp to MetaMask, and finally transfer HBAR to the connected MetaMask account.
-
-
-## Prerequisites
-
-* Create a Hedera Testnet account [here](../../getting-started/introduction.md).
-* Install the [MetaMask Chrome extension](https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en).
-* Basic understanding of [TypeScript](https://www.typescriptlang.org/) and [React](https://react.dev/).
-* Set up your environment and create your client [here](../../getting-started/environment-set-up.md).
-
#### What we will do:
This tutorial will show you how to create a Hedera React app using TypeScript and Material UI. You'll install the MetaMask Chrome extension, add the Hedera Testnet network, connect your dApp to it, and even send some HBAR to your MetaMask wallet.
@@ -25,6 +16,32 @@ The complete JavaScript project can be found on GitHub [here](https://github.com
+***
+
+## Prerequisites
+
+* Create a Hedera Testnet account [here](../../getting-started/introduction.md).
+* Install the [MetaMask Chrome extension](https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en).
+* Basic understanding of [TypeScript](https://www.typescriptlang.org/) and [React](https://react.dev/).
+* Set up your environment and create your client [here](../../getting-started/environment-set-up.md).
+
+***
+
+## Table of Contents
+
+1. [Create React App](create-an-hbar-faucet-app-using-react-and-metamask.md#create-react-app)
+2. [Configure MetaMask](create-an-hbar-faucet-app-using-react-and-metamask.md#configure-metamask-with-hedera-testnet-network)
+3. [Connect MetaMask](create-an-hbar-faucet-app-using-react-and-metamask.md#connect-our-dapp-to-metamask-and-retrieve-wallet-address)
+4. [Install Dependencies](create-an-hbar-faucet-app-using-react-and-metamask.md#install-dependencies)
+5. [Create Your Client](create-an-hbar-faucet-app-using-react-and-metamask.md#create-your-client)
+6. [Send HBAR to MetaMask](create-an-hbar-faucet-app-using-react-and-metamask.md#send-hbar-to-metamask-wallet)
+7. [Summary](create-an-hbar-faucet-app-using-react-and-metamask.md#summary)
+8. [Additional Resources](create-an-hbar-faucet-app-using-react-and-metamask.md#additional-resources)
+
+***
+
+***
+
## Create React App
Open your terminal and run the following command to create a React app that utilizes TypeScript and Material UI.
@@ -50,6 +67,8 @@ Open the project in Visual Studio code or your IDE of choice. Your project direc
**If you have not already installed the MetaMask Chrome extension, please install it** [**here**](https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en)**.**
+***
+
## Configure MetaMask with Hedera Testnet Network
In this step, we will add the code necessary to add the Hedera Testnet network to MetaMask so we can connect to it. Before we do that, let’s check out our project folder structure, which looks like this:
@@ -126,6 +145,8 @@ Let’s digest this function a little further. This function starts by submittin
\
In the request to add a new chain, the decimal value is set to 18 even though HBAR has 8 decimals. The reason for this is that MetaMask only supports chains that have 18 decimals. The RPC URL we use is [**https://testnet.hashio.io/api**](https://testnet.hashio.io/api), which comes from [Hashio](https://swirldslabs.com/hashio/), the SwirldsLabs-hosted version of the [JSON-RPC Relay](../../core-concepts/smart-contracts/deploying-smart-contracts/json-rpc-relay.md).
+***
+
## Connect Our dApp to MetaMask and Retrieve Wallet Address
We have added the code necessary to configure MetaMask with the Hedera test network. Now, it's time to focus on adding the code that will allow us to connect our dApp to MetaMask.
@@ -156,12 +177,10 @@ If MetaMask is installed, _connectToMetamask()_ will call _switchToHederaNetwork
Before we do any kind of work or testing, it is important to ensure we are connected to the correct network.
-## Install Hedera JS SDK and Create Your Client
+## Install Dependencies
We’ve written the code to connect our application to MetaMask. Now it’s time to send HBAR to our MetaMask wallet.
-### Install Dependencies
-
Install the Hedera JavaScript SDK and dotenv by running the following command in the project root directory:
```bash
@@ -181,7 +200,7 @@ In a react-app, the environment variables in your .env file must start with REAC
_**Note**: If you need to create a Hedera Testnet account, visit_ [_portal.hedera.com_](https://portal.hedera.com/) _and register to receive 10,000 test HBAR._
-### Create Your Client
+## Create Your Client
A client is used to communicate with the network. We create our client for the Hedera Testnet, which enables us to submit transactions and pay for them. Let’s create our client in our `Home.tsx` file.
@@ -410,10 +429,20 @@ Once connected, send HBAR by clicking on the ‘_SEND HBAR TO METAMASK_’ butto
## Summary
-Congratulations! **🎉** You successfully followed the tutorial to create an HBAR faucet for MetaMask and a Hedera React application that integrates with MetaMask!
-
You learned how to build a transfer transaction that sends an amount of HBAR through the Hedera Testnet to a MetaMask account. This can also be applied to other applications, and I encourage all to keep building.
-Feel free to reach out if you have any questions:
+Congratulations! 🎉 You successfully followed the tutorial to create an HBAR faucet for MetaMask and a Hedera React application that integrates with MetaMask! Feel free to reach out in [Discord](https://hedera.com/discord) if you have any questions!
+
+***
+
+## Additional Resources
+
+**➡** [**TypeScript Project Repository**](https://github.com/a-ridley/hbar-faucet-for-metamask)
+
+**➡** [**JavaScript Project Repository**](https://github.com/a-ridley/hbar-faucet-for-metamask-JS)
+
+**➡** [**Download MetaMask Wallet**](https://metamask.io/download/)
+
+**➡ Have a question? Ask on** [**StackOverflow**](https://stackoverflow.com/questions/tagged/hedera-hashgraph)
-
diff --git a/tutorials/smart-contracts/deploy-a-contract-using-the-hedera-token-service.md b/tutorials/smart-contracts/deploy-a-contract-using-the-hedera-token-service.md
index 3c9146d10c85..d2fbfce795c0 100644
--- a/tutorials/smart-contracts/deploy-a-contract-using-the-hedera-token-service.md
+++ b/tutorials/smart-contracts/deploy-a-contract-using-the-hedera-token-service.md
@@ -10,15 +10,17 @@ The example does not cover the environment setup or creating certain variables t
_Smart contract entity auto renewal and expiry will be enabled in a future release. Please check out_ [_HIP-16_](https://hips.hedera.com/hip/hip-16) _for more information._
{% endhint %}
+***
+
## Prerequisites
We recommend you complete the following introduction to get a basic understanding of Hedera transactions. This example does not build upon the previous examples.
-
-
-* Get a [Hedera testnet account](https://portal.hedera.com/register).
+* Get a [Hedera testnet account](../../getting-started/introduction.md).
* Set up your environment [here](../../getting-started/environment-set-up.md).
+***
+
## 1. Create Your "HTS" Smart Contract
In this example, you will associate a token to an account and transfer tokens to the associated account by interacting with the HTS contract deployed to Hedera. The HTS contract has three functions that allow you to associate, transfer, and dissociate tokens from a Hedera account.
@@ -210,6 +212,8 @@ contract HTS is HederaTokenService {
{% endtab %}
{% endtabs %}
+***
+
## 2. Store the Smart Contract Bytecode on Hedera
Create a file using the `FileCreateTransaction()` API to store the hex-encoded byte code of the "HTS" contract. Once the file is created, you can obtain the file ID from the receipt of the transaction.
@@ -324,6 +328,8 @@ fmt.Printf("The contract bytecode file ID: %v\n", byteCodeFileID)
{% endtab %}
{% endtabs %}
+***
+
## 3. Deploy a Hedera Smart Contract
Create the contract and set the file ID to the file that contains the hex-encoded bytecode from the previous step. You will need to set the gas high enough to deploy the contract. The gas should be estimated to be within 25% of the actual gas cost to avoid paying extra gas. You can read more about gas and fees [here](broken-reference).
@@ -408,6 +414,8 @@ fmt.Printf("The contract ID %v\n", contractId)
{% endtab %}
{% endtabs %}
+***
+
## 4. Call the `tokenAssociate` Contract Function
The `tokenAssociate` function in the contract will associate a token that was created using the native Hedera Token Service. You can create a new token using HTS or using an existing token in this example. Use the `ContractExecuteTransaction()` API to call the contract's `tokenAssociate` function. You will pass the token ID and account ID in Solidity `address` format to the contract function. The contract function parameters must be provided in the order expected by the function to execute successfully.
@@ -505,6 +513,8 @@ fmt.Printf("The associate transaction status %v\n", txStatus)
{% endtab %}
{% endtabs %}
+***
+
## 5. Get the `tokenAssociate` Transaction Record
The contract execute transaction that triggered a subsequent token associate transaction in the contract is an example of a **nested transaction.** The contract execute transaction is the parent transaction and the token associate transaction is referred to as the child transaction. Both parent and child transactions share the same payer account ID and transaction valid duration with the exception of the child transaction having a nonce value at the end. The nonce value increments for each subsequent child transaction.
@@ -594,6 +604,8 @@ fmt.Printf("The account token balance %v\n", accountBalance.Tokens)
{% endtab %}
{% endtabs %}
+***
+
## 6. Call the `tokenTransfer` Contract Function
Transfer 100 units of the token to the account that was associated with the token. You will use the `ContractExecuteTransaction()` API and set the contract function to `tokenTransfer`. The contract function parameters must be provided in the order of the function expects to receive them.
@@ -734,6 +746,8 @@ _**Note:** Check out our_ [_smart contract mirror node rest APIs_](../../sdks-an
* Requested a transaction record for a nested transaction
* Transferred tokens using the deployed contract
+***
+
## Code Check ✅
@@ -1392,10 +1406,12 @@ func main() {
-Happy Building! Feel free to reach out if you have any questions:
+***
-{% hint style="info" %}
-Have a question? [Ask it on StackOverflow](https://stackoverflow.com/questions/tagged/hedera-hashgraph)
-{% endhint %}
+## Additional Resources
+
+**➡ Have a question? Ask on** [**StackOverflow**](https://stackoverflow.com/questions/tagged/hedera-hashgraph)
+
+**➡ Feel free to reach out in** [**Discord**](https://hedera.com/discord)**!**
diff --git a/tutorials/smart-contracts/deploy-a-smart-contract-using-hardhat-and-hedera-json-rpc-relays.md b/tutorials/smart-contracts/deploy-a-smart-contract-using-hardhat-and-hedera-json-rpc-relays.md
index 4879280ba12c..3faf06330467 100644
--- a/tutorials/smart-contracts/deploy-a-smart-contract-using-hardhat-and-hedera-json-rpc-relays.md
+++ b/tutorials/smart-contracts/deploy-a-smart-contract-using-hardhat-and-hedera-json-rpc-relays.md
@@ -636,4 +636,4 @@ _**Note:** At the top of the explorer page, remember to switch the network to **
**➡**[ **Hardhat Documentation**](https://hardhat.org/hardhat-runner/docs/getting-started#overview)
-
diff --git a/tutorials/smart-contracts/deploy-a-subgraph-using-the-graph-and-json-rpc.md b/tutorials/smart-contracts/deploy-a-subgraph-using-the-graph-and-json-rpc.md
index 001d2859caec..80e8eff4d32c 100644
--- a/tutorials/smart-contracts/deploy-a-subgraph-using-the-graph-and-json-rpc.md
+++ b/tutorials/smart-contracts/deploy-a-subgraph-using-the-graph-and-json-rpc.md
@@ -1,17 +1,15 @@
-# Deploy a Subgraph Using The Graph and JSON-RPC
+# Deploy a Subgraph Using The Graph and Hedera JSON-RPC Relay
In this tutorial, you'll learn how to create and deploy a subgraph using The Graph protocol. By indexing specific network data using user-defined data structures called "subgraphs," developers can easily query the indexed data through a GraphQL API, creating robust backends for dApps. Subgraphs simplify the process of obtaining blockchain/network data for developers building dApps. This approach removes the complexities of interacting directly with the network, allowing developers to focus on building. Although Hedera supports subgraphs, its hosted service is currently unavailable, so we'll need to set up and run a local graph node to deploy our subgraph.
By the end of this tutorial, you'll be able to configure a mirror node, query data from your subgraph using the GraphQL API, and integrate it into your dApp. You'll also have a better understanding of how to define custom data schemas, indexing rules, and queries for your subgraph, allowing you to tailor it to your specific use case.
-
-
-> _**NOTE:** While it is possible to present and interact with HTS tokens in a similar manner as ERC-20/721 tokens, the network is presently unable to capture all the expected ERC-20/721 event logs. In other words, if ERC-like operations are conducted on HTS tokens, not all of them will be captured in smart contract event logging at this time._
-
{% hint style="info" %}
**Note:** While it is possible to present and interact with HTS tokens in a similar manner as ERC-20/721 tokens, the network is presently unable to capture all the expected ERC-20/721 event logs. In other words, if ERC-like operations are conducted on HTS tokens, not all of them will be captured in smart contract event logging.
{% endhint %}
+***
+
## Prerequisites
* Basic understanding of JavaScript and NPM installed.
@@ -54,7 +52,19 @@ _**Note**: The Graph CLI will be installed globally, so you can run the command
-## Subgraph Project Setup
+***
+
+## Table of Contents
+
+1. [Project Setup](deploy-a-subgraph-using-the-graph-and-json-rpc.md#project-setup)
+2. [Project Configuration](deploy-a-subgraph-using-the-graph-and-json-rpc.md#project-configuration)
+3. [Deploy Subgraph](deploy-a-subgraph-using-the-graph-and-json-rpc.md#deploy-subgraph)
+4. [Code Check](deploy-a-subgraph-using-the-graph-and-json-rpc.md#code-check)
+5. [Additional Resources](deploy-a-subgraph-using-the-graph-and-json-rpc.md#additional-resources)
+
+***
+
+## Project Setup
Open a terminal window and navigate to the directory where you want your subgraph project stored. Clone the `hedera-subgraph-example` repo, change directories, and install dependencies:
@@ -94,7 +104,9 @@ In the `testnet.json` file, under the `config` folder, replace the `startBlock`
```
{% endcode %}
-## Project Contents and Configuration
+***
+
+## Project Configuration
In this step, you will use the `Greeter` contract from the [Hardhat tutorial](deploy-a-smart-contract-using-hardhat-and-hedera-json-rpc-relays.md) as an example subgraph, to configure four main project files: the subgraph manifest, GraphQL schema, event mappings, and Docker compose configuration. The manifest specifies which events the subgraph will listen for, while mappings map each event emitted by the smart contract into entities that can be indexed.
@@ -189,6 +201,8 @@ ethereum: 'testnet:https://testnet.hashio.io/api
_**Note:** For more info on how to set up an indexer, check out_ T\_he Graph\_ [_docs_](https://thegraph.com/docs/en/) _and the_ [_official graph-node GitHub repository_](https://github.com/graphprotocol/graph-node)_. For a full subgraph project example, check out_ [_this_](https://github.com/hashgraph/hedera-json-rpc-relay/tree/main/tools/subgraph-example) _repo._
+***
+
## Deploy Subgraph
In this step, you will create the subgraph and deploy it to your local graph node. If everything runs without errors, your terminal should resemble the console check at the end of each subsection.
@@ -348,6 +362,8 @@ After the subgraph is successfully deployed, open the [GraphQL playground](http:
+***
+
## Code Check ✅
@@ -477,6 +493,14 @@ Follow the steps below to execute the query and fetch the indexed data from the
-#### **Congratulations! 🎉 You have successfully learned how to deploy a Subgraph using The Graph Protocol and JSON-RPC.** Feel free to reach out if you have any questions:
+#### **Congratulations! 🎉 You have successfully learned how to deploy a Subgraph using The Graph Protocol and JSON-RPC. Feel free to reach out on** [**Discord**](https://hedera.com/discord) **if you have any questions!**
+
+***
+
+## Additional Resources
+
+**➡** [**Project Repository**](https://github.com/hashgraph/hedera-subgraph-example)
+
+**➡** [**Subgraph Example**](https://github.com/hashgraph/hedera-json-rpc-relay/tree/main/tools/subgraph-example)
-
diff --git a/tutorials/smart-contracts/deploy-by-leveraging-ethereum-developer-tools-on-hedera.md b/tutorials/smart-contracts/deploy-by-leveraging-ethereum-developer-tools-on-hedera.md
index 7e5b3ebea92d..d3806aa07ade 100644
--- a/tutorials/smart-contracts/deploy-by-leveraging-ethereum-developer-tools-on-hedera.md
+++ b/tutorials/smart-contracts/deploy-by-leveraging-ethereum-developer-tools-on-hedera.md
@@ -127,4 +127,4 @@ The release of the JSON-RPC Relay to developers brings greater usability to the
Happy Building! Feel free to reach out if you have any questions:
-
diff --git a/tutorials/smart-contracts/deploy-smart-contracts-on-hedera-using-truffle.md b/tutorials/smart-contracts/deploy-smart-contracts-on-hedera-using-truffle.md
index d38613f4c802..37bb838916f1 100644
--- a/tutorials/smart-contracts/deploy-smart-contracts-on-hedera-using-truffle.md
+++ b/tutorials/smart-contracts/deploy-smart-contracts-on-hedera-using-truffle.md
@@ -10,7 +10,7 @@ This tutorial shows you how to deploy smart contracts on Hedera using Truffle an
You can find more examples using Truffle, Web3JS, and Hardhat in [this GitHub repository](https://github.com/hashgraph/hedera-json-rpc-relay/tree/main/tools).
-
+***
## **Prerequisites**
@@ -23,6 +23,17 @@ You can find more examples using Truffle, Web3JS, and Hardhat in [this GitHub re
* _**node create-account.js**_
* Get[ ](https://github.com/ed-marquez/hedera-example-staking)[the example code from GitHub](https://github.com/ed-marquez/hedera-example-json-rpc-truffle)
+***
+
+## Table of Contents
+
+1. [Create an ECDSA Account](deploy-smart-contracts-on-hedera-using-truffle.md#create-an-account-that-has-ecdsa-keys)
+2. [Compile Smart Contract](deploy-smart-contracts-on-hedera-using-truffle.md#compile-a-smart-contract-using-truffle)
+3. [Deploy Smart Contract](deploy-smart-contracts-on-hedera-using-truffle.md#deploy-the-smart-contract-to-hedera-using-truffle)
+4. [Additional Resources](deploy-smart-contracts-on-hedera-using-truffle.md#additional-resources)
+
+***
+
## Create an Account that Has ECDSA Keys
Hedera supports two popular types of signature algorithms, ED25519 and ECDSA. Both are used in many blockchain platforms, including Bitcoin and Ethereum. **Currently, the JSON RPC Relay only supports Hedera accounts with an alias set (i.e. public address) based on its ECDSA public key.** To deploy a smart contract using Truffle, we first have to create a new account that meets these criteria. The _**main()**_ function in _**create-account.js**_ helps us do just that.
@@ -109,6 +120,8 @@ async function mirrorQueryFcn(publicKey) {
}
```
+***
+
## Compile a Smart Contract Using Truffle
Now it’s time to compile _**SimpleStorage**_, which is a basic smart contract that allows anyone to set and get data.
@@ -140,6 +153,8 @@ _**Console Output:**_
+***
+
## Deploy the Smart Contract to Hedera Using Truffle
Finally, deploy the contract on Hedera through the JSON RPC Relay. Be sure to configure the following parameters in your _**.env**_ file to be able to deploy to the Hedera testnet with Truffle.
@@ -176,8 +191,18 @@ You can obtain more information about the newly deployed contract using the [mir
Now you know how to deploy smart contracts on Hedera using Truffle and the JSON RPC Relay. The first part of this example used the Hedera [JavaScript SDK](../../sdks-and-apis/sdks/#hedera-services-code-sdks). However, you can try this with the other officially supported SDKs for Java and Go.
-Feel free to reach out if you have any questions:
+***
+
+## Additional Resources
+
+**➡** [**Project Repository**](https://github.com/ed-marquez/hedera-example-json-rpc-truffle)
+
+**➡** [**CodeSandbox**](https://codesandbox.io/s/hedera-example-json-rpc-truffle-q6kibt?file=/create-account.js)
+
+**➡** [**Truffle Documentation**](https://trufflesuite.com/docs/)
+
+**➡ Feel free to reach out in** [**Discord**](https://hedera.com/discord)
-
diff --git a/tutorials/smart-contracts/deploy-your-first-smart-contract.md b/tutorials/smart-contracts/deploy-your-first-smart-contract.md
index 2f035b937fe3..125c1aafc08f 100644
--- a/tutorials/smart-contracts/deploy-your-first-smart-contract.md
+++ b/tutorials/smart-contracts/deploy-your-first-smart-contract.md
@@ -1,20 +1,27 @@
# Deploy Your First Smart Contract
-## Summary
-
In this tutorial, you will learn how to create a simple smart contract on Hedera using Solidity.
-We recommend you complete the following introduction to get a basic understanding of Hedera transactions. This example does not build upon the previous examples.
+***
## Prerequisites
We recommend you complete the following introduction to get a basic understanding of Hedera transactions. This example does not build upon the previous examples.
-
-
-* Get a [Hedera testnet account](https://portal.hedera.com/register).
+* Get a [Hedera testnet account](../../getting-started/introduction.md).
* Set up your environment [here](../../getting-started/environment-set-up.md).
+***
+
+## Table of Contents
+
+1. [Create Smart Contract](deploy-your-first-smart-contract.md#1.-create-a-hello-hedera-smart-contract)
+2. [Store Bytecode on Hedera](deploy-your-first-smart-contract.md#2.-store-the-smart-contract-bytecode-on-hedera)
+3. [Deploy Hedera Smart Contract](deploy-your-first-smart-contract.md#3.-deploy-a-hedera-smart-contract)
+4. [Call Contract Functions](deploy-your-first-smart-contract.md#4.-call-contract-functions)
+
+***
+
## 1. Create a "Hello Hedera" Smart Contract
Create a smart contract in solidity using the [remix IDE](https://remix.ethereum.org/#optimize=false\&runs=200\&evmVersion=null\&version=soljson-v0.8.7+commit.e28d00a7.js). The "Hello Hedera" contract Solidity file is sampled below along with the "Hello Hedera" JSON file that is produced after the contract has been compiled. You can use remix to create and compile the contract yourself or you can copy the files below into your project. If you are not familiar with Solidity you can check out the docs [here](https://docs.soliditylang.org/en/v0.8.9/). Hedera supports the latest version of Solidity (v0.8.9) on previewnet and testnet.
@@ -165,6 +172,8 @@ contract HelloHedera {
{% endtab %}
{% endtabs %}
+***
+
## 2. Store the Smart Contract Bytecode on Hedera
Create a file using the `FileCreateTransaction()` API to store the hex-encoded byte code of the "Hello Hedera" contract. Once the file is created, you can obtain the file ID from the receipt of the transaction.
@@ -284,6 +293,8 @@ fmt.Printf("contract bytecode file: %v\n", bytecodeFileID)
{% endtab %}
{% endtabs %}
+***
+
## 3. Deploy a Hedera Smart Contract
Create the contract and set the file ID to the file ID that stores the hex-encoded byte code from the previous step. You will also need to set gas the value that will create the contract and pass the constructor parameters using `ContractFunctionParameters()` API. In this example, "hello from Hedera!" was passed to the constructor. After the transaction is successfully executed, you can get the contract ID from the receipt.
@@ -380,7 +391,11 @@ newContractID := *contractReceipt.ContractID
{% endtab %}
{% endtabs %}
-## 4. Call the `get_message` contract function
+***
+
+## 4. Call Contract Functions
+
+### Call the `get_message` contract function
In the previous step, the contract message variable was set to "hello from Hedera!." You can return this message from the contract by submitting a query that will return the stored message string. The `ContractCallQuery()` similarly does not modify the state of the contract like other Hedera queries. It only reads stored values.
@@ -470,7 +485,7 @@ fmt.Printf("The contract message: ", getMessage)
{% endtab %}
{% endtabs %}
-## 5. Call the `set_message` contract function
+### Call the `set_message` contract function
Call the `set_message` function of the contract. To do this you will need to use the `ContractExecuteTransaction()` API. This transaction will update the contract message. Once the transaction is successfully submitted you can verify the message was updated by requesting `ContractCallQuery()`. The message returned from the contract should now log "Hello from Hedera again!"
@@ -626,8 +641,10 @@ fmt.Printf("The updated contract message: ", getMessage2)
Video tutorial
{% endembed %}
-{% hint style="info" %}
-Have a question? [Ask it on StackOverflow](https://stackoverflow.com/questions/tagged/hedera-hashgraph)
-{% endhint %}
+***
+
+## Additional Resources
+
+**➡ Have a question? Ask on** [**StackOverflow**](https://stackoverflow.com/questions/tagged/hedera-hashgraph)
diff --git a/tutorials/smart-contracts/how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md b/tutorials/smart-contracts/how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md
index dcf547128a49..c207067ef147 100644
--- a/tutorials/smart-contracts/how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md
+++ b/tutorials/smart-contracts/how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md
@@ -2,12 +2,12 @@
[Foundry](https://book.getfoundry.sh/forge/) provides tools to developers who are developing smart contracts. One of the 3 main components of Foundry is _**Forge**: Foundry’s testing framework_. Tests are written in Solidity and are easily run with the forge test command. This tutorial will dive into configuring Foundry with Hedera to use Forge in order to write and run tests for smart contracts.
-
-
{% hint style="info" %}
**Note:** [Hashio](https://swirldslabs.com/hashio/), the SwirldsLabs hosted version of the [JSON-RPC Relay](../../core-concepts/smart-contracts/deploying-smart-contracts/json-rpc-relay.md), is in beta. If issues are encountered while using Foundry and Hashio, please create an issue in the JSON-RPC Relay GitHub [repository](https://github.com/hashgraph/hedera-json-rpc-relay).
{% endhint %}
+***
+
## Prerequisites
* [Install Foundry](https://book.getfoundry.sh/getting-started/installation) and [a Hedera Testnet account](../../getting-started/introduction.md).
@@ -15,6 +15,20 @@
* Basic understanding of [Foundry](https://book.getfoundry.sh/) and [Forge](https://book.getfoundry.sh/forge/) framework.
* Basic understanding of the Hedera [JSON-RPC Relay](../../core-concepts/smart-contracts/deploying-smart-contracts/json-rpc-relay.md).
+***
+
+## Table of Contents
+
+1. [Create Hedera Project](how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md#create-a-hedera-project-and-install-the-hedera-js-sdk)
+2. [Configure Foundry](how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md#configure-foundry-in-your-hedera-project)
+3. [Create Tests](how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md#create-tests)
+4. [Deploy Smart Contract](how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md#deploy-your-smart-contract)
+5. [Forge Gas Reports](how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md#forge-gas-reports)
+6. [Summary](how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md#summary)
+7. [Additional Resources](how-to-set-up-foundry-to-test-smart-contracts-on-hedera.md#additional-resources)
+
+***
+
## Create a Hedera Project and Install the Hedera JS SDK
Open your terminal and create a directory called `my-hedera-project` by running the following command:
@@ -120,6 +134,8 @@ Foundry manages dependencies using git submodules by default. Hedera manages dep
└── tsconfig.json
```
+***
+
## Configure Foundry in your Hedera project
Foundry’s default directory for contracts is `src/`, but we will need it to map to contracts. Tests will map to our `test/foundry` path, and the `cache_path` will map to our `cache/forge-cache` directory.
@@ -149,6 +165,8 @@ And what these remappings translate to is:
* To import from `ds-test` we write import “ds-test/TodoList.sol”;
* To import from `forge-std` we write import “forge-std/Contract.sol”;
+***
+
## Create Tests
#### Create a smart contract
@@ -262,6 +280,8 @@ forge test
+***
+
## Deploy Your Smart Contract
#### Step 1: Compile your smart contract using solc
@@ -326,6 +346,8 @@ const hederaFoundryExample = async () => {
hederaFoundryExample();
```
+***
+
## Forge Gas Reports
Forge has functionality built in to give you [gas reports](https://book.getfoundry.sh/forge/gas-reports) of your contracts. First, configure your `foundry.toml` to specify which contracts should generate a gas report.
@@ -348,10 +370,22 @@ forge test –gas-report
Your output will show you an estimated gas average, median, and max for each contract function and total deployment cost and size.
+***
+
## Summary
In this tutorial, we have learned how to configure Foundry to work with a Hedera project to test our smart contracts using the [forge](https://book.getfoundry.sh/forge/) framework. We also learned how to generate gas reports for our smart contracts.
-Happy Building! Feel free to reach out if you have any questions:
+Happy Building! Feel free to reach out in [Discord](https://hedera.com/discord) if you have any questions!
+
+***
+
+## Additional Resources
+
+**➡** [**Project Repository**](https://github.com/hedera-dev/hedera-smart-contract-testing-with-foundry)
+
+**➡** [**Foundry Documentation**](https://book.getfoundry.sh/)
+
+**➡ Have a question? Ask on** [**StackOverflow**](https://stackoverflow.com/questions/tagged/hedera-hashgraph)
-
diff --git a/tutorials/smart-contracts/send-and-receive-hbar-using-solidity-smart-contracts.md b/tutorials/smart-contracts/send-and-receive-hbar-using-solidity-smart-contracts.md
index 2be056e0c237..f1f20cd28773 100644
--- a/tutorials/smart-contracts/send-and-receive-hbar-using-solidity-smart-contracts.md
+++ b/tutorials/smart-contracts/send-and-receive-hbar-using-solidity-smart-contracts.md
@@ -12,12 +12,26 @@ Follow these main 3 steps:
Throughout the tutorial, you also learn how to check the HBAR balance of the contract by calling a function of the contract itself and by using the SDK query. The last step is to review the transaction history for the contract and the operator account in a mirror node explorer, like [HashScan](https://hashscan.io/#/mainnet/dashboard).
-
+***
## **Prerequisites**
-* Get a [Hedera testnet account](https://portal.hedera.com/register).
-* Get the [example code from GitHub](https://github.com/ed-marquez/hedera-smart-contracts/tree/examples/examples/transfer-hbar2contracts-solidity).
+We recommend you complete the following introduction to get a basic understanding of Hedera transactions. This example does not build upon the previous examples.
+
+* Get a [Hedera testnet account](../../getting-started/introduction.md).
+* Set up your environment [here](../../getting-started/environment-set-up.md).
+
+***
+
+## Table of Contents
+
+1. [Create Accounts and Deploy a Contract](send-and-receive-hbar-using-solidity-smart-contracts.md#create-accounts-and-deploy-a-contract)
+2. [Get HBAR to ➡ Contract](send-and-receive-hbar-using-solidity-smart-contracts.md#getting-hbar-to-the-contract)
+3. [Get HBAR from ⬅ Contract](send-and-receive-hbar-using-solidity-smart-contracts.md#getting-hbar-from-the-contract)
+4. [Summary](send-and-receive-hbar-using-solidity-smart-contracts.md#summary)
+5. [Additional Resources ](send-and-receive-hbar-using-solidity-smart-contracts.md#additional-resources)
+
+***
## **Create Accounts and Deploy a Contract**
@@ -179,6 +193,8 @@ async function contractDeployFcn(bytecode, gasLim) {
+***
+
## **Getting HBAR to the Contract**
### **The **_**receive**_**/**_**fallback**_** Functions**
@@ -353,6 +369,8 @@ async function hbar2ContractSdkFcn(sender, receiver, amount, pKey) {
+***
+
## **Getting HBAR from the Contract**
In this section the contract transfers HBAR to Alice using three different methods: _**transfer**_, _**send**_, _**call**_. Each transfer is of 20 HBAR, so by the end the contract should have 1 HBAR left in its balance.
@@ -463,16 +481,24 @@ https://hashscan.io/#/testnet/account/${operatorId}`);
+***
+
## **Summary**
If you run the entire example successfully, your console should look something like:
-Congratulations! 🎉 Now you know how to send HBAR to and from a contract on Hedera using both the SDK and Solidity!
-
This tutorial used the Hedera JavaScript SDK. However, you can try this with the other officially supported [SDKs](../../sdks-and-apis/sdks/) for Java and Go.
-Feel free to reach out if you have any questions:
+**Congratulations! 🎉 Now you know how to send HBAR to and from a contract on Hedera using both the SDK and Solidity! Feel free to reach out in** [**Discord**](https://hedera.com/discord) **if you have any questions!**
+
+***
+
+## Additional Resources
+
+**➡** [**Project Repository**](https://github.com/ed-marquez/hedera-smart-contracts/tree/examples/examples/transfer-hbar2contracts-solidity)
+
+**➡ Have a question? Ask on** [**StackOverflow**](https://stackoverflow.com/questions/tagged/hedera-hashgraph)
-
diff --git a/tutorials/token/create-and-transfer-an-nft-using-a-solidity-contract.md b/tutorials/token/create-and-transfer-an-nft-using-a-solidity-contract.md
index b6e5784581aa..222d91e2d849 100644
--- a/tutorials/token/create-and-transfer-an-nft-using-a-solidity-contract.md
+++ b/tutorials/token/create-and-transfer-an-nft-using-a-solidity-contract.md
@@ -11,6 +11,8 @@ Besides creating NFTs using Hedera SDK, you can use a Solidity Contract to creat
* FeeHelper.sol
* KeyHelper.sol
+***
+
## Prerequisites
We recommend you complete the following introduction to get a basic understanding of Hedera transactions. This example does not build upon the previous examples.
@@ -24,6 +26,8 @@ If you are interested in creating, minting, and transferring NFTs using Hedera S
In this example, you will set gas for smart contract transactions multiple times. If you don't have enough gas you will receive an`INSUFFICIENT_GAS` response. If you set the value too high you will be refunded a maximum of 20% of the amount that was set for the transaction.
{% endhint %}
+***
+
## 1. Create an “NFT Creator” Smart Contract
You can find an NFTCreator Solidity contract sample below with the contract bytecode obtained by compiling the solidity contract using [Remix IDE](https://remix.ethereum.org/). If you are not familiar with Solidity, you can take a look at the docs [here](https://docs.soliditylang.org/en/v0.8.14/).
@@ -411,6 +415,8 @@ fmt.Printf("Minted NFT with serial: %v\n", serial)
{% endtab %}
{% endtabs %}
+***
+
## 5. Execute the Contract to Transfer the NFT
The NFT is minted to the contract address because the contract is the treasury for the token. Now transfer the NFT to another account or contract address. In this example, you will transfer the NFT to Alice. For the transfer, you must specify the token address and NFT serial number.
@@ -505,6 +511,8 @@ fmt.Printf("Transfer status: %v\n", transferRecord.Status)
{% endtab %}
{% endtabs %}
+***
+
## Code Check ✅
@@ -978,3 +986,7 @@ func main() {
```
+
+{% hint style="info" %}
+Have a question? [Ask it on StackOverflow](https://stackoverflow.com/questions/tagged/hedera-hashgraph)
+{% endhint %}
diff --git a/tutorials/token/create-and-transfer-your-first-fungible-token.md b/tutorials/token/create-and-transfer-your-first-fungible-token.md
index 227fffef934a..e238d77b82f4 100644
--- a/tutorials/token/create-and-transfer-your-first-fungible-token.md
+++ b/tutorials/token/create-and-transfer-your-first-fungible-token.md
@@ -4,11 +4,16 @@
Fungible tokens share a single set of properties and have interchangeable value with one another. Use cases for fungible tokens include applications like stablecoins, in-game rewards systems, crypto tokens, loyalty program points, and much more.
+***
+
## Prerequisites
We recommend you complete the following introduction to get a basic understanding of Hedera transactions. This example does not build upon the previous examples.
-
+* Get a [Hedera testnet account](../../getting-started/introduction.md).
+* Set up your environment [here](../../getting-started/environment-set-up.md).
+
+***
## 1. Create a Fungible Token
@@ -113,6 +118,8 @@ fmt.Println("Created fungible token with token ID", tokenId)
{% endtab %}
{% endtabs %}
+***
+
## 2. Associate User Accounts with Token
Before an account that is not the treasury for a token can receive or send this specific token ID, the account must become “associated” with the token.
@@ -181,6 +188,8 @@ fmt.Println("Non-fungible token association with Alice's account:", associateAli
{% endtab %}
{% endtabs %}
+***
+
## 3. Transfer the Token
Now, transfer 25 units of the token from the Treasury to Alice and check the account balances before and after the transfer.
@@ -289,6 +298,8 @@ gofmt.Println("Alice's balance:", balanceCheckAlice2.Tokens, "units of token", t
{% endtab %}
{% endtabs %}
+***
+
## Code Check ✅
diff --git a/tutorials/token/create-and-transfer-your-first-nft.md b/tutorials/token/create-and-transfer-your-first-nft.md
index 45be33726a3c..7bac905cfa0c 100644
--- a/tutorials/token/create-and-transfer-your-first-nft.md
+++ b/tutorials/token/create-and-transfer-your-first-nft.md
@@ -4,11 +4,16 @@
Using the Hedera Token Service, you can create non-fungible tokens (NFTs). NFTs are uniquely identifiable. On the Hedera network, the token ID represents a collection of NFTs of the same class, and the serial number of each token uniquely identifies each NFT in the class.
+***
+
## Prerequisites
We recommend you complete the following introduction to get a basic understanding of Hedera transactions. This example does not build upon the previous examples.
-
+* Get a [Hedera testnet account](../../getting-started/introduction.md).
+* Set up your environment [here](../../getting-started/environment-set-up.md).
+
+***
## 1. Create a Non-Fungible Token (NFT)
@@ -115,6 +120,8 @@ fmt.Println("Created NFT with token ID ", tokenId)
{% endtab %}
{% endtabs %}
+***
+
## 2. Mint a New NFT
When creating an NFT, the decimals and initial supply must be set to zero. After the token is created, you mint each NFT using the token mint operation. Specifying a _supply key_ during token creation is a requirement to be able to [mint](../../sdks-and-apis/sdks/token-service/mint-a-token.md) and [burn](../../sdks-and-apis/sdks/readme-1/burn-a-token.md) tokens. The supply key is required to sign mint and burn transactions.
@@ -348,6 +355,8 @@ func executeWithRetry(fn func() error) error {
{% endtab %}
{% endtabs %}
+***
+
## 3. Associate User Accounts with the NFT
Before an account that is not the treasury for a token can receive or send this specific token ID, the account must become “associated” with the token. To associate a token to an account the account owner must sign the associate transaction.
@@ -418,6 +427,8 @@ fmt.Println("NFT association with Alice's account:", associateAliceRx.Status)
{% endtab %}
{% endtabs %}
+***
+
## 4. Transfer the NFT
Now, transfer the NFT and check the account balances before and after the send! After the transfer you should expect to the NFT to be removed from the treasury account and available in Alice's account. The treasury account key has to sign the transfer transaction to authorize the transfer to Alice's account.
@@ -517,6 +528,8 @@ fmt.Println("Alice's balance:", balanceCheckAlice2.Tokens, "NFTs of ID", tokenId
{% endtab %}
{% endtabs %}
+***
+
## Code Check ✅
diff --git a/tutorials/token/structure-your-token-metadata-using-json-schema-v2.md b/tutorials/token/structure-your-token-metadata-using-json-schema-v2.md
index cafff27a247b..3a79b1004bb4 100644
--- a/tutorials/token/structure-your-token-metadata-using-json-schema-v2.md
+++ b/tutorials/token/structure-your-token-metadata-using-json-schema-v2.md
@@ -6,7 +6,7 @@ When you create a new fungible or non-fungible token, you have the ability to ad
Therefore, Hedera has developed the ["Token Metadata JSON Schema V2](https://github.com/hashgraph/hedera-improvement-proposal/blob/main/HIP/hip-412.md#reference-implementation)" for developers and creators who want to structure their metadata in an organized way. The biggest benefit of using this community-accepted standard is that most of the tooling on the Hedera network can scrape and interpret your metadata, like NFT explorers listing rarity attributes based on your metadata.
-
+***
## Prerequisites
@@ -20,6 +20,17 @@ We recommend you complete one of the two tutorials below that teach you how to c
[create-and-transfer-your-first-fungible-token.md](create-and-transfer-your-first-fungible-token.md)
{% endcontent-ref %}
+***
+
+## Table of Contents
+
+1. [Connect Metadata](structure-your-token-metadata-using-json-schema-v2.md#how-do-you-connect-metadata-to-a-token)
+2. [Metadata Schema](structure-your-token-metadata-using-json-schema-v2.md#what-does-the-token-metadata-json-schema-v2-look-like)
+3. [Verify Metadata](structure-your-token-metadata-using-json-schema-v2.md#how-to-verify-your-token-metadata-is-correct)
+4. [Video Tutorial](structure-your-token-metadata-using-json-schema-v2.md#want-to-learn-more-about-token-metadata)
+
+***
+
## How do you connect metadata to a token?
It's essential to understand that the token metadata JSON schema V2 requires you to store metadata using a storage solution, centralized or decentralized, such as IPFS or Arweave.
@@ -67,6 +78,8 @@ mintTx, err := hedera.NewTokenMintTransaction().
{% endtab %}
{% endtabs %}
+***
+
## What does the Token Metadata JSON schema V2 look like?
First of all, you can find the full reference implementation of this JSON schema here:
@@ -311,6 +324,8 @@ This is what a full Token Metadata JSON Schema V2 specification looks like.
{% endtab %}
{% endtabs %}
+***
+
## How to verify your token metadata is correct?
When you create token metadata for the first time, you want to verify your metadata against the Token Metadata JSON Schema V2. To help you in this, Hedera has created an [NFT utilities SDK](https://github.com/hashgraph/hedera-nft-utilities#token-metadata-validator) **(only for JavaScript)** to verify your metadata against the JSON Schema V2.
@@ -357,6 +372,8 @@ The package will return errors and warnings using the below interface. This snip
}
```
+***
+
## Want to learn more about token metadata?
Here's a video that talks about the importance of structuring your token metadata and how to do it according to Token Metadata JSON Schema V2.