Using Hardhat
Hardhat is an Ethereum development tool designed to facilitate the deployment, testing, and debugging of smart contracts. It provides a streamlined experience for developers working with Solidity contracts.
Prerequisites
Software
Node v18 or higher, available for download here.
For those new to Hardhat, we recommend exploring the official documentation to get acquainted. The following instructions utilize npm
to initialize a project and install dependencies:
_10mkdir hardhat-example_10cd hardhat-example_10_10npm init_10_10npm install --save-dev hardhat_10_10npx hardhat init
Fund Your Wallet
To deploy smart contracts, ensure your wallet has $FLOW. Obtain funds by navigating to the Flow Previewnet Faucet and entering your wallet address.
Deploying a Smart Contract with Hardhat
This section guides you through the process of deploying smart contracts on the Flow network using Hardhat.
Configuration
First, incorporate the Previewnet network into your hardhat.config.ts
:
_19_19require('dotenv').config()_19import "@nomiclabs/hardhat-ethers";_19_19import { HardhatUserConfig } from "hardhat/config";_19_19const config: HardhatUserConfig = {_19 solidity: "0.8.19",_19 networks: {_19 previewNet: {_19 url: "https://previewnet.evm.nodes.onflow.org",_19 accounts: [`<PRIVATE_KEY>`],_19 gas: 500000, // Example gas limit_19 }_19 }_19};_19_19_19export default config;
To keep this example straightforward, we've included the account's private key directly in hardhat.config.ts
. However, it is crucial to avoid committing private keys to your Git repository for security reasons. Instead, opt for using environment variables for safer handling of sensitive information.
Deploying HelloWorld Smart Contract
HelloWorld Smart Contract
_25// SPDX-License-Identifier: MIT_25pragma solidity ^0.8.0;_25_25contract HelloWorld {_25 // Declare a public field of type string._25 string public greeting;_25_25 // Constructor to initialize the greeting._25 // In Solidity, the constructor is defined with the "constructor" keyword._25 constructor() {_25 greeting = "Hello, World!";_25 }_25_25 // Public function to change the greeting._25 // The "public" keyword makes the function accessible from outside the contract._25 function changeGreeting(string memory newGreeting) public {_25 greeting = newGreeting;_25 }_25_25 // Public function that returns the greeting._25 // In Solidity, explicit return types are declared._25 function hello() public view returns (string memory) {_25 return greeting;_25 }_25}
Deploying:
- Create a file named
HelloWorld.so
lunder
contracts` directory. - Add above
HelloWorld.sol
contract code to new file. - Create a
deploy.ts
file inscripts
directory. - Paste in the following TypeScript code.
_15import { ethers } from "hardhat";_15_15async function main() {_15 const HelloWorld = await ethers.getContractFactory("HelloWorld");_15 console.log("Deploying HelloWorld...")_15 const helloWorld = await HelloWorld.deploy();_15 console.log("HelloWorld address:", helloWorld.address);_15}_15_15main()_15 .then(() => process.exit(0))_15 .catch((error) => {_15 console.error(error);_15 process.exit(1);_15 });
- Run
npx hardhat run scripts/deploy.ts --network previewNet
in the project root. - Get the deployed contract
address
. This address will be used in other scripts.
Output should look like this:
_10❯ npx hardhat run scripts/deploy.ts --network previewNet_10Deploying HelloWorld..._10HelloWorld address: 0x3Fe94f43Fb5CdB8268A801f274521a07F7b99dfb
Get HelloWorld contract Greeting
Get the Greeting from the deployed HelloWorld smart contract.
_19import { ethers } from "hardhat";_19import HelloWorldABI from "../contracts/HelloWorldABI.json"_19_19async function main() {_19 // Replace with your contract's address_19 const contractAddress = "0x3Fe94f43Fb5CdB8268A801f274521a07F7b99dfb";_19 // Get hardhat provider_19 const provider = ethers.provider;_19 // Create a new contract instance_19 const helloWorldContract = new ethers.Contract(contractAddress, HelloWorldABI, provider);_19 // Call the greeting function_19 const greeting = await helloWorldContract.hello();_19 console.log("The greeting is:", greeting);_19}_19_19main().catch((error) => {_19 console.error(error);_19 process.exit(1);_19});
Steps:
- Create a
getGreeting.ts
file in thescripts
directory. - Paste contents of script above. Make sure to update the contract address with the one from deployment in earlier step.
- Call script to get the greeting,
npx hardhat run scripts/getGreeting.ts --network previewNet
- The output should be as follows:
_10❯ npx hardhat run scripts/getGreeting.ts --network previewNet_10The greeting is: Hello, World!
Update Greeting on HelloWorld Smart Contract
_34import HelloWorldABI from "../contracts/HelloWorldABI.json"_34import { ethers } from "hardhat";_34_34async function main() {_34 const contractAddress = "0x3Fe94f43Fb5CdB8268A801f274521a07F7b99dfb";_34_34 const newGreeting = process.env.NEW_GREETING;_34 if (!newGreeting) {_34 console.error("Please set the NEW_GREETING environment variable.");_34 process.exit(1);_34 }_34_34 // Signer to send the transaction (e.g., the first account from the hardhat node)_34 const [signer] = await ethers.getSigners();_34_34 // Contract instance with signer_34 const helloWorldContract = new ethers.Contract(contractAddress, HelloWorldABI, signer);_34_34 console.log("The greeting is:", await helloWorldContract.hello());_34_34 // Create and send the transaction_34 const tx = await helloWorldContract.changeGreeting(newGreeting);_34 console.log("Transaction hash:", tx.hash);_34_34 // Wait for the transaction to be mined_34 await tx.wait().catch((error: Error) => {});_34 console.log("Greeting updated successfully!");_34 console.log("The greeting is:", await helloWorldContract.hello());_34}_34_34main().catch((error) => {_34 console.error(error);_34 process.exit(1);_34});
Next, we'll add a script to update the greeting and log it. Here are the steps to follow:
- Create an
updateGreeting.ts
script in thescripts
directory. - Paste in the TypeScript above, Make sure to update the contract address with the one from deployment in earlier step.
- Call the new script,
NEW_GREETING='Howdy!' npx hardhat run ./scripts/updateGreeting.ts --network previewNet
- The output should be
_10❯ NEW_GREETING='Howdy!' npx hardhat run ./scripts/updateGreeting.ts --network previewNet_10The greeting is: Hello, World!_10Transaction hash: 0x03136298875d405e0814f54308390e73246e4e8b4502022c657f04f3985e0906_10Greeting updated successfully!_10The greeting is: Howdy!
Flow EVM Block explorer
Coming Soon
- Comprehensive Guides: Step-by-step tutorials on deploying various types of smart contracts, including NFTs (ERC-721), using Hardhat on the Flow network.
- Requirements: Detailed prerequisites for using Hardhat with FlowEVM, including Node.js setup, wallet preparation, and obtaining testnet FLOW for gas fees.
- Verification and Interaction: Steps to verify your smart contracts on FlowEVM and interact with them using tools like Flowdiver.
Stay tuned for updates and feel free to check back soon for the full guide.