Build a Buymeacoffee DApp Using Solidity + Ethereum Smart Contract + ReactJs + TailwindCSS

Blockchain development is typically one of the highest-paying programming industries, with developers earning between $150,000 and $175,000 per year as salaried employees.

That sounds interesting, right?

To learn more about a developer roadmap and get started, check here.

In this article, we will build a mini buymeacoffee DApp using Solidity, an Ethereum smart contract, React, and TailwindCSS. It'll be a platform where anyone on the Internet can learn a little about us and send us a note and money to purchase a coffee, with the information on-chain via an Ethereum smart contract. A smart contract is essentially code that stays on the blockchain and can be read and written from; we'll go over this in more detail later.

We'll create the smart contract and deploy it. We will also build a website that will allow people to connect their wallets and engage with our smart contract.

Here is a link to the live demo and the GitHub repositories ๐Ÿ‘‰ frontend and backend/smart contract

D_D Newsletter CTA

Prerequisite

Ensure you have Node/NPM installed on our PC. If you don't have it, head over here for a guide.

Project Setup and Installation

Next, let's head over to the terminal. We'll need to cd into the directory we wish to work with and then run the following commands:

mkdir mini-buymeacoffee-be
cd mini-buymeacoffee-be
npm init -y
npm install --save-dev hardhat

Now, we should have a hardhat. Let's get a sample project going by running the command below:

npx hardhat

We'll go with the option of creating a sample project. Accept all requests. Installing hardhat-waffle and hardhat-ethers is required for the sample project. These are some of the other things we'll be using later :)

If it didn't do it automatically, we would install these other requirements.

npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers

To make sure everything is working, run:

npx hardhat test

We will see a passed test result in our console.

It is now possible for us to delete sample-test.js from the test folder. Delete sample-script.js from the scripts directory as well. After that, go to contracts and delete Greeter.sol.

You should not delete the folders themselves!

Next, under the contracts directory, we'll create a file called CoffeePortal.sol. When using hardhat, file layout is crucial, so pay attention! We're going to start with the basic structure of every contract.

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.0;

import "hardhat/console.sol";

contract CoffeePortal {

    constructor() payable {
        console.log("Yo! Smart Contract");
    }
}

To build and deploy our smart contract, navigate to the scripts folder, create a new file called run.js, and update it with the following code snippet:

const main = async () => {

// This will compile our contract and generate the necessary files we need to work with our contract under the artifacts directory.
  const coffeeContractFactory = await hre.ethers.getContractFactory('CoffeePortal');
  const coffeeContract = await coffeeContractFactory.deploy();

  await coffeeContract.deployed(); // We'll wait until the network deploys our contract to our local blockchain! Our constructor runs when we deploy.

 console.log("Coffee Contract deployed to:", coffeeContract.address);
};

const runMain = async () => {
  try {
    await main();
    process.exit(0);
  } catch (error) {
    console.log(error);
    process.exit(1);
  }
};

runMain();

Let's run it!

npx hardhat run scripts/run.js

You should see something similar to what we have below:

Hardhat compilation result

We have a working smart contract ๐Ÿฅณ Let us deploy it to a network by making it available to everyone worldwide.

Under the scripts folder, create a file called deploy.js. Here's the code for it. It looks super similar to run.js.

const main = async () => {
  const [deployer] = await hre.ethers.getSigners();
  const accountBalance = await deployer.getBalance();

  console.log("Deploying contracts with account: ", deployer.address);
  console.log("Account balance: ", accountBalance.toString());

  const Token = await hre.ethers.getContractFactory("CoffeePortal");
  const portal = await Token.deploy();
  await portal.deployed();

  console.log("CoffeePortal address: ", portal.address);
};

const runMain = async () => {
  try {
    await main();
    process.exit(0);
  } catch (error) {
    console.error(error);
    process.exit(1);
  }
};

runMain();

Now the command below we're going to deploy locally using the localhost network for test:

npx hardhat run scripts/deploy.js --network localhost

We should have something similar to what we have below:

Rinkeby Network

Building and Deploying CoffeeContract to the Blockchain

Everything is now in place, including the test script and the 'deploy.js' file. With the following code snippet, we'll update the Smart Contract, run.js, and deploy.js files:

contracts/CoffeePortal.sol

Update scripts/run.js

Update scripts/deploy.js

Now it's time to get down to business, deploying to the actual blockchain.

We'll need to sign up for an Alchemy account before deploying to the blockchain.

Alchemy allows us to broadcast our contract creation transaction so that miners can pick it up as soon as possible. Once mined, the miners then broadcast the transaction to the blockchain as a legitimate transaction. After that, everyone updates their copy of the blockchain.

We'll create an app as shown below after signing up. Remember to change the network selection to Rinkeby because that's where we'll be deploying.

We switched it from mainnet to Rinkeby testnet for a reason. Because it's real money, and it's not worth squandering! We'll start with a "testnet," which is a clone of a "mainnet" but utilizes pretend money so we can experiment as much as we like. However, it's crucial to note that genuine miners operate testnets, which simulate real-world conditions.

Alchemy App

Afterward, we will need to grab our keys, as shown below, and store them for later use:

Alchemy keys

We'll need some fake ETH in our testnet account, and we'll have to request some from the network. You can use this fake ETH only on the testnet. Rinkeby can get some phony ETH by using a faucet.

NameLinkAmountTime
MyCryptohttps://app.mycrypto.com/faucet0.01None
Buildspacehttps://buildspace-faucet.vercel.app/0.0251d
Ethilyhttps://ethily.io/rinkeby-faucet/0.21w
Official Rinkebyhttps://faucet.rinkeby.io/3 / 7.5 / 18.758h / 1d / 3d

Table by Buildspace

Our hardhat.config.js file needs to be updated. This can be found in the smart contract project's root directory.


require("@nomiclabs/hardhat-waffle");
require("dotenv").config();

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  solidity: "0.8.4",
  networks: {
    rinkeby: {
      url: process.env.STAGING_ALCHEMY_KEY,
      accounts: [process.env.PRIVATE_KEY],
    },
  },
};

If we look at the code snippet above, we can see that Hardhat read some keys from the .env file, as well as the import at the top of require("dotenv").config(), which implies we'll need to install the dotenv package and also create a .env file using the command below:

npm install -D dotenv

touch .env

Inside the .env file, add the following keys:

STAGING_ALCHEMY_KEY= // Add the key we copied from the Alchemy dashboard here
PRIVATE_KEY= // Add your account private key here

To get our account's private key is easy; check out this post.

Now we can run the command to deploy our contract to a real blockchain network.

npx hardhat run scripts/deploy.js --network rinkeby

Here's what our output should look like:

Rinkeby Output

Yay ๐Ÿฅณ we just deployed our contract.

Set up Frontend React Client

It's time to get our website up and running! We completed our smart contract, but we need to figure out how our front end can interact with it as soon as possible!

To create a new project, we use the npx create-next-app -e with-tailwindcss command to scaffold a new project in a directory of our choice.

This command creates a Next.js project with TailwindCSS set up. TailwindCSS is a utility-first CSS framework packed with classes to help us style our web pages.

To install the dependencies, we use the commands:

cd <project name> 
npm install ethers react-toastify

Once we create the app and install the dependencies, we will see a message with instructions for navigating to our site and running it locally. We do this with the command.

npm run dev

Next.js will start a hot-reloading development environment accessible by default at http://localhost:3000

We need to connect our wallet to the blockchain for our website to communicate with it. After connecting our wallet to our website, our website will have permission to call smart contracts on our behalf. Remember, it's the same as logging into a website.

All of our work will be done in index.js, found under pages.

We need to import abi and update our contractAddress in the code sample above. Let's start by creating a folder named utils, then using the following command to create a file called CoffeePortal.json inside the utils folder.

mkdir utils
touch CoffeePortal.json

Following that, we'll need our contract address and the content that will be updated in the CoffeePortal.json file. What's the best way to get it?

Let's go back to the smart contract project we worked on before, then navigate to artifacts/contracts/coffeePortal.json and copy the entire content inside it and our contract address, which was displayed in our terminal when we deployed our contract to the blockchain.

We will update the CoffeePortal.json file with what we copied and also update index.js as shown below:

// ...

import Head from "next/head";

// Import abi
import abi from "../utils/CoffeePortal.json";

export default function Home() {
  /**
   * Create a variable here that holds the contract address after you deploy!
   */
  const contractAddress = "";  // Add contract address here

   // ...
  return (
    <div className="flex flex-col items-center justify-center min-h-screen py-2">
      [...]
    </div>
  );
}

Its time to test our app; we should have something similar to what we have below when we visit http://localhost:3000

DApp landing page

Next, clicking connect wallet button should redirect us to the MetaMask UI, where we will grant the site access as shown below:

MetaMask

MetaMask Connecting

Then our UI should look similar to what you can see below:

Buy Me A Coffee - DApp

We can now support by buying a coffee worth $5 and also providing our name and any preferred message to the owner ๐Ÿ˜Š

Buy A Coffee

Next,

Connect MetaMask

Minning

Completed...

Transaction Completed

Another coffee support:

Blockchain Transaction

If we observe, the page updates in real-time once it completes a transaction; this is the result of the event we introduced to our smart contract, and React, of course, effortlessly updates the UI.

Conclusion

In this article, we learned how to build a mini buymeacoffee DApp using Solidity, Ethereum smart contract, React, and TailwindCSS.

D_D Newsletter CTA

References

I'd love to connect with you at Twitter | LinkedIn | GitHub | Portfolio

See you in my next blog article. Take care!!!