đˇCreate Your First dAPP using Hardhat
Last updated
Last updated
Prerequisites
Hardhat projects are Node.js
projects with the hardhat
package installed and a hardhat.config.js
file.
Download hardhat
After the installation is successful, next, create a simple Hardhat project. Run the following commands:
Letâs choose create a JavaScript
or TypeScript
project. We recommend choosing TypeScript
, but if youâre not familiar with it, simply select JavaScript
.
Select Create a JavaScript project
, a simple project creation wizard will ask you some questions. After that, the wizard will create some directories and files and install the necessary dependencies. The most important of these dependencies is the Hardhat Toolbox, a plugin that bundles all the things you need to start working with Hardhat.
The initialized project has the following structure:
These are the default paths for a Hardhat project.
contracts/
is where the source files for your contracts should be.
ignition/modules/
is where the Ignition modules that handle contract deployments should be.
test/
is where your tests should go.
hardhat.config.js
is used for project configuration, such as blockchain network settings, contract compilation version settings, and more.
Install Sight Oracle and openzeppelin dependency.
In the src directory, create a new file named Example.sol
, and copy the example contract code below into contracts/Example.sol
.
Contract Initialization:
The Example
contract imports the necessary modules from the Sight Oracle package.
The contract uses the RequestBuilder
library to construct requests and the ResponseResolver
library to interpret the responses.
Constructor:
The constructor initializes the contract with the address of the Sight Oracle. This address is used to send requests and handle callbacks.
makeRequest Function:
This function initiates a new request to the Sight Oracle.
A new request is created using RequestBuilder.newRequest
, specifying the sender, the number of steps in the computation, the address to which the callback should be sent, and the callback function.
The rand
function is called to generate a random encrypted value and store it in the Sight Network.
The send
function sends the request to the Sight Oracle.
callback Function:
This function is called by the Sight Oracle once the computation is complete.
It decodes the returned value using the ResponseResolver
and stores the encrypted target value in the _target
variable.
Modifiers:
onlyOracle
: Ensures that only the Sight Oracle can call the callback
function.
View Function:
getLatestReqId
: Retrieves the request ID of the most recent request sent to the Oracle
.
getTarget
: Retrieves the target value of the most recent request.
To compile Example
contracts in your Hardhat project, use the built-in compile
task:
After a successful compilation, some new files will be generated in our project directory. The cache/
directory contains cache files. The artifacts/
directoryâs build-info
folder stores information about the build process. The artifacts/contracts
folder contains the ABI interface information for each compiled contract.
Create a .env
file in the root directory and set the following environment variables:
SEPOLIA_ORACLE_CONTRACT_ADDRESS
is the Oracle address we have deployed on the Sepolia test network.
If you donât have a Sepolia RPC yet, you can click here to require one.
Note: You can get the
private key
through MetaMask by going to Account Details => Export Private Key (Please use a test wallet, as leaking the private key poses a risk of account theft!).
network configuration
Add the following code to the hardhat.config.js
file:
Explanation:
The first three lines import the necessary dependencies:
@nomicfoundation/hardhat-toolbox
is the toolkit recommended by Hardhat officially.
To use .env
environment variables, you must first install the dotenv
dependency and then import it using require("dotenv").config()
in hardhat.config.js
.
hardhat-deploy
is a powerful deployment plugin for Hardhat that provides a more structured and repeatable way to deploy smart contracts. Click here to learn more.
This code sets the default network to the hardhat
local simulation network, and we also additionally configure the sepolia
network:
accounts
can be an array of multiple private keys, used for blockchain access and interaction.
chainId
is a unique ID for the Sepolia test network, used to identify the network.
This section defines an account named deployer
, which by default uses the first account (index 0) from the account list.
Create a file named deploy/deploy-example.js
in the root directory.
getNamedAccounts
is a function used to retrieve named accounts (such as deployer), which are typically specified in the Hardhat configuration file.
deployments
provides various deployment-related functionalities (like the deploy
function), which can be used to deploy contracts and record deployment information.
This code use the address of the Oracle contract as a parameter for the Example contract. deploy()
function is used to deploy contracts, where the first parameter is the name of the contract, which must already exist in the project. The second parameter is an object, and its properties are as follows:
from: Specifies which account to use for deploying the contract.
args: []: The constructor arguments for the contract.
log: Indicates whether to print deployment logs.
waitConfirmations: Waits for 1 block confirmation to ensure the deployment is on-chain.
Then execute hardhat deploy to carry out the deployment.
Wait for about a minute, and you should see the printed information as below. Congratulations! You have successfully deployed a Example
contracts on the Sepolia test network in Hardhat!
In this section, weâll using Hardhat Ignition to deploy a smart contract. Ignition is a deployment manager provided by Hardhat that simplifies contract deployment and configuration.
You can copy this code in /ignition/modules/Example.js
.
Explanation
buildModule: The first aspect to note is that modules are created by calling the buildModule
function, which requires a module ID and a callback function. Our module will be identified as "ExampleModule"
.
m: The m
parameter being passed into the callback is an instance of a ModuleBuilder
, which is an object with methods to define and configure your smart contract instances.
m.contract("Example", [oracleContractAddress]): Deploys the Example
contract and passes the Oracle address as a constructor parameter.
m.call(Example, "makeRequest"): It will invoke the makeRequest
function within the Example contract.
Run the deployment script
Then you will see the following output information.
Congratulations, you have successfully deployed the contract and sent a request to the Oracle.