Solidity, Hardhat, React.js Deployment using Hardhat Ignition Full Setup and Deployment Steps
- Create a React App npx create-react-app .
- Install Dependencies npm install express hardhat ethers dotenv @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-ignition
- Initialize Hardhat npx hardhat init
- Set Up Environment Variables Create a .env file in the root directory and add: PROVIDER_URL=https://rpc.ankr.com/fantom_testnet PRIVATE_KEY=***** # Your MetaMask private key with Fantom balance
• Get Fantom balance : https://faucet.fantom.network/ • Add Fantom testnet to MetaMask : https://fantom-testnet.publicnode.com 5. Configure Hardhat Update hardhat.config.js:
require("@nomicfoundation/hardhat-toolbox"); require("@nomicfoundation/hardhat-ignition"); require("dotenv").config();
module.exports = {
solidity: "0.8.24",
networks: {
fantomtest: {
url: process.env.PROVIDER_URL,
accounts: [0x${process.env.PRIVATE_KEY}
]
}
}
};
- Create the Smart Contract Create contracts/Apple.sol: // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24;
contract Apple { string public myCity = "Mardin"; } 7. Create Ignition Module Create ignition/modules/Apple.js:
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");
module.exports = buildModule("AppleModule", (m) => { const appleContract = m.contract("Apple", []); return { appleContract }; });
- Compile the Contract npx hardhat compile
- Deploy the Contract using Ignition npx hardhat ignition deploy ignition/modules/Apple.js --network fantomtest
- Update React App with Contract Information Create src/AddressABI/contractABI.js:
export const contractABI = [ { "constant": true, "inputs": [], "name": "myCity", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" } ];
Create src/AddressABI/contractAddress.js: JavaScript export const contractAddress = "your_deployed_contract_address"; // Replace with your deployed contract address
- Update the React Component Update src/components/Main.js:
import React, { useEffect, useState } from 'react'; import { ethers } from 'ethers'; import { contractABI } from '../AddressABI/contractABI'; import { contractAddress } from '../AddressABI/contractAddress';
function Main() { const [account, setAccount] = useState(''); const [city, setCity] = useState(''); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [requestInProgress, setRequestInProgress] = useState(false);
useEffect(() => { const initialize = async () => { try { if (window.ethereum) { if (!requestInProgress) { setRequestInProgress(true);
try {
// Check if accounts are already connected
const accounts = await window.ethereum.request({ method: 'eth_accounts' });
if (accounts.length === 0) {
// Request user accounts if not already connected
await window.ethereum.request({ method: 'eth_requestAccounts' });
const newAccounts = await window.ethereum.request({ method: 'eth_accounts' });
setAccount(newAccounts[0]);
} else {
setAccount(accounts[0]);
}
// Connect to the smart contract
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const contractApple = new ethers.Contract(contractAddress, contractABI, signer);
const myData = await contractApple.myCity();
setCity(myData);
} catch (err) {
console.error('Error:', err);
if (err.code === -32002) {
setError('Please log in to Metamask.');
} else {
setError(`Error: ${err.message}`);
}
} finally {
setRequestInProgress(false);
}
}
} else {
setError('Metamask is not installed. Please install Metamask and try again.');
}
} catch (err) {
console.error('Unexpected error:', err);
setError('An unexpected error occurred.');
} finally {
setLoading(false);
}
};
initialize();
}, [requestInProgress]);
if (loading) { return
if (error) { return
return (
Connected Account: {account}
City: {city}
export default Main;
- Run the React App npm start