- Node.JS for creating DApp(De-centralized application)
- HardHat for creating local blockchain node
- Metamask wallet extension for connecting to the local blockchain node
-
create react app
npx create-react-app react-dapp
-
install npm dependency packages
- Ethers - Node.JS library for interacting with the Ethereum blockchain
- Hardhat - for creating local blockchain node
npm install ethers hardhat @nomiclabs/hardhat-waffle \ ethereum-waffle chai \ @nomiclabs/hardhat-ethers
-
create hardhat configuration file
npx hardhat
- Select "Create a basic sample project"
- Install the dependencies when prompted
- This will create a
hardhat.config.jsfile in the root directory
-
add artifacts and network conf in hardhat.config.js
-
create a local blockchain node
npx hardhat node
-
add hardhat integration with metamask. Specify the localhost network in metamask by specifying
- RPC URL as
http://localhost:8545 - Chain ID as
1337configured inhardhat.config.jsfile - Name as
Hardhat Local Node
- RPC URL as
-
create a sample contract
- Create a
contractsdirectory in the root directory - Create a
Greeting.solfile in thecontractsdirectory - Add the following code to file:
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; import "hardhat/console.sol"; // to use console logging in Hardhat contract Greeter { string private greeting; constructor(string memory _greeting) { console.log("Deploying a Greeter with greeting:", _greeting); greeting = _greeting; } function greet() public view returns (string memory) { return greeting; } function setGreeting(string memory _greeting) public { console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); greeting = _greeting; } }
- Create a
-
compile the contract
npx hardhat compile. This will create asrc/artifactsdirectory in the root directory with the compiled contracts inartifacts/contractsdirectory, including the bytecode. -
Add testAccount in metamask using private key. This should display the test account balance in metamask. This will require public key of the reciever bank. Copy it from the metamask.
-
You can try sending from your newly created/imported account to another TEST account in metamask. This will though some warnings/errors in hardhat console like-
eth_call WARNING: Calling an account which is not a contract From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 To: 0x5b07003baf157b988b853ea80c2e75e7f18743c9 eth_call WARNING: Calling an account which is not a contract From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 To: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 eth_call WARNING: Calling an account which is not a contract From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 To: 0x5b07003baf157b988b853ea80c2e75e7f18743c9 eth_call WARNING: Calling an account which is not a contract From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 To: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 eth_call WARNING: Calling an account which is not a contract From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 To: 0x5b07003baf157b988b853ea80c2e75e7f18743c9 eth_call WARNING: Calling an account which is not a contract From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 To: 0x5b07003baf157b988b853ea80c2e75e7f18743c9 eth_call WARNING: Calling an account which is not a contract From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 To: 0x5b07003baf157b988b853ea80c2e75e7f18743c9 eth_call WARNING: Calling an account which is not a contract From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 To: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 eth_call WARNING: Calling an account which is not a contract From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 To: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 eth_blockNumber (4) eth_getTransactionCount eth_sendRawTransaction Transaction: 0x41d5e8ba2d801f6d73db5d11676d30fd22f2cade73717457ac3bca1cd42d47fc From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 To: 0x5b07003baf157b988b853ea80c2e75e7f18743c9 Value: 1. ETH Gas used: 21000 of 21000 Block #1: 0x9cd7ebc0b7e52e6bd08fb6b9fd755b73de177ce6a15de33fbc3b9c187caf558e
-
Create a
scriptsdirectory in the root directory -
Create a
deploy.jsfile in thescriptsdirectory -
Add the following code to the
deploy.jsfile:// require the Hardhat Runtime Environment explicitly // This is optional when running scripts with `npx hardhat run <script>` // but useful for running the script in a standalone fashion // or testing the script. const hre = require("hardhat"); async function main() { // hardhat always run the compile task(byte-code) when running a script with its cli. // If you want to run the compile task manually, you can use `await hre.run('compile');` // get the contract to deploy const Greeter = await hre.ethers.getContractFactory("Greeter"); const greeter = await Greeter.deploy("Hello, Hardhat!"); await greeter.deployed(); console.log("Greeter deployed to:", greeter.address); } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
-
Run the deploy script
npx hardhat run scripts/deploy.js --network localhost
- This will deploy the contract to the local blockchain node and display the contract address in the console.
- This should display the following output in the console:
Greeter deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
eth_sendTransaction Contract deployment: Greeter Contract address: 0x5fbdb2315678afecb367f032d93f642f64180aa3 Transaction: 0x73954d0f2edc6bcbb429d8470204714db70f4e61cfd380ebf8100d4e3c84a223 From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 Value: 0 ETH Gas used: 588080 of 588080 Block #1: 0x411a8c838a866c4fa03df37372afeeec9f63dc459e63765206346d799a132b5b console.log: Deploying a Greeter with greeting: Hello, Hardhat! eth_chainId
- Keep track of Greeter contract address. ex: Here
0x5fbdb2315678afecb367f032d93f642f64180aa3 - This deployment will be required every time node starts. So, you can create a script to automate this process.
-
Edit the
src/App.jsfile in thereact-dappdirectory -
Add the following code to the
App.jsfile:import logo from './logo.svg'; import './App.css'; import {useState} from 'react'; import {ethers} from 'ethers'; // acts like backend for the dapp import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'; const greeterAddress = "0x5fbdb2315678afecb367f032d93f642f64180aa3"; // replace with your deployed contract address function App() { const [greetingState, setGreetingValueState] = useState(); async function requestAccount() { await window.ethereum.request({ method: 'eth_requestAccounts' }); } async function fetchGreeting() { if (typeof window.ethereum !== 'undefined') { const provider = new ethers.providers.Web3Provider(window.ethereum); const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider); try { const data = await contract.greet(); console.log('data: ', data); } catch (err) { console.error("Error fetching greeting:", err); } } else { console.log("Ethereum object not found. Install MetaMask."); } } async function setGreeting() { if (!greetingState) return; if (typeof window.ethereum !== 'undefined') { await requestAccount(); const provider = new ethers.providers.Web3Provider(window.ethereum); const signer = provider.getSigner(); // get the signer to sign transactions const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer); try { const transaction = await contract.setGreeting(greetingState); await transaction.wait(); console.log('Transaction successful:', transaction); await fetchGreeting() } catch (err) { console.error("Error setting greeting:", err); } } else { console.log("Ethereum object not found. Install MetaMask."); } } return ( <div className="App"> <header className="App-header"> <button onClick={fetchGreeting}>Fetch Greeting</button> <button onClick={setGreeting}>Set Greeting</button> <input onChange={e=> setGreetingValueState(e.target.value)} placeholder="Set greeting" /> </header> </div> ); } export default App;
-
Start the React app
npm start
This will start the React app on
http://localhost:3000where you can interact with the contract. -
Open the React app in your browser and interact with the contract using the buttons and input field.
- Click on "Fetch Greeting" to fetch the current greeting from the contract.
- Enter a new greeting in the input field and click on "Set Greeting" to set a new greeting in the contract.
- You should see the greeting being updated in the console and in the contract state.
-
Create a Token contract for enabling exchange medium.
- Create a
Token.solfile in thecontractsdirectory - Add the Token contract and required methods to file:
pragma solidity ^0.8.0; import "hardhat/console.sol"; contract Token { string public name = "Recluze token"; string public symbol = "REC"; uint public totalSupply = 1000; mapping(address => uint) balances; constructor() { // assign all initial tokens to the contract's creator balances[msg.sender] = totalSupply; } function transfer(address to, uint amount) external { // ensure the sender has enough tokens to send require(balances[msg.sender] >= amount, "Insufficient tokens"); // decrease the balance of the sender from the lookup table balances[msg.sender] -= amount; // increase the balance of the recipient balances[to] += amount; } function balanceOf(address account) external view returns(uint) { return balances[account]; } }
- Compile the contract
npx hardhat compile
- Create a
-
Update scripts/deploy.js to deploy Token contract
// get the Token contract to deploy const Token = await hre.ethers.getContractFactory("Token"); const token = await Token.deploy(); await token.deployed(); console.log("Token deployed to:", token.address);
-
Run the deploy script
npx hardhat run scripts/deploy.js --network localhost Greeter deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 Token deployed to: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
-
Add the newly created token(s) to wallet:
- Open metamask and select "Import tokens"
- Enter the Token contract address displayed in the console after deployment. ex: Here
0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 - Click on "Add Custom Token"
- Click on "Import Tokens"
- This should display the token balance in metamask
-
You can now send tokens from one account to another using metamask.