{"id":2357,"date":"2022-01-26T13:03:21","date_gmt":"2022-01-26T13:03:21","guid":{"rendered":"https:\/\/lvboard.infostore.in.ua\/?p=2357"},"modified":"2022-01-26T13:03:21","modified_gmt":"2022-01-26T13:03:21","slug":"the-complete-guide-to-full-stack-ethereum-development","status":"publish","type":"post","link":"https:\/\/lvboard.infostore.in.ua\/?p=2357","title":{"rendered":"The Complete Guide to Full Stack Ethereum Development"},"content":{"rendered":"\n<p>In this article, you&#8217;ll learn how to build full stack dApps with React, Ethers.js, Solidity, and Hardhat.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>You can find the code for this project <a href=\"https:\/\/github.com\/dabit3\/full-stack-ethereum\">here<\/a>. The video course for this tutorial is <a href=\"https:\/\/www.youtube.com\/watch?v=a0osIaAOFSE\">here<\/a>.<\/p>\n\n\n\n<p>I recently joined <a href=\"https:\/\/twitter.com\/edgeandnode\">Edge &amp; Node<\/a> as a Developer Relations Engineer and have been diving deeper into smart contract development with Ethereum. I have settled upon what I think is the best stack for building full stack dApps with Solidity:<\/p>\n\n\n\n<ul><li>Client Framework \u2013 <strong>React<\/strong><\/li><li>Ethereum development environment \u2013 <a href=\"https:\/\/hardhat.org\/\"><strong>Hardhat<\/strong><\/a><\/li><li>Ethereum Web Client Library \u2013 <a href=\"https:\/\/docs.ethers.io\/v5\/\"><strong>Ethers.js<\/strong><\/a><\/li><li>API layer \u2013 <a href=\"https:\/\/thegraph.com\/\">The Graph Protocol<\/a><\/li><\/ul>\n\n\n\n<p>But I ran into a problem while figuring all this out. While there&#8217;s fairly good documentation out there for each of these tools individually, there&#8217;s not a lot that helps you put them all together and understand how they work with each other.<\/p>\n\n\n\n<p>There are some really good boilerplates out there like <a href=\"https:\/\/github.com\/austintgriffith\/scaffold-eth\">scaffold-eth<\/a> (which also includes Ethers, Hardhat, and The Graph), but they may be too much to pick up for people just getting started.<\/p>\n\n\n\n<p>I wanted an end-to-end guide to show me how to build full stack Ethereum apps using the most up-to-date resources, libraries, and tooling.<\/p>\n\n\n\n<p>Here&#8217;s what I was interested in:<\/p>\n\n\n\n<ol><li>How to create, deploy, and test Ethereum smart contracts to local, test, and mainnet<\/li><li>How to switch between local, test, and production environments \/ networks<\/li><li>How to connect to and interact with the contracts using various environments from a front end like React, Vue, Svelte, or Angular<\/li><\/ol>\n\n\n\n<p>After spending some time figuring all of this out, I finally got going with the stack that I felt really happy with. Then I thought it would be nice to write up how to build and test a full stack Ethereum app using this stack.<\/p>\n\n\n\n<p>I hope this guide will be useful not only for other people out there who may be interested in this stack, but also for myself for future reference. This is that reference.<\/p>\n\n\n\n<h2 id=\"the-tech-we-ll-be-using\">The Tech We&#8217;ll Be Using<\/h2>\n\n\n\n<p>Let&#8217;s go over the main pieces we will be using and how they fit into the stack.<\/p>\n\n\n\n<h3 id=\"1-ethereum-development-environment\">1. Ethereum development environment<\/h3>\n\n\n\n<p>When building smart contracts, you will need a way to deploy your contracts, run tests, and debug Solidity code without dealing with live environments.<\/p>\n\n\n\n<p>You will also need a way to compile your Solidity code into code that can be run in a client-side application \u2013 in our case, a React app. We&#8217;ll learn more about how this works a little later.<\/p>\n\n\n\n<p>Hardhat is an Ethereum development environment and framework designed for full stack development, and it&#8217;s the framework that I will be using for this tutorial.<\/p>\n\n\n\n<p>Other similar tools in the ecosystem are <a href=\"https:\/\/www.trufflesuite.com\/ganache\">Ganache<\/a> and <a href=\"https:\/\/www.trufflesuite.com\/\">Truffle<\/a>.<\/p>\n\n\n\n<h3 id=\"2-ethereum-web-client-library\">2. Ethereum Web Client Library<\/h3>\n\n\n\n<p>In our React app, we will need a way to interact with the smart contracts that have been deployed. We will need a way to read for data as well as send new transactions.<\/p>\n\n\n\n<p><a href=\"https:\/\/docs.ethers.io\/v5\/\">ethers.js<\/a> aims to be a complete and compact library for interacting with the Ethereum Blockchain and its ecosystem from client-side JavaScript applications like React, Vue, Angular, or Svelte. It is the library we&#8217;ll be using.<\/p>\n\n\n\n<p>Another popular option in the ecosystem is <a href=\"https:\/\/web3js.readthedocs.io\/en\/v1.3.4\/\">web3.js<\/a><\/p>\n\n\n\n<h3 id=\"3-metamask\">3. Metamask<\/h3>\n\n\n\n<p><a href=\"https:\/\/metamask.io\/download.html\">Metamask<\/a> helps you handle account management and connecting the current user to the blockchain. MetaMask enables users to manage their accounts and keys in a few different ways while isolating them from the site context.<\/p>\n\n\n\n<p>Once a user has connected their MetaMask wallet, you as a developer can interact with the globally available Ethereum API (<code>window.ethereum<\/code>) that identifies the users of web3-compatible browsers (like MetaMask users). Whenever you request a transaction signature, MetaMask will prompt the user in a comprehensible way.<\/p>\n\n\n\n<h3 id=\"4-react\">4. React<\/h3>\n\n\n\n<p>React is a front end JavaScript library for building web applications, user interfaces, and UI components. It&#8217;s maintained by Facebook and many individual developers and companies.<\/p>\n\n\n\n<p>React and its large ecosystem of metaframeworks like <a href=\"https:\/\/nextjs.org\/\">Next.js<\/a>, <a href=\"https:\/\/www.gatsbyjs.com\/\">Gatsby<\/a>, <a href=\"https:\/\/redwoodjs.com\/\">Redwood<\/a>, <a href=\"https:\/\/blitzjs.com\/\">Blitz.js<\/a>, and others enable all types of deployment targets including traditional SPAs, static site generators, server-side rendering, and a combination of all three.<\/p>\n\n\n\n<p>React continues to seemingly dominate the front-end space, and I think will continue to do so for the near future and possibly beyond.<\/p>\n\n\n\n<h3 id=\"5-the-graph\">5. The Graph<\/h3>\n\n\n\n<p>For most apps built on blockchains like Ethereum, it&#8217;s hard and time-intensive to read data directly from the chain. So in the past, you&#8217;d see people and companies building their own centralized indexing server and serving API requests from these servers. This requires a lot of engineering and hardware resources and breaks the security properties required for decentralization.<\/p>\n\n\n\n<p>The Graph is an indexing protocol for querying blockchain data that lets you create fully decentralized applications. It solves this problem by exposing a rich GraphQL query layer that apps can consume.<\/p>\n\n\n\n<p>In this guide we won&#8217;t be building a subgraph for our app, but will do so in a future tutorial.<\/p>\n\n\n\n<h2 id=\"what-we-will-be-building\">What we will be building<\/h2>\n\n\n\n<p>In this tutorial, we&#8217;ll be building, deploying, and connecting to a couple of basic smart contracts:<\/p>\n\n\n\n<ol><li>A contract for creating and updating a message on the Ethereum blockchain<\/li><li>A contract for minting tokens, which allows the owner of the contract to send tokens to others and to read the token balances, and lets owners of the new tokens also send them to others.<\/li><\/ol>\n\n\n\n<p>We will also build out a React front end that will allow a user to:<\/p>\n\n\n\n<ol><li>Read the greeting from the contract deployed to the blockchain<\/li><li>Update the greeting<\/li><li>Send the newly minted tokens from their address to another address<\/li><li>Once someone has received tokens, allow them to also send their tokens to someone else<\/li><li>Read the token balance from the contract deployed to the blockchain<\/li><\/ol>\n\n\n\n<h3 id=\"prerequisites\">Prerequisites<\/h3>\n\n\n\n<ol><li>Node.js installed on your local machine<\/li><li><a href=\"https:\/\/metamask.io\/\">MetaMask<\/a> Chrome extension installed in your browser<\/li><\/ol>\n\n\n\n<p>You do not need to own any Ethereum for this guide as we will be using fake \/ test Ether on a test network for the entire tutorial.<\/p>\n\n\n\n<h2 id=\"how-to-get-started-with-create-react-app\">How to get started with create-react-app<\/h2>\n\n\n\n<p>To get started, we&#8217;ll create a new React application:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx create-react-app react-dapp\n<\/code><\/pre>\n\n\n\n<p>Next, change into the new directory and install <a href=\"https:\/\/docs.ethers.io\/v5\/\"><code>ethers.js<\/code><\/a> and <a href=\"https:\/\/github.com\/nomiclabs\/hardhat\"><code>hardhat<\/code><\/a> using either <strong>NPM<\/strong> or <strong>Yarn<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install ethers hardhat @nomiclabs\/hardhat-waffle ethereum-waffle chai @nomiclabs\/hardhat-ethers\n<\/code><\/pre>\n\n\n\n<h2 id=\"how-to-install-and-configure-an-ethereum-development-environment\">How to Install and Configure an Ethereum Development Environment<\/h2>\n\n\n\n<p>Next, initialize a new Ethereum Development Environment with Hardhat:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat\n\n? What do you want to do? Create a sample project\n? Hardhat project root: &lt;Choose default path&gt;\n<\/code><\/pre>\n\n\n\n<p>Now you should see the following artifacts created for you in your root directory:<\/p>\n\n\n\n<ul><li><strong>hardhat.config.js<\/strong> \u2013 The entirety of your Hardhat setup (that is, your config, plugins, and custom tasks) is contained in this file.<\/li><li><strong>scripts<\/strong> \u2013 A folder containing a script named <strong>sample-script.js<\/strong> that will deploy your smart contract when executed<\/li><li><strong>test<\/strong> \u2013 A folder containing an example testing script<\/li><li><strong>contracts<\/strong> \u2013 A folder holding an example Ethereum smart contract<\/li><\/ul>\n\n\n\n<p>Because of <a href=\"https:\/\/hardhat.org\/metamask-issue.html\">a MetaMask configuration issue<\/a>, we need to update the chain ID on our HardHat configuration to be <strong>1337<\/strong>. We also need to update the location of the <a href=\"https:\/\/hardhat.org\/guides\/compile-contracts.html#artifacts\">artifacts<\/a> for our compiled contracts so they&#8217;re in the <strong>src<\/strong> directory of our React app.<\/p>\n\n\n\n<p>To make these updates, open <strong>hardhat.config.js<\/strong> and update the <code>module.exports<\/code> to look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module.exports = {\n  solidity: \"0.8.3\",\n  paths: {\n    artifacts: '.\/src\/artifacts',\n  },\n  networks: {\n    hardhat: {\n      chainId: 1337\n    }\n  }\n};\n<\/code><\/pre>\n\n\n\n<h2 id=\"our-smart-contract\">Our smart contract<\/h2>\n\n\n\n<p>Next, let&#8217;s have a look at the example contract we have at <strong>contracts\/Greeter.sol<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\n\nimport \"hardhat\/console.sol\";\n\n\ncontract Greeter {\n  string greeting;\n\n  constructor(string memory _greeting) {\n    console.log(\"Deploying a Greeter with greeting:\", _greeting);\n    greeting = _greeting;\n  }\n\n  function greet() public view returns (string memory) {\n    return greeting;\n  }\n\n  function setGreeting(string memory _greeting) public {\n    console.log(\"Changing greeting from '%s' to '%s'\", greeting, _greeting);\n    greeting = _greeting;\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>This is a very basic smart contract. When deployed, it sets a Greeting variable and exposes a function (<code>greet<\/code>) that can be called to return the greeting.<\/p>\n\n\n\n<p>It also exposes a function that allows a user to update the greeting (<code>setGreeting<\/code>). When deployed to the Ethereum blockchain, these methods will be available for a user to interact with.<\/p>\n\n\n\n<p>Let&#8217;s make one small modification to the smart contract. Since we set the solidity version of our compiler to <code>0.8.3<\/code> in <strong>hardhat.config.js<\/strong>, let&#8217;s also be sure to update our contract to use the same version of solidity:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ contracts\/Greeter.sol\npragma solidity ^0.8.3;\n<\/code><\/pre>\n\n\n\n<h3 id=\"how-to-read-and-write-to-the-ethereum-blockchain\">How to Read and Write to the Ethereum Blockchain<\/h3>\n\n\n\n<p>There are two ways to interact with a smart contract \u2013 reading or writing \/ transactions. In our contract, <code>greet<\/code> can be considered reading, and <code>setGreeting<\/code> can be considered writing \/ transactional.<\/p>\n\n\n\n<p>When writing or initializing a transaction, you have to pay for the transaction to be written to the blockchain. To make this work, you need to pay <a href=\"https:\/\/www.investopedia.com\/terms\/g\/gas-ethereum.asp#:~:text=What%20Is%20Gas%20(Ethereum)%3F,on%20the%20Ethereum%20blockchain%20platform\">gas<\/a> which is the fee or price required to successfully conduct a transaction and execute a contract on the Ethereum blockchain.<\/p>\n\n\n\n<p>As long as you are only reading from the blockchain and not changing or updating anything, you don&#8217;t need to carry out a transaction and there will be no gas or cost to do so. The function you call is then carried out only by the node you are connected to, so you don&#8217;t need to pay any gas and the read is free.<\/p>\n\n\n\n<p>From our React app, we will interact with the smart contract using a combination of the <code>ethers.js<\/code> library, the contract address, and the <a href=\"https:\/\/docs.soliditylang.org\/en\/v0.5.3\/abi-spec.html\">ABI<\/a> that will be created from the contract by Hardhat.<\/p>\n\n\n\n<p>What is an ABI? ABI stands for application binary interface. You can think of it as the interface between your client-side application and the Ethereum blockchain where the smart contract you are going to be interacting with is deployed.<\/p>\n\n\n\n<p>ABIs are typically compiled from Solidity smart contracts by a development framework like Hardhat. You can also often find the ABIs for a smart contract on <a href=\"https:\/\/etherscan.io\/\">Etherscan<\/a><\/p>\n\n\n\n<h3 id=\"how-to-compile-the-abi\">How to Compile the ABI<\/h3>\n\n\n\n<p>Now that we have gone over the basic smart contract and know what ABIs are, let&#8217;s compile an ABI for our project.<\/p>\n\n\n\n<p>To do so, go to the command line and run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat compile\n<\/code><\/pre>\n\n\n\n<p>Now, you should see a new folder named <strong>artifacts<\/strong> in the <strong>src<\/strong> directory. The <strong>artifacts\/contracts\/Greeter.json<\/strong> file contains the ABI as one of the properties. When we need to use the ABI, we can import it from our JavaScript file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import Greeter from '.\/artifacts\/contracts\/Greeter.sol\/Greeter.json'\n<\/code><\/pre>\n\n\n\n<p>We can then reference the ABI like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>console.log(\"Greeter ABI: \", Greeter.abi)\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Note that Ethers.js also enables <a href=\"https:\/\/blog.ricmoo.com\/human-readable-contract-abis-in-ethers-js-141902f4d917\">human readable ABIs<\/a>, but will will not be going into this during this tutorial.<\/p><\/blockquote>\n\n\n\n<h3 id=\"how-to-deploy-and-use-a-local-network-blockchain\">How to Deploy and Use a Local Network \/ Blockchain<\/h3>\n\n\n\n<p>Next, let&#8217;s deploy our smart contract to a local blockchain so that we can test it out.<\/p>\n\n\n\n<p>To deploy to the local network, you first need to start the local test node. To do so, open the CLI and run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat node\n<\/code><\/pre>\n\n\n\n<p>When we run this command, you should see a list of addresses and private keys.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/e176nc82ik77hei3a48s.jpg\" alt=\"Hardhat node addresses\"\/><\/figure>\n\n\n\n<p>These are 20 test accounts and addresses created for us that we can use to deploy and test our smart contracts. Each account is also loaded up with 10,000 fake Ether. In a moment, we&#8217;ll learn how to import the test account into MetaMask so that we can use it.<\/p>\n\n\n\n<p>Next, we need to deploy the contract to the test network. First update the name of <strong>scripts\/sample-script.js<\/strong> to <strong>scripts\/deploy.js<\/strong>.<\/p>\n\n\n\n<p>Now we can run the deploy script and give a flag to the CLI that we would like to deploy to our local network:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat run scripts\/deploy.js --network localhost\n<\/code><\/pre>\n\n\n\n<p>Once this script is executed, the smart contract should be deployed to the local test network and we should be then able to start interacting with it.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>When the contract was deployed, it used the first account that was created when we started the local network.<\/p><\/blockquote>\n\n\n\n<p>If you look at the output from the CLI, you should be able to see something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Greeter deployed to: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0\n<\/code><\/pre>\n\n\n\n<p>This address is what we will use in our client application to talk to the smart contract. Keep this address available as we will need to use it when connecting to it from the client application.<\/p>\n\n\n\n<p>To send transactions to the smart contract, we will need to connect our MetaMask wallet using one of the accounts created when we ran <code>npx hardhat node<\/code>. In the list of contracts that the CLI logs out, you should see both an <strong>Account number<\/strong> as well as a <strong>Private Key<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u279c  react-defi-stack git:(main) npx hardhat node\nStarted HTTP and WebSocket JSON-RPC server at http:\/\/127.0.0.1:8545\/\n\nAccounts\n========\nAccount #0: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 (10000 ETH)\nPrivate Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80\n\n...\n<\/code><\/pre>\n\n\n\n<p>We can import this account into MetaMask in order to start using some of the fake Eth available there. To do so, first open MetaMask and update the network to be Localhost 8545:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/qnbsbcm4y1md6cwjttpx.jpg\" alt=\"MetaMask Localhost\"\/><\/figure>\n\n\n\n<p>Next, in MetaMask click on <strong>Import Account<\/strong> from the accounts menu:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/n7vbzlov869gwk9rtwl1.jpg\" alt=\"Import account\"\/><\/figure>\n\n\n\n<p>Copy then paste one of the <strong>Private Keys<\/strong> logged out by the CLI and click <strong>Import<\/strong>. Once the account is imported, you should see the Eth in the account:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/x5lob4yug3jznhy9z0qt.jpg\" alt=\"Imported account\"\/><\/figure>\n\n\n\n<p>Now that we have a deployed our smart contract and set up our account, we can start interacting with it from the React app.<\/p>\n\n\n\n<h3 id=\"how-to-connect-the-react-client\">How to Connect the React Client<\/h3>\n\n\n\n<p>In this tutorial we are not going to be worrying about building a beautiful UI with CSS and all of that \u2013 we are focused 100% on the core functionality to get you up and running. From there, you can take it and make it look good if you&#8217;d like.<\/p>\n\n\n\n<p>With that being said, let&#8217;s review the two objectives that we want from our React application:<\/p>\n\n\n\n<ol><li>Fetch the current value of <code>greeting<\/code> from the smart contract<\/li><li>Allow a user to update the value of the <code>greeting<\/code><\/li><\/ol>\n\n\n\n<p>So how do we accomplish this? Here are the things we need to do to make this happen:<\/p>\n\n\n\n<ol><li>Create an input field and some local state to manage the value of the input (to update the <code>greeting<\/code>)<\/li><li>Allow the application to connect to the user&#8217;s MetaMask account to sign transactions<\/li><li>Create functions for reading and writing to the smart contract<\/li><\/ol>\n\n\n\n<p>To do this, open <code>src\/App.js<\/code> and update it with the following code, setting the value of <code>greeterAddress<\/code> to the address of your smart contract:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import '.\/App.css';\nimport { useState } from 'react';\nimport { ethers } from 'ethers'\nimport Greeter from '.\/artifacts\/contracts\/Greeter.sol\/Greeter.json'\n\n\/\/ Update with the contract address logged out to the CLI when it was deployed \nconst greeterAddress = \"your-contract-address\"\n\nfunction App() {\n  \/\/ store greeting in local state\n  const &#91;greeting, setGreetingValue] = useState()\n\n  \/\/ request access to the user's MetaMask account\n  async function requestAccount() {\n    await window.ethereum.request({ method: 'eth_requestAccounts' });\n  }\n\n  \/\/ call the smart contract, read the current greeting value\n  async function fetchGreeting() {\n    if (typeof window.ethereum !== 'undefined') {\n      const provider = new ethers.providers.Web3Provider(window.ethereum)\n      const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)\n      try {\n        const data = await contract.greet()\n        console.log('data: ', data)\n      } catch (err) {\n        console.log(\"Error: \", err)\n      }\n    }    \n  }\n\n  \/\/ call the smart contract, send an update\n  async function setGreeting() {\n    if (!greeting) return\n    if (typeof window.ethereum !== 'undefined') {\n      await requestAccount()\n      const provider = new ethers.providers.Web3Provider(window.ethereum);\n      const signer = provider.getSigner()\n      const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)\n      const transaction = await contract.setGreeting(greeting)\n      await transaction.wait()\n      fetchGreeting()\n    }\n  }\n\n  return (\n    &lt;div className=\"App\"&gt;\n      &lt;header className=\"App-header\"&gt;\n        &lt;button onClick={fetchGreeting}&gt;Fetch Greeting&lt;\/button&gt;\n        &lt;button onClick={setGreeting}&gt;Set Greeting&lt;\/button&gt;\n        &lt;input onChange={e =&gt; setGreetingValue(e.target.value)} placeholder=\"Set greeting\" \/&gt;\n      &lt;\/header&gt;\n    &lt;\/div&gt;\n  );\n}\n\nexport default App;\n<\/code><\/pre>\n\n\n\n<p>To test it out, start the React server:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm start\n<\/code><\/pre>\n\n\n\n<p>When the app loads, you should be able to fetch the current greeting and log it out to the console. You should also be able to make updates to the greeting by signing the contract with your MetaMask wallet and spending the fake Ether.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/9a57jbzrwylr2l0rujxm.png\" alt=\"Setting and getting the greeting value\"\/><\/figure>\n\n\n\n<h3 id=\"how-to-deploy-and-use-a-live-test-network\">How to Deploy and Use a Live Test Network<\/h3>\n\n\n\n<p>There are several Ethereum test networks like Ropsten, Rinkeby, or Kovan that we can also deploy to in order to have a publicly accessible version of our contract available without having to deploy it to mainnet.<\/p>\n\n\n\n<p>In this tutorial we&#8217;ll be deploying to the <strong>Ropsten<\/strong> test network.<\/p>\n\n\n\n<p>To start off, first update your MetaMask wallet to connect to the Ropsten network.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/k85gplgp26wp58l95bhr.jpg\" alt=\"Ropsten network\"\/><\/figure>\n\n\n\n<p>Next, send yourself some test Ether to use during the rest of this tutorial by visiting <a href=\"https:\/\/faucet.ropsten.be\/\">this test faucet<\/a>.<\/p>\n\n\n\n<p>We can get access to Ropsten (or any of the other test networks) by signing up with a service like <a href=\"https:\/\/infura.io\/dashboard\/ethereum\/cbdf7c5eee8b4e2b91e76b77ffd34533\/settings\">Infura<\/a> or <a href=\"https:\/\/www.alchemyapi.io\/\">Alchemy<\/a> (I&#8217;m using Infura for this tutorial).<\/p>\n\n\n\n<p>Once you&#8217;ve created the app in Infura or Alchemy, you will be given an endpoint that looks something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;ropsten.infura.io\/v3\/your-project-id\n<\/code><\/pre>\n\n\n\n<p>Be sure to set the <strong>ALLOWLIST ETHEREUM ADDRESSES<\/strong> in the Infura or Alchemy app configuration to include the wallet address of the account you will be deploying from.<\/p>\n\n\n\n<p>To deploy to the test network we need to update our Hardhat config with some additional network information. One of the things we need to set is the private key of the wallet we will be deploying from.<\/p>\n\n\n\n<p>To get the private key, you can export it from MetaMask.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/deod3d6qix8us12t17i4.jpg\" alt=\"Export private key\"\/><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>I&#8217;d suggest not hardcoding this value in your app but instead setting it as something like an environment variable.<\/p><\/blockquote>\n\n\n\n<p>Next, add a <code>networks<\/code> property with the following configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module.exports = {\n  defaultNetwork: \"hardhat\",\n  paths: {\n    artifacts: '.\/src\/artifacts',\n  },\n  networks: {\n    hardhat: {},\n    ropsten: {\n      url: \"https:\/\/ropsten.infura.io\/v3\/your-project-id\",\n      accounts: &#91;`0x${your-private-key}`]\n    }\n  },\n  solidity: \"0.7.3\",\n};\n<\/code><\/pre>\n\n\n\n<p>To deploy, run the following script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat run scripts\/deploy.js --network ropsten\n<\/code><\/pre>\n\n\n\n<p>Once your contract is deployed you should be able to start interacting with it. You should be now able to view the live contract on <a href=\"https:\/\/ropsten.etherscan.io\/\">Etherscan Ropsten Testnet Explorer<\/a><\/p>\n\n\n\n<h2 id=\"how-to-mint-tokens\">How to Mint Tokens<\/h2>\n\n\n\n<p>One of the most common use cases of smart contracts is creating tokens. Let&#8217;s look at how we can do that. Since we know a little more about how all of this works, we&#8217;ll be going a little faster.<\/p>\n\n\n\n<p>In the main <strong>contracts<\/strong> directory, create a new file named <strong>Token.sol<\/strong>.<\/p>\n\n\n\n<p>Next, update <strong>Token.sol<\/strong> with the following smart contract:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/SPDX-License-Identifier: MIT\npragma solidity ^0.8.3;\n\nimport \"hardhat\/console.sol\";\n\ncontract Token {\n  string public name = \"Nader Dabit Token\";\n  string public symbol = \"NDT\";\n  uint public totalSupply = 1000000;\n  mapping(address =&gt; uint) balances;\n\n  constructor() {\n    balances&#91;msg.sender] = totalSupply;\n  }\n\n  function transfer(address to, uint amount) external {\n    require(balances&#91;msg.sender] &gt;= amount, \"Not enough tokens\");\n    balances&#91;msg.sender] -= amount;\n    balances&#91;to] += amount;\n  }\n\n  function balanceOf(address account) external view returns (uint) {\n    return balances&#91;account];\n  }\n}\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Note that this token contract is for demo purposes only and is not <a href=\"https:\/\/eips.ethereum.org\/EIPS\/eip-20\">ERC20<\/a>-compliant. We will be covering ERC20 tokens later.<\/p><\/blockquote>\n\n\n\n<p>This contract will create a new token called &#8220;Nader Dabit Token&#8221; and set the supply to 1000000.<\/p>\n\n\n\n<p>Next, compile this contract:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat compile\n<\/code><\/pre>\n\n\n\n<p>Now, update the deploy script at <strong>scripts\/deploy.js<\/strong> to include this new Token contract:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const hre = require(\"hardhat\");\n\nasync function main() {\n  const &#91;deployer] = await hre.ethers.getSigners();\n\n  console.log(\n    \"Deploying contracts with the account:\",\n    deployer.address\n  );\n  \n  const Greeter = await hre.ethers.getContractFactory(\"Greeter\");\n  const greeter = await Greeter.deploy(\"Hello, World!\");\n\n  const Token = await hre.ethers.getContractFactory(\"Token\");\n  const token = await Token.deploy();\n  \n  await greeter.deployed();\n  await token.deployed();\n\n  console.log(\"Greeter deployed to:\", greeter.address);\n  console.log(\"Token deployed to:\", token.address);\n}\n\nmain()\n  .then(() =&gt; process.exit(0))\n  .catch(error =&gt; {\n    console.error(error);\n    process.exit(1);\n  });\n<\/code><\/pre>\n\n\n\n<p>Now, we can deploy this new contract to the local or Ropsten network:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat run scripts\/deploy.js --network localhost\n<\/code><\/pre>\n\n\n\n<p>Once the contract is deployed, you can start sending these tokens to other addresses.<\/p>\n\n\n\n<p>To do so, let&#8217;s update the client code we will need in order to make this work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import '.\/App.css';\nimport { useState } from 'react';\nimport { ethers } from 'ethers'\nimport Greeter from '.\/artifacts\/contracts\/Greeter.sol\/Greeter.json'\nimport Token from '.\/artifacts\/contracts\/Token.sol\/Token.json'\n\nconst greeterAddress = \"your-contract-address\"\nconst tokenAddress = \"your-contract-address\"\n\nfunction App() {\n  const &#91;greeting, setGreetingValue] = useState()\n  const &#91;userAccount, setUserAccount] = useState()\n  const &#91;amount, setAmount] = useState()\n\n  async function requestAccount() {\n    await window.ethereum.request({ method: 'eth_requestAccounts' });\n  }\n\n  async function fetchGreeting() {\n    if (typeof window.ethereum !== 'undefined') {\n      const provider = new ethers.providers.Web3Provider(window.ethereum)\n      console.log({ provider })\n      const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)\n      try {\n        const data = await contract.greet()\n        console.log('data: ', data)\n      } catch (err) {\n        console.log(\"Error: \", err)\n      }\n    }    \n  }\n\n  async function getBalance() {\n    if (typeof window.ethereum !== 'undefined') {\n      const &#91;account] = await window.ethereum.request({ method: 'eth_requestAccounts' })\n      const provider = new ethers.providers.Web3Provider(window.ethereum);\n      const contract = new ethers.Contract(tokenAddress, Token.abi, provider)\n      const balance = await contract.balanceOf(account);\n      console.log(\"Balance: \", balance.toString());\n    }\n  }\n\n  async function setGreeting() {\n    if (!greeting) return\n    if (typeof window.ethereum !== 'undefined') {\n      await requestAccount()\n      const provider = new ethers.providers.Web3Provider(window.ethereum);\n      console.log({ provider })\n      const signer = provider.getSigner()\n      const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)\n      const transaction = await contract.setGreeting(greeting)\n      await transaction.wait()\n      fetchGreeting()\n    }\n  }\n\n  async function sendCoins() {\n    if (typeof window.ethereum !== 'undefined') {\n      await requestAccount()\n      const provider = new ethers.providers.Web3Provider(window.ethereum);\n      const signer = provider.getSigner();\n      const contract = new ethers.Contract(tokenAddress, Token.abi, signer);\n      const transation = await contract.transfer(userAccount, amount);\n      await transation.wait();\n      console.log(`${amount} Coins successfully sent to ${userAccount}`);\n    }\n  }\n\n  return (\n    &lt;div className=\"App\"&gt;\n      &lt;header className=\"App-header\"&gt;\n        &lt;button onClick={fetchGreeting}&gt;Fetch Greeting&lt;\/button&gt;\n        &lt;button onClick={setGreeting}&gt;Set Greeting&lt;\/button&gt;\n        &lt;input onChange={e =&gt; setGreetingValue(e.target.value)} placeholder=\"Set greeting\" \/&gt;\n\n        &lt;br \/&gt;\n        &lt;button onClick={getBalance}&gt;Get Balance&lt;\/button&gt;\n        &lt;button onClick={sendCoins}&gt;Send Coins&lt;\/button&gt;\n        &lt;input onChange={e =&gt; setUserAccount(e.target.value)} placeholder=\"Account ID\" \/&gt;\n        &lt;input onChange={e =&gt; setAmount(e.target.value)} placeholder=\"Amount\" \/&gt;\n      &lt;\/header&gt;\n    &lt;\/div&gt;\n  );\n}\n\nexport default App;\n<\/code><\/pre>\n\n\n\n<p>Next, run the app:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm start\n<\/code><\/pre>\n\n\n\n<p>We should be able to click on <strong>Get Balance<\/strong> and see that we have 1,000,000 coins in our account logged out to the console.<\/p>\n\n\n\n<p>You should also be able to view them in MetaMask by clicking on <strong>Add Token<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/0t2ip26i5d2ltjc9j2a6.jpg\" alt=\"Add token\"\/><\/figure>\n\n\n\n<p>Next click on <strong>Custom Token<\/strong> and enter the token contract address and then <strong>Add Token<\/strong>. Now the tokens should be available in your wallet:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/5op32iqbeszizri72qc0.jpg\" alt=\"NDT\"\/><\/figure>\n\n\n\n<p>Next, let&#8217;s try to send those coins to another address.<\/p>\n\n\n\n<p>To do so, copy the address of another account and send them to that address using the updated React UI. When you check the token amount, it should be equal to the original amount minus the amount you sent to the address.<\/p>\n\n\n\n<h2 id=\"how-to-build-an-erc20-token\">How to Build An ERC20 Token<\/h2>\n\n\n\n<p>The <a href=\"https:\/\/ethereum.org\/en\/developers\/docs\/standards\/tokens\/erc-20\/\">ERC20 Token Standard<\/a> defines a set of rules that apply to all ERC20 tokens which allow them to easily interact with each other. ERC20 makes it really easy for someone to mint their own tokens that will have interoperability with others on the Ethereum blockchain.<\/p>\n\n\n\n<p>Let&#8217;s look at how we can build our own token using the ERC20 standard.<\/p>\n\n\n\n<p>First, install the <a href=\"https:\/\/github.com\/OpenZeppelin\/openzeppelin-contracts\">OpenZepplin<\/a> smart contract library where we will be importing the base <code>ERC20<\/code> Token:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install @openzeppelin\/contracts\n<\/code><\/pre>\n\n\n\n<p>Next, we&#8217;ll create our token by extending (or inheriting from) the <code>ERC20<\/code> contract:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/SPDX-License-Identifier: MIT\npragma solidity ^0.8.3;\n\nimport \"@openzeppelin\/contracts\/token\/ERC20\/ERC20.sol\";\n\ncontract NDToken is ERC20 {\n    constructor(string memory name, string memory symbol) ERC20(name, symbol) {\n        _mint(msg.sender, 100000 * (10 ** 18));\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>The constructor allows you to set the token name and symbol, and the <code>_mint<\/code> function allows you to mint the tokens and set the amount.<\/p>\n\n\n\n<p>By default, ERC20 sets the number of decimals to 18, so in our <code>_mint<\/code> function we multiply 100,000 by 10 to the 18 power to mint a total of 100,000 tokens, each with 18 decimal places (similarly to how 1 Eth is made up of 10 to the 18 <a href=\"https:\/\/www.investopedia.com\/terms\/w\/wei.asp\">wei<\/a>.<\/p>\n\n\n\n<p>To deploy, we need to pass in the constructor values (<code>name<\/code> and <code>symbol<\/code>), so we might do something like this in our deploy script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const NDToken = await hre.ethers.getContractFactory(\"NDToken\");\nconst ndToken = await NDToken.deploy(\"Nader Dabit Token\", \"NDT\");\n<\/code><\/pre>\n\n\n\n<p>By extending the original ERC20 token, your token will inherit all of the following functions and functionality:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function name() public view returns (string)\nfunction symbol() public view returns (string)\nfunction decimals() public view returns (uint8)\nfunction totalSupply() public view returns (uint256)\nfunction balanceOf(address _owner) public view returns (uint256 balance)\nfunction transfer(address _to, uint256 _value) public returns (bool success)\nfunction transferFrom(address _from, address _to, uint256 _value) public returns (bool success)\nfunction approve(address _spender, uint256 _value) public returns (bool success)\nfunction allowance(address _owner, address _spender) public view returns (uint256 remaining)\n<\/code><\/pre>\n\n\n\n<p>Once deployed, you can use any of these functions to interact with the new smart contract. For another example of an ERC20 token, check out Solidity by example here: <a href=\"https:\/\/solidity-by-example.org\/app\/erc20\/\">https:\/\/solidity-by-example.org\/app\/erc20\/<\/a>.<\/p>\n\n\n\n<h2 id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>Ok, we covered a lot in this article. But for me this is kind of the bread and butter \/ core of getting started with this stack.<\/p>\n\n\n\n<p>It&#8217;s kind of what I wanted to have, not only as someone who was learning all of this stuff, but also in the future if I ever need to reference anything I may need. I hope you learned a lot.<\/p>\n\n\n\n<p>If you want to support multiple wallets in addition to MetaMask, check out <a href=\"https:\/\/github.com\/Web3Modal\/web3modal\">Web3Modal<\/a> which makes it easy to implement support for multiple providers in your app with a fairly simple and customizable configuration.<\/p>\n\n\n\n<p>In my future tutorials and guides, I&#8217;ll be diving into more complex smart contract development and also how to deploy them as <a href=\"https:\/\/thegraph.com\/docs\/define-a-subgraph\">subgraphs<\/a> to expose a GraphQL API on top of them and implement things like pagination and full text search.<\/p>\n\n\n\n<p>I&#8217;ll also be going into how to use technologies like IPFS and Web3 databases to store data in a decentralized way.<\/p>\n\n\n\n<p>In this article, you&#8217;ll learn how to build full stack dApps with React, Ethers.js, Solidity, and Hardhat.<\/p>\n\n\n\n<p>You can find the code for this project <a href=\"https:\/\/github.com\/dabit3\/full-stack-ethereum\">here<\/a>. The video course for this tutorial is <a href=\"https:\/\/www.youtube.com\/watch?v=a0osIaAOFSE\">here<\/a>.<\/p>\n\n\n\n<p>I recently joined <a href=\"https:\/\/twitter.com\/edgeandnode\">Edge &amp; Node<\/a> as a Developer Relations Engineer and have been diving deeper into smart contract development with Ethereum. I have settled upon what I think is the best stack for building full stack dApps with Solidity:<\/p>\n\n\n\n<ul><li>Client Framework \u2013 <strong>React<\/strong><\/li><li>Ethereum development environment \u2013 <a href=\"https:\/\/hardhat.org\/\"><strong>Hardhat<\/strong><\/a><\/li><li>Ethereum Web Client Library \u2013 <a href=\"https:\/\/docs.ethers.io\/v5\/\"><strong>Ethers.js<\/strong><\/a><\/li><li>API layer \u2013 <a href=\"https:\/\/thegraph.com\/\">The Graph Protocol<\/a><\/li><\/ul>\n\n\n\n<p>But I ran into a problem while figuring all this out. While there&#8217;s fairly good documentation out there for each of these tools individually, there&#8217;s not a lot that helps you put them all together and understand how they work with each other.<\/p>\n\n\n\n<p>There are some really good boilerplates out there like <a href=\"https:\/\/github.com\/austintgriffith\/scaffold-eth\">scaffold-eth<\/a> (which also includes Ethers, Hardhat, and The Graph), but they may be too much to pick up for people just getting started.<\/p>\n\n\n\n<p>I wanted an end-to-end guide to show me how to build full stack Ethereum apps using the most up-to-date resources, libraries, and tooling.<\/p>\n\n\n\n<p>Here&#8217;s what I was interested in:<\/p>\n\n\n\n<ol><li>How to create, deploy, and test Ethereum smart contracts to local, test, and mainnet<\/li><li>How to switch between local, test, and production environments \/ networks<\/li><li>How to connect to and interact with the contracts using various environments from a front end like React, Vue, Svelte, or Angular<\/li><\/ol>\n\n\n\n<p>After spending some time figuring all of this out, I finally got going with the stack that I felt really happy with. Then I thought it would be nice to write up how to build and test a full stack Ethereum app using this stack.<\/p>\n\n\n\n<p>I hope this guide will be useful not only for other people out there who may be interested in this stack, but also for myself for future reference. This is that reference.<\/p>\n\n\n\n<h2 id=\"the-tech-we-ll-be-using\">The Tech We&#8217;ll Be Using<\/h2>\n\n\n\n<p>Let&#8217;s go over the main pieces we will be using and how they fit into the stack.<\/p>\n\n\n\n<h3 id=\"1-ethereum-development-environment\">1. Ethereum development environment<\/h3>\n\n\n\n<p>When building smart contracts, you will need a way to deploy your contracts, run tests, and debug Solidity code without dealing with live environments.<\/p>\n\n\n\n<p>You will also need a way to compile your Solidity code into code that can be run in a client-side application \u2013 in our case, a React app. We&#8217;ll learn more about how this works a little later.<\/p>\n\n\n\n<p>Hardhat is an Ethereum development environment and framework designed for full stack development, and it&#8217;s the framework that I will be using for this tutorial.<\/p>\n\n\n\n<p>Other similar tools in the ecosystem are <a href=\"https:\/\/www.trufflesuite.com\/ganache\">Ganache<\/a> and <a href=\"https:\/\/www.trufflesuite.com\/\">Truffle<\/a>.<\/p>\n\n\n\n<h3 id=\"2-ethereum-web-client-library\">2. Ethereum Web Client Library<\/h3>\n\n\n\n<p>In our React app, we will need a way to interact with the smart contracts that have been deployed. We will need a way to read for data as well as send new transactions.<\/p>\n\n\n\n<p><a href=\"https:\/\/docs.ethers.io\/v5\/\">ethers.js<\/a> aims to be a complete and compact library for interacting with the Ethereum Blockchain and its ecosystem from client-side JavaScript applications like React, Vue, Angular, or Svelte. It is the library we&#8217;ll be using.<\/p>\n\n\n\n<p>Another popular option in the ecosystem is <a href=\"https:\/\/web3js.readthedocs.io\/en\/v1.3.4\/\">web3.js<\/a><\/p>\n\n\n\n<h3 id=\"3-metamask\">3. Metamask<\/h3>\n\n\n\n<p><a href=\"https:\/\/metamask.io\/download.html\">Metamask<\/a> helps you handle account management and connecting the current user to the blockchain. MetaMask enables users to manage their accounts and keys in a few different ways while isolating them from the site context.<\/p>\n\n\n\n<p>Once a user has connected their MetaMask wallet, you as a developer can interact with the globally available Ethereum API (<code>window.ethereum<\/code>) that identifies the users of web3-compatible browsers (like MetaMask users). Whenever you request a transaction signature, MetaMask will prompt the user in a comprehensible way.<\/p>\n\n\n\n<h3 id=\"4-react\">4. React<\/h3>\n\n\n\n<p>React is a front end JavaScript library for building web applications, user interfaces, and UI components. It&#8217;s maintained by Facebook and many individual developers and companies.<\/p>\n\n\n\n<p>React and its large ecosystem of metaframeworks like <a href=\"https:\/\/nextjs.org\/\">Next.js<\/a>, <a href=\"https:\/\/www.gatsbyjs.com\/\">Gatsby<\/a>, <a href=\"https:\/\/redwoodjs.com\/\">Redwood<\/a>, <a href=\"https:\/\/blitzjs.com\/\">Blitz.js<\/a>, and others enable all types of deployment targets including traditional SPAs, static site generators, server-side rendering, and a combination of all three.<\/p>\n\n\n\n<p>React continues to seemingly dominate the front-end space, and I think will continue to do so for the near future and possibly beyond.<\/p>\n\n\n\n<h3 id=\"5-the-graph\">5. The Graph<\/h3>\n\n\n\n<p>For most apps built on blockchains like Ethereum, it&#8217;s hard and time-intensive to read data directly from the chain. So in the past, you&#8217;d see people and companies building their own centralized indexing server and serving API requests from these servers. This requires a lot of engineering and hardware resources and breaks the security properties required for decentralization.<\/p>\n\n\n\n<p>The Graph is an indexing protocol for querying blockchain data that lets you create fully decentralized applications. It solves this problem by exposing a rich GraphQL query layer that apps can consume.<\/p>\n\n\n\n<p>In this guide we won&#8217;t be building a subgraph for our app, but will do so in a future tutorial.<\/p>\n\n\n\n<h2 id=\"what-we-will-be-building\">What we will be building<\/h2>\n\n\n\n<p>In this tutorial, we&#8217;ll be building, deploying, and connecting to a couple of basic smart contracts:<\/p>\n\n\n\n<ol><li>A contract for creating and updating a message on the Ethereum blockchain<\/li><li>A contract for minting tokens, which allows the owner of the contract to send tokens to others and to read the token balances, and lets owners of the new tokens also send them to others.<\/li><\/ol>\n\n\n\n<p>We will also build out a React front end that will allow a user to:<\/p>\n\n\n\n<ol><li>Read the greeting from the contract deployed to the blockchain<\/li><li>Update the greeting<\/li><li>Send the newly minted tokens from their address to another address<\/li><li>Once someone has received tokens, allow them to also send their tokens to someone else<\/li><li>Read the token balance from the contract deployed to the blockchain<\/li><\/ol>\n\n\n\n<h3 id=\"prerequisites\">Prerequisites<\/h3>\n\n\n\n<ol><li>Node.js installed on your local machine<\/li><li><a href=\"https:\/\/metamask.io\/\">MetaMask<\/a> Chrome extension installed in your browser<\/li><\/ol>\n\n\n\n<p>You do not need to own any Ethereum for this guide as we will be using fake \/ test Ether on a test network for the entire tutorial.<\/p>\n\n\n\n<h2 id=\"how-to-get-started-with-create-react-app\">How to get started with create-react-app<\/h2>\n\n\n\n<p>To get started, we&#8217;ll create a new React application:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx create-react-app react-dapp\n<\/code><\/pre>\n\n\n\n<p>Next, change into the new directory and install <a href=\"https:\/\/docs.ethers.io\/v5\/\"><code>ethers.js<\/code><\/a> and <a href=\"https:\/\/github.com\/nomiclabs\/hardhat\"><code>hardhat<\/code><\/a> using either <strong>NPM<\/strong> or <strong>Yarn<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install ethers hardhat @nomiclabs\/hardhat-waffle ethereum-waffle chai @nomiclabs\/hardhat-ethers\n<\/code><\/pre>\n\n\n\n<h2 id=\"how-to-install-and-configure-an-ethereum-development-environment\">How to Install and Configure an Ethereum Development Environment<\/h2>\n\n\n\n<p>Next, initialize a new Ethereum Development Environment with Hardhat:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat\n\n? What do you want to do? Create a sample project\n? Hardhat project root: &lt;Choose default path&gt;\n<\/code><\/pre>\n\n\n\n<p>Now you should see the following artifacts created for you in your root directory:<\/p>\n\n\n\n<ul><li><strong>hardhat.config.js<\/strong> \u2013 The entirety of your Hardhat setup (that is, your config, plugins, and custom tasks) is contained in this file.<\/li><li><strong>scripts<\/strong> \u2013 A folder containing a script named <strong>sample-script.js<\/strong> that will deploy your smart contract when executed<\/li><li><strong>test<\/strong> \u2013 A folder containing an example testing script<\/li><li><strong>contracts<\/strong> \u2013 A folder holding an example Ethereum smart contract<\/li><\/ul>\n\n\n\n<p>Because of <a href=\"https:\/\/hardhat.org\/metamask-issue.html\">a MetaMask configuration issue<\/a>, we need to update the chain ID on our HardHat configuration to be <strong>1337<\/strong>. We also need to update the location of the <a href=\"https:\/\/hardhat.org\/guides\/compile-contracts.html#artifacts\">artifacts<\/a> for our compiled contracts so they&#8217;re in the <strong>src<\/strong> directory of our React app.<\/p>\n\n\n\n<p>To make these updates, open <strong>hardhat.config.js<\/strong> and update the <code>module.exports<\/code> to look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module.exports = {\n  solidity: \"0.8.3\",\n  paths: {\n    artifacts: '.\/src\/artifacts',\n  },\n  networks: {\n    hardhat: {\n      chainId: 1337\n    }\n  }\n};\n<\/code><\/pre>\n\n\n\n<h2 id=\"our-smart-contract\">Our smart contract<\/h2>\n\n\n\n<p>Next, let&#8217;s have a look at the example contract we have at <strong>contracts\/Greeter.sol<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\n\nimport \"hardhat\/console.sol\";\n\n\ncontract Greeter {\n  string greeting;\n\n  constructor(string memory _greeting) {\n    console.log(\"Deploying a Greeter with greeting:\", _greeting);\n    greeting = _greeting;\n  }\n\n  function greet() public view returns (string memory) {\n    return greeting;\n  }\n\n  function setGreeting(string memory _greeting) public {\n    console.log(\"Changing greeting from '%s' to '%s'\", greeting, _greeting);\n    greeting = _greeting;\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>This is a very basic smart contract. When deployed, it sets a Greeting variable and exposes a function (<code>greet<\/code>) that can be called to return the greeting.<\/p>\n\n\n\n<p>It also exposes a function that allows a user to update the greeting (<code>setGreeting<\/code>). When deployed to the Ethereum blockchain, these methods will be available for a user to interact with.<\/p>\n\n\n\n<p>Let&#8217;s make one small modification to the smart contract. Since we set the solidity version of our compiler to <code>0.8.3<\/code> in <strong>hardhat.config.js<\/strong>, let&#8217;s also be sure to update our contract to use the same version of solidity:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ contracts\/Greeter.sol\npragma solidity ^0.8.3;\n<\/code><\/pre>\n\n\n\n<h3 id=\"how-to-read-and-write-to-the-ethereum-blockchain\">How to Read and Write to the Ethereum Blockchain<\/h3>\n\n\n\n<p>There are two ways to interact with a smart contract \u2013 reading or writing \/ transactions. In our contract, <code>greet<\/code> can be considered reading, and <code>setGreeting<\/code> can be considered writing \/ transactional.<\/p>\n\n\n\n<p>When writing or initializing a transaction, you have to pay for the transaction to be written to the blockchain. To make this work, you need to pay <a href=\"https:\/\/www.investopedia.com\/terms\/g\/gas-ethereum.asp#:~:text=What%20Is%20Gas%20(Ethereum)%3F,on%20the%20Ethereum%20blockchain%20platform\">gas<\/a> which is the fee or price required to successfully conduct a transaction and execute a contract on the Ethereum blockchain.<\/p>\n\n\n\n<p>As long as you are only reading from the blockchain and not changing or updating anything, you don&#8217;t need to carry out a transaction and there will be no gas or cost to do so. The function you call is then carried out only by the node you are connected to, so you don&#8217;t need to pay any gas and the read is free.<\/p>\n\n\n\n<p>From our React app, we will interact with the smart contract using a combination of the <code>ethers.js<\/code> library, the contract address, and the <a href=\"https:\/\/docs.soliditylang.org\/en\/v0.5.3\/abi-spec.html\">ABI<\/a> that will be created from the contract by Hardhat.<\/p>\n\n\n\n<p>What is an ABI? ABI stands for application binary interface. You can think of it as the interface between your client-side application and the Ethereum blockchain where the smart contract you are going to be interacting with is deployed.<\/p>\n\n\n\n<p>ABIs are typically compiled from Solidity smart contracts by a development framework like Hardhat. You can also often find the ABIs for a smart contract on <a href=\"https:\/\/etherscan.io\/\">Etherscan<\/a><\/p>\n\n\n\n<h3 id=\"how-to-compile-the-abi\">How to Compile the ABI<\/h3>\n\n\n\n<p>Now that we have gone over the basic smart contract and know what ABIs are, let&#8217;s compile an ABI for our project.<\/p>\n\n\n\n<p>To do so, go to the command line and run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat compile\n<\/code><\/pre>\n\n\n\n<p>Now, you should see a new folder named <strong>artifacts<\/strong> in the <strong>src<\/strong> directory. The <strong>artifacts\/contracts\/Greeter.json<\/strong> file contains the ABI as one of the properties. When we need to use the ABI, we can import it from our JavaScript file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import Greeter from '.\/artifacts\/contracts\/Greeter.sol\/Greeter.json'\n<\/code><\/pre>\n\n\n\n<p>We can then reference the ABI like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>console.log(\"Greeter ABI: \", Greeter.abi)\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Note that Ethers.js also enables <a href=\"https:\/\/blog.ricmoo.com\/human-readable-contract-abis-in-ethers-js-141902f4d917\">human readable ABIs<\/a>, but will will not be going into this during this tutorial.<\/p><\/blockquote>\n\n\n\n<h3 id=\"how-to-deploy-and-use-a-local-network-blockchain\">How to Deploy and Use a Local Network \/ Blockchain<\/h3>\n\n\n\n<p>Next, let&#8217;s deploy our smart contract to a local blockchain so that we can test it out.<\/p>\n\n\n\n<p>To deploy to the local network, you first need to start the local test node. To do so, open the CLI and run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat node\n<\/code><\/pre>\n\n\n\n<p>When we run this command, you should see a list of addresses and private keys.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/e176nc82ik77hei3a48s.jpg\" alt=\"Hardhat node addresses\"\/><\/figure>\n\n\n\n<p>These are 20 test accounts and addresses created for us that we can use to deploy and test our smart contracts. Each account is also loaded up with 10,000 fake Ether. In a moment, we&#8217;ll learn how to import the test account into MetaMask so that we can use it.<\/p>\n\n\n\n<p>Next, we need to deploy the contract to the test network. First update the name of <strong>scripts\/sample-script.js<\/strong> to <strong>scripts\/deploy.js<\/strong>.<\/p>\n\n\n\n<p>Now we can run the deploy script and give a flag to the CLI that we would like to deploy to our local network:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat run scripts\/deploy.js --network localhost\n<\/code><\/pre>\n\n\n\n<p>Once this script is executed, the smart contract should be deployed to the local test network and we should be then able to start interacting with it.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>When the contract was deployed, it used the first account that was created when we started the local network.<\/p><\/blockquote>\n\n\n\n<p>If you look at the output from the CLI, you should be able to see something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Greeter deployed to: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0\n<\/code><\/pre>\n\n\n\n<p>This address is what we will use in our client application to talk to the smart contract. Keep this address available as we will need to use it when connecting to it from the client application.<\/p>\n\n\n\n<p>To send transactions to the smart contract, we will need to connect our MetaMask wallet using one of the accounts created when we ran <code>npx hardhat node<\/code>. In the list of contracts that the CLI logs out, you should see both an <strong>Account number<\/strong> as well as a <strong>Private Key<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u279c  react-defi-stack git:(main) npx hardhat node\nStarted HTTP and WebSocket JSON-RPC server at http:\/\/127.0.0.1:8545\/\n\nAccounts\n========\nAccount #0: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 (10000 ETH)\nPrivate Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80\n\n...\n<\/code><\/pre>\n\n\n\n<p>We can import this account into MetaMask in order to start using some of the fake Eth available there. To do so, first open MetaMask and update the network to be Localhost 8545:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/qnbsbcm4y1md6cwjttpx.jpg\" alt=\"MetaMask Localhost\"\/><\/figure>\n\n\n\n<p>Next, in MetaMask click on <strong>Import Account<\/strong> from the accounts menu:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/n7vbzlov869gwk9rtwl1.jpg\" alt=\"Import account\"\/><\/figure>\n\n\n\n<p>Copy then paste one of the <strong>Private Keys<\/strong> logged out by the CLI and click <strong>Import<\/strong>. Once the account is imported, you should see the Eth in the account:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/x5lob4yug3jznhy9z0qt.jpg\" alt=\"Imported account\"\/><\/figure>\n\n\n\n<p>Now that we have a deployed our smart contract and set up our account, we can start interacting with it from the React app.<\/p>\n\n\n\n<h3 id=\"how-to-connect-the-react-client\">How to Connect the React Client<\/h3>\n\n\n\n<p>In this tutorial we are not going to be worrying about building a beautiful UI with CSS and all of that \u2013 we are focused 100% on the core functionality to get you up and running. From there, you can take it and make it look good if you&#8217;d like.<\/p>\n\n\n\n<p>With that being said, let&#8217;s review the two objectives that we want from our React application:<\/p>\n\n\n\n<ol><li>Fetch the current value of <code>greeting<\/code> from the smart contract<\/li><li>Allow a user to update the value of the <code>greeting<\/code><\/li><\/ol>\n\n\n\n<p>So how do we accomplish this? Here are the things we need to do to make this happen:<\/p>\n\n\n\n<ol><li>Create an input field and some local state to manage the value of the input (to update the <code>greeting<\/code>)<\/li><li>Allow the application to connect to the user&#8217;s MetaMask account to sign transactions<\/li><li>Create functions for reading and writing to the smart contract<\/li><\/ol>\n\n\n\n<p>To do this, open <code>src\/App.js<\/code> and update it with the following code, setting the value of <code>greeterAddress<\/code> to the address of your smart contract:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import '.\/App.css';\nimport { useState } from 'react';\nimport { ethers } from 'ethers'\nimport Greeter from '.\/artifacts\/contracts\/Greeter.sol\/Greeter.json'\n\n\/\/ Update with the contract address logged out to the CLI when it was deployed \nconst greeterAddress = \"your-contract-address\"\n\nfunction App() {\n  \/\/ store greeting in local state\n  const &#91;greeting, setGreetingValue] = useState()\n\n  \/\/ request access to the user's MetaMask account\n  async function requestAccount() {\n    await window.ethereum.request({ method: 'eth_requestAccounts' });\n  }\n\n  \/\/ call the smart contract, read the current greeting value\n  async function fetchGreeting() {\n    if (typeof window.ethereum !== 'undefined') {\n      const provider = new ethers.providers.Web3Provider(window.ethereum)\n      const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)\n      try {\n        const data = await contract.greet()\n        console.log('data: ', data)\n      } catch (err) {\n        console.log(\"Error: \", err)\n      }\n    }    \n  }\n\n  \/\/ call the smart contract, send an update\n  async function setGreeting() {\n    if (!greeting) return\n    if (typeof window.ethereum !== 'undefined') {\n      await requestAccount()\n      const provider = new ethers.providers.Web3Provider(window.ethereum);\n      const signer = provider.getSigner()\n      const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)\n      const transaction = await contract.setGreeting(greeting)\n      await transaction.wait()\n      fetchGreeting()\n    }\n  }\n\n  return (\n    &lt;div className=\"App\"&gt;\n      &lt;header className=\"App-header\"&gt;\n        &lt;button onClick={fetchGreeting}&gt;Fetch Greeting&lt;\/button&gt;\n        &lt;button onClick={setGreeting}&gt;Set Greeting&lt;\/button&gt;\n        &lt;input onChange={e =&gt; setGreetingValue(e.target.value)} placeholder=\"Set greeting\" \/&gt;\n      &lt;\/header&gt;\n    &lt;\/div&gt;\n  );\n}\n\nexport default App;\n<\/code><\/pre>\n\n\n\n<p>To test it out, start the React server:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm start\n<\/code><\/pre>\n\n\n\n<p>When the app loads, you should be able to fetch the current greeting and log it out to the console. You should also be able to make updates to the greeting by signing the contract with your MetaMask wallet and spending the fake Ether.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/9a57jbzrwylr2l0rujxm.png\" alt=\"Setting and getting the greeting value\"\/><\/figure>\n\n\n\n<h3 id=\"how-to-deploy-and-use-a-live-test-network\">How to Deploy and Use a Live Test Network<\/h3>\n\n\n\n<p>There are several Ethereum test networks like Ropsten, Rinkeby, or Kovan that we can also deploy to in order to have a publicly accessible version of our contract available without having to deploy it to mainnet.<\/p>\n\n\n\n<p>In this tutorial we&#8217;ll be deploying to the <strong>Ropsten<\/strong> test network.<\/p>\n\n\n\n<p>To start off, first update your MetaMask wallet to connect to the Ropsten network.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/k85gplgp26wp58l95bhr.jpg\" alt=\"Ropsten network\"\/><\/figure>\n\n\n\n<p>Next, send yourself some test Ether to use during the rest of this tutorial by visiting <a href=\"https:\/\/faucet.ropsten.be\/\">this test faucet<\/a>.<\/p>\n\n\n\n<p>We can get access to Ropsten (or any of the other test networks) by signing up with a service like <a href=\"https:\/\/infura.io\/dashboard\/ethereum\/cbdf7c5eee8b4e2b91e76b77ffd34533\/settings\">Infura<\/a> or <a href=\"https:\/\/www.alchemyapi.io\/\">Alchemy<\/a> (I&#8217;m using Infura for this tutorial).<\/p>\n\n\n\n<p>Once you&#8217;ve created the app in Infura or Alchemy, you will be given an endpoint that looks something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;ropsten.infura.io\/v3\/your-project-id\n<\/code><\/pre>\n\n\n\n<p>Be sure to set the <strong>ALLOWLIST ETHEREUM ADDRESSES<\/strong> in the Infura or Alchemy app configuration to include the wallet address of the account you will be deploying from.<\/p>\n\n\n\n<p>To deploy to the test network we need to update our Hardhat config with some additional network information. One of the things we need to set is the private key of the wallet we will be deploying from.<\/p>\n\n\n\n<p>To get the private key, you can export it from MetaMask.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/deod3d6qix8us12t17i4.jpg\" alt=\"Export private key\"\/><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>I&#8217;d suggest not hardcoding this value in your app but instead setting it as something like an environment variable.<\/p><\/blockquote>\n\n\n\n<p>Next, add a <code>networks<\/code> property with the following configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module.exports = {\n  defaultNetwork: \"hardhat\",\n  paths: {\n    artifacts: '.\/src\/artifacts',\n  },\n  networks: {\n    hardhat: {},\n    ropsten: {\n      url: \"https:\/\/ropsten.infura.io\/v3\/your-project-id\",\n      accounts: &#91;`0x${your-private-key}`]\n    }\n  },\n  solidity: \"0.7.3\",\n};\n<\/code><\/pre>\n\n\n\n<p>To deploy, run the following script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat run scripts\/deploy.js --network ropsten\n<\/code><\/pre>\n\n\n\n<p>Once your contract is deployed you should be able to start interacting with it. You should be now able to view the live contract on <a href=\"https:\/\/ropsten.etherscan.io\/\">Etherscan Ropsten Testnet Explorer<\/a><\/p>\n\n\n\n<h2 id=\"how-to-mint-tokens\">How to Mint Tokens<\/h2>\n\n\n\n<p>One of the most common use cases of smart contracts is creating tokens. Let&#8217;s look at how we can do that. Since we know a little more about how all of this works, we&#8217;ll be going a little faster.<\/p>\n\n\n\n<p>In the main <strong>contracts<\/strong> directory, create a new file named <strong>Token.sol<\/strong>.<\/p>\n\n\n\n<p>Next, update <strong>Token.sol<\/strong> with the following smart contract:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/SPDX-License-Identifier: MIT\npragma solidity ^0.8.3;\n\nimport \"hardhat\/console.sol\";\n\ncontract Token {\n  string public name = \"Nader Dabit Token\";\n  string public symbol = \"NDT\";\n  uint public totalSupply = 1000000;\n  mapping(address =&gt; uint) balances;\n\n  constructor() {\n    balances&#91;msg.sender] = totalSupply;\n  }\n\n  function transfer(address to, uint amount) external {\n    require(balances&#91;msg.sender] &gt;= amount, \"Not enough tokens\");\n    balances&#91;msg.sender] -= amount;\n    balances&#91;to] += amount;\n  }\n\n  function balanceOf(address account) external view returns (uint) {\n    return balances&#91;account];\n  }\n}\n<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Note that this token contract is for demo purposes only and is not <a href=\"https:\/\/eips.ethereum.org\/EIPS\/eip-20\">ERC20<\/a>-compliant. We will be covering ERC20 tokens later.<\/p><\/blockquote>\n\n\n\n<p>This contract will create a new token called &#8220;Nader Dabit Token&#8221; and set the supply to 1000000.<\/p>\n\n\n\n<p>Next, compile this contract:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat compile\n<\/code><\/pre>\n\n\n\n<p>Now, update the deploy script at <strong>scripts\/deploy.js<\/strong> to include this new Token contract:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const hre = require(\"hardhat\");\n\nasync function main() {\n  const &#91;deployer] = await hre.ethers.getSigners();\n\n  console.log(\n    \"Deploying contracts with the account:\",\n    deployer.address\n  );\n  \n  const Greeter = await hre.ethers.getContractFactory(\"Greeter\");\n  const greeter = await Greeter.deploy(\"Hello, World!\");\n\n  const Token = await hre.ethers.getContractFactory(\"Token\");\n  const token = await Token.deploy();\n  \n  await greeter.deployed();\n  await token.deployed();\n\n  console.log(\"Greeter deployed to:\", greeter.address);\n  console.log(\"Token deployed to:\", token.address);\n}\n\nmain()\n  .then(() =&gt; process.exit(0))\n  .catch(error =&gt; {\n    console.error(error);\n    process.exit(1);\n  });\n<\/code><\/pre>\n\n\n\n<p>Now, we can deploy this new contract to the local or Ropsten network:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx hardhat run scripts\/deploy.js --network localhost\n<\/code><\/pre>\n\n\n\n<p>Once the contract is deployed, you can start sending these tokens to other addresses.<\/p>\n\n\n\n<p>To do so, let&#8217;s update the client code we will need in order to make this work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import '.\/App.css';\nimport { useState } from 'react';\nimport { ethers } from 'ethers'\nimport Greeter from '.\/artifacts\/contracts\/Greeter.sol\/Greeter.json'\nimport Token from '.\/artifacts\/contracts\/Token.sol\/Token.json'\n\nconst greeterAddress = \"your-contract-address\"\nconst tokenAddress = \"your-contract-address\"\n\nfunction App() {\n  const &#91;greeting, setGreetingValue] = useState()\n  const &#91;userAccount, setUserAccount] = useState()\n  const &#91;amount, setAmount] = useState()\n\n  async function requestAccount() {\n    await window.ethereum.request({ method: 'eth_requestAccounts' });\n  }\n\n  async function fetchGreeting() {\n    if (typeof window.ethereum !== 'undefined') {\n      const provider = new ethers.providers.Web3Provider(window.ethereum)\n      console.log({ provider })\n      const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)\n      try {\n        const data = await contract.greet()\n        console.log('data: ', data)\n      } catch (err) {\n        console.log(\"Error: \", err)\n      }\n    }    \n  }\n\n  async function getBalance() {\n    if (typeof window.ethereum !== 'undefined') {\n      const &#91;account] = await window.ethereum.request({ method: 'eth_requestAccounts' })\n      const provider = new ethers.providers.Web3Provider(window.ethereum);\n      const contract = new ethers.Contract(tokenAddress, Token.abi, provider)\n      const balance = await contract.balanceOf(account);\n      console.log(\"Balance: \", balance.toString());\n    }\n  }\n\n  async function setGreeting() {\n    if (!greeting) return\n    if (typeof window.ethereum !== 'undefined') {\n      await requestAccount()\n      const provider = new ethers.providers.Web3Provider(window.ethereum);\n      console.log({ provider })\n      const signer = provider.getSigner()\n      const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)\n      const transaction = await contract.setGreeting(greeting)\n      await transaction.wait()\n      fetchGreeting()\n    }\n  }\n\n  async function sendCoins() {\n    if (typeof window.ethereum !== 'undefined') {\n      await requestAccount()\n      const provider = new ethers.providers.Web3Provider(window.ethereum);\n      const signer = provider.getSigner();\n      const contract = new ethers.Contract(tokenAddress, Token.abi, signer);\n      const transation = await contract.transfer(userAccount, amount);\n      await transation.wait();\n      console.log(`${amount} Coins successfully sent to ${userAccount}`);\n    }\n  }\n\n  return (\n    &lt;div className=\"App\"&gt;\n      &lt;header className=\"App-header\"&gt;\n        &lt;button onClick={fetchGreeting}&gt;Fetch Greeting&lt;\/button&gt;\n        &lt;button onClick={setGreeting}&gt;Set Greeting&lt;\/button&gt;\n        &lt;input onChange={e =&gt; setGreetingValue(e.target.value)} placeholder=\"Set greeting\" \/&gt;\n\n        &lt;br \/&gt;\n        &lt;button onClick={getBalance}&gt;Get Balance&lt;\/button&gt;\n        &lt;button onClick={sendCoins}&gt;Send Coins&lt;\/button&gt;\n        &lt;input onChange={e =&gt; setUserAccount(e.target.value)} placeholder=\"Account ID\" \/&gt;\n        &lt;input onChange={e =&gt; setAmount(e.target.value)} placeholder=\"Amount\" \/&gt;\n      &lt;\/header&gt;\n    &lt;\/div&gt;\n  );\n}\n\nexport default App;\n<\/code><\/pre>\n\n\n\n<p>Next, run the app:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm start\n<\/code><\/pre>\n\n\n\n<p>We should be able to click on <strong>Get Balance<\/strong> and see that we have 1,000,000 coins in our account logged out to the console.<\/p>\n\n\n\n<p>You should also be able to view them in MetaMask by clicking on <strong>Add Token<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/0t2ip26i5d2ltjc9j2a6.jpg\" alt=\"Add token\"\/><\/figure>\n\n\n\n<p>Next click on <strong>Custom Token<\/strong> and enter the token contract address and then <strong>Add Token<\/strong>. Now the tokens should be available in your wallet:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/dev-to-uploads.s3.amazonaws.com\/uploads\/articles\/5op32iqbeszizri72qc0.jpg\" alt=\"NDT\"\/><\/figure>\n\n\n\n<p>Next, let&#8217;s try to send those coins to another address.<\/p>\n\n\n\n<p>To do so, copy the address of another account and send them to that address using the updated React UI. When you check the token amount, it should be equal to the original amount minus the amount you sent to the address.<\/p>\n\n\n\n<h2 id=\"how-to-build-an-erc20-token\">How to Build An ERC20 Token<\/h2>\n\n\n\n<p>The <a href=\"https:\/\/ethereum.org\/en\/developers\/docs\/standards\/tokens\/erc-20\/\">ERC20 Token Standard<\/a> defines a set of rules that apply to all ERC20 tokens which allow them to easily interact with each other. ERC20 makes it really easy for someone to mint their own tokens that will have interoperability with others on the Ethereum blockchain.<\/p>\n\n\n\n<p>Let&#8217;s look at how we can build our own token using the ERC20 standard.<\/p>\n\n\n\n<p>First, install the <a href=\"https:\/\/github.com\/OpenZeppelin\/openzeppelin-contracts\">OpenZepplin<\/a> smart contract library where we will be importing the base <code>ERC20<\/code> Token:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install @openzeppelin\/contracts\n<\/code><\/pre>\n\n\n\n<p>Next, we&#8217;ll create our token by extending (or inheriting from) the <code>ERC20<\/code> contract:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/SPDX-License-Identifier: MIT\npragma solidity ^0.8.3;\n\nimport \"@openzeppelin\/contracts\/token\/ERC20\/ERC20.sol\";\n\ncontract NDToken is ERC20 {\n    constructor(string memory name, string memory symbol) ERC20(name, symbol) {\n        _mint(msg.sender, 100000 * (10 ** 18));\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>The constructor allows you to set the token name and symbol, and the <code>_mint<\/code> function allows you to mint the tokens and set the amount.<\/p>\n\n\n\n<p>By default, ERC20 sets the number of decimals to 18, so in our <code>_mint<\/code> function we multiply 100,000 by 10 to the 18 power to mint a total of 100,000 tokens, each with 18 decimal places (similarly to how 1 Eth is made up of 10 to the 18 <a href=\"https:\/\/www.investopedia.com\/terms\/w\/wei.asp\">wei<\/a>.<\/p>\n\n\n\n<p>To deploy, we need to pass in the constructor values (<code>name<\/code> and <code>symbol<\/code>), so we might do something like this in our deploy script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const NDToken = await hre.ethers.getContractFactory(\"NDToken\");\nconst ndToken = await NDToken.deploy(\"Nader Dabit Token\", \"NDT\");\n<\/code><\/pre>\n\n\n\n<p>By extending the original ERC20 token, your token will inherit all of the following functions and functionality:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function name() public view returns (string)\nfunction symbol() public view returns (string)\nfunction decimals() public view returns (uint8)\nfunction totalSupply() public view returns (uint256)\nfunction balanceOf(address _owner) public view returns (uint256 balance)\nfunction transfer(address _to, uint256 _value) public returns (bool success)\nfunction transferFrom(address _from, address _to, uint256 _value) public returns (bool success)\nfunction approve(address _spender, uint256 _value) public returns (bool success)\nfunction allowance(address _owner, address _spender) public view returns (uint256 remaining)\n<\/code><\/pre>\n\n\n\n<p>Once deployed, you can use any of these functions to interact with the new smart contract. For another example of an ERC20 token, check out Solidity by example here: <a href=\"https:\/\/solidity-by-example.org\/app\/erc20\/\">https:\/\/solidity-by-example.org\/app\/erc20\/<\/a>.<\/p>\n\n\n\n<h2 id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>Ok, we covered a lot in this article. But for me this is kind of the bread and butter \/ core of getting started with this stack.<\/p>\n\n\n\n<p>It&#8217;s kind of what I wanted to have, not only as someone who was learning all of this stuff, but also in the future if I ever need to reference anything I may need. I hope you learned a lot.<\/p>\n\n\n\n<p>If you want to support multiple wallets in addition to MetaMask, check out <a href=\"https:\/\/github.com\/Web3Modal\/web3modal\">Web3Modal<\/a> which makes it easy to implement support for multiple providers in your app with a fairly simple and customizable configuration.<\/p>\n\n\n\n<p>In my future tutorials and guides, I&#8217;ll be diving into more complex smart contract development and also how to deploy them as <a href=\"https:\/\/thegraph.com\/docs\/define-a-subgraph\">subgraphs<\/a> to expose a GraphQL API on top of them and implement things like pagination and full text search.<\/p>\n\n\n\n<p>I&#8217;ll also be going into how to use technologies like IPFS and Web3 databases to store data in a decentralized way.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, you&#8217;ll learn how to build full stack dApps with React, Ethers.js, Solidity, and Hardhat.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[178],"tags":[174],"_links":{"self":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2357"}],"collection":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2357"}],"version-history":[{"count":1,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2357\/revisions"}],"predecessor-version":[{"id":2358,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/2357\/revisions\/2358"}],"wp:attachment":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2357"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2357"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2357"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}