Using Hardhat
Hardhat is a comprehensive Ethereum development tool that simplifies the process of deploying, testing, and debugging smart contracts. It's designed to offer developers a seamless experience when working with Solidity contracts.
Prerequisites
Software
Node v18+, can be downloaded Here
Getting Started with Hardhat. More Information. These directions demonstrate using npm commands to create a project and add its dependencies.
_10mkdir hardhat-example_10cd hardhat-example_10_10npm init_10_10npm install --save-dev hardhat_10_10npx hardhat init
Fund Your Wallet
Navigate to the Crescendo Previewnet Faucet. Paste in your wallet address to get receive $FLOW. This will allow your wallet address to deploy smart contracts.
Deploying a Smart Contract using Hardhat
This section is dedicated to guiding you through deploying smart contracts on the Flow EVM network using Hardhat.
Configuration
Make sure to add FlowEVM network to 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.sol under 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 new file getGreeting.ts in
scripts
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 HelloWorld 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 new script
updateGreeting.ts
file 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
- 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
Coming Soon
- Comprehensive Guides: Step-by-step tutorials on deploying various types of smart contracts, including NFTs (ERC-721), using Hardhat on the FlowEVM 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.