# Deploy with Hardhat

Hardhat is one of the popular smart contract development frameworks.&#x20;

This document is a guide on how to deploy a smart contract on the Concha network using Hardhat.

## Hardhat smart contract <a href="#hardhat-smart-contract" id="hardhat-smart-contract"></a>

* `mkdir <project-name>;cd <project-name>`
* Initialize a project with Hardhat: `npx hardhat`.
* Next, (… *To avoid failure … please go slow with this cli dialogue*…),

  So then,
* Press `<ENTER>` to set the project root.
* Press `<ENTER>` again to accept addition of `.gitignore`.
* Type `n` to reject installing `sample project's dependencies`.

  The idea here is to postpone installing dependencies to later steps due to a possible version-related bug.
* Open the `hardhat.config.js` file and paste the below code:

  Copy

  ```
  require("dotenv").config();
  require("@nomicfoundation/hardhat-toolbox");

  /** @type import('hardhat/config').HardhatUserConfig */
  module.exports = {
  solidity: "0.8.9",
  paths: {
      artifacts: "./src",
  },
  networks: {
      concha-testnet: {
      url: `https://testnet-rpc.concha.network`,
      accounts: [process.env.ACCOUNT_PRIVATE_KEY],
      },
  },
  };
  ```

  Note that a different path to artifacts is added so that the React app will be able to read the contract ABI within the `src` folder.

## Add scripts <a href="#add-scripts" id="add-scripts"></a>

* Create a new file, in the contracts folder, named `Counter.sol`: `touch contracts/Counter.sol`.
* Copy the below code and paste it in the Counter contract code:

  Copy

  ```
  //SPDX-License-Identifier: MIT
  pragma solidity ^0.8.9;

  contract Counter {
  uint256 currentCount = 0;

      function increment() public {
          currentCount = currentCount + 1;
      }

      function retrieve() public view returns (uint256){
          return currentCount;
      }
  }
  ```
* Create a new file in the scripts folder `deploy-counter.js`: `touch scripts/deploy-counter.js`.
* Add the code below to the `deploy-counter.js` file:

  Copy

  ```
  const hre = require("hardhat");

  async function main() {
      const deployedContract = await hre.ethers.deployContract("Counter");
      await deployedContract.waitForDeployment();
      console.log(
          `Counter contract deployed to https://explorer.concha.network/address/${deployedContract.target}`
      );
  }

  main().catch((error) => {
      console.error(error);
      process.exitCode = 1;
  });
  ```
* Before compiling the contract, you need to install the toolbox. You may need to change directory to install outside the project. Use this command:

  Copy

  ```
  npm install --save-dev @nomicfoundation/hardhat-toolbox
  ```
* Compile your contract code (i.e., go back to the project root in the CLI):

  Copy

  ```
  npx hardhat compile
  ```
* Now run the scripts:

  Copy

  ```
  npx hardhat run scripts/deploy-counter.js --network concha-testnet
  ```

  ​Here’s an output example:

  `Counter contract deployed to https://explorer.concha.network/address/0x5FbDB2315678afecb367f032d93F642f64180aa3`

## Update frontend <a href="#update-frontend" id="update-frontend"></a>

The next step is to turn `Counter.sol` into a dApp by importing the `ethers` and the `Counter` file, as well as logging the contract’s ABI.

* Include the below code in the `App.js` file:

  Copy

  ```
  import { ethers } from "ethers";
  import Counter from "./contracts/Counter.sol/Counter.json";
  const counterAddress = "your-contract-address"
  console.log(counterAddress, "Counter ABI: ", Counter.abi);
  ```
* Update the `counterAddress` to your deployed address.
  * It is the hexadecimal number found at the tail-end of the output of the last `npx hardhat run ...` command and looks like this `0x5FbDB2315678afecb367f032d93F642f64180aa3`.
  * It must be pasted in the `App.js` to replace `your-contract-address`. Be sure to use the deployed address from your own implementation!
* Update frontend counter to read from blockchain. Include the below code in the `App.js` file:

  Copy

  ```
  useEffect(() => {
      // declare the data fetching function
      const fetchCount = async () => {
      const data = await readCounterValue();
      return data;
      };

      fetchCount().catch(console.error);
  }, []);

  async function readCounterValue() {
      if (typeof window.ethereum !== "undefined") {
          const provider = new ethers.providers.Web3Provider(window.ethereum);

          console.log("provider", provider);

          const contract = new ethers.Contract(
              counterAddress,
              Counter.abi,
              provider
          );

          console.log("contract", contract);

          try {
              const data = await contract.retrieve();
              console.log(data);
              console.log("data: ", parseInt(data.toString()));
              setCount(parseInt(data.toString()));
          } catch (err) {
              console.log("Error: ", err);
              alert(
                  "Switch your MetaMask network to Concha Testnet and refresh this page!"
              );
          }
      }
  }
  ```
* Also, to import `useEffect`, insert it like this:

  Copy

  ```
  import { useState, useEffect } from "react";
  ```
* To be able to track a loader, add this to your state:

  Copy

  ```
  const [isLoading, setIsLoading] = useState(false);
  ```

  * This is within the `App()` function.
* Let frontend counter write to the blockchain by adding the below `requestAccount` and `updateCounter` functions:

  Copy

  ```
  async function requestAccount() {
  await window.ethereum.request({ method: "eth_requestAccounts" });
  }

  async function updateCounter() {
  if (typeof window.ethereum !== "undefined") {
      await requestAccount();
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      console.log({ provider });
      const signer = provider.getSigner();
      const contract = new ethers.Contract(counterAddress, Counter.abi, signer);
      const transaction = await contract.increment();
      setIsLoading(true);
      await transaction.wait();
      setIsLoading(false);
      readCounterValue();
  }
  }
  ```

  Place these two functions above the `readCounterValue()` function in the `App.js` file.
* Replace the `incrementCounter` function with this one:

  Copy

  ```
  const incrementCounter = async () => {
  await updateCounter();
  };
  ```
* Update the increment button code to:

  Copy

  ```
  <Button
  onClick={incrementCounter}
  variant="outlined"
  disabled={isLoading}
  >
  {isLoading ? "loading..." : "+1"}
  </Button>
  ```

Now, run the Counter dApp by simply using `npm start` in CLI at the project root.

You have successfully deployed a dApp on the Concha testnet.
