DEV Community

Cover image for How I Created a Crowdfunding Platform with Web3 & Micro-Frontends
Tapajyoti Bose
Tapajyoti Bose

Posted on

How I Created a Crowdfunding Platform with Web3 & Micro-Frontends

Over the past few months, I was learning about Micro-Frontend & Web3 Technologies. As the best way to learn is to try things hands-on, so I built up a small side-project to test out my understanding of the topics.

The aim of the project was to create a Crowdfunding Platform based on the Ethereum Blockchain utilizing Micro-Frontend Architecture

You can dive into the source code here

GitHub logo ruppysuppy / Crypto-Crowdfund

πŸ€‘πŸ’° Crowdfunding Platform backed by Ethereum Blockchain to bring your creative projects to life

And the website here: https://crypto-crowdfund.web.app/

NOTE: You need a MetaMask Wallet to interact with the blockchain

Smart Contract

You can interact with Ethereum Blockchain using Smart Contracts, so let's create one as per our requirement. The Contracts used in the project is available here

Making changes to a deployed Smart Contracts is not possible, and you have to re-deploy the contract, which costs Ethereum coins as Gas Fee. So it is essential that you extensively test the contract before deploying

Since storing data in the Smart Contracts incur Gas Fee too, only the essential data, such as the Campaign Manager, the Votes for a Transaction Request, etc are stored on the Blockchain.

Potential Improvements

  1. Split the Campaign Factory and the Campaign into separate files containing only the given Smart Contract
  2. Add the Manager functionality as a separate Smart Contract and add it to the Campaign using inheritance

Micro-Frontend

With the Smart Contract out of the way, let's focus on the Micro-Frontend

Let's Focus

Micro-Frontend architecture is a design approach in which a Frontend app is decomposed into individual, independent β€œmicro-apps” working loosely together.

Was Micro-Frontend Architecture essential for this project?

The answer to that is a definite NO. Then why did I use it? Just to put what I learned to practice. Micro-Frontend Architecture is useful only when working with large teams, where the role of each team is to work on only a small sub-section of the project

The Micro-Frontend was implemented using Webpack's Module Federation Plugin. If you want to learn how to implement Micro-Frontends from scratch, you are highly encouraged to check out this article

The Webpack config for each of the sub-apps and the container follow the same method.

  1. Make a common config file with the shared config for dev & prod build, for example:

    // imports ...
    
    module.exports = {
      // all shared config ...
    };
    
  2. Make a dev config and merge it with the common config

    const { merge } = require('webpack-merge');
    // other imports ...
    
    const devConfig = {
        // all development config ...
      },
    };
    
    module.exports = merge(commonConfig, devConfig);
    
  3. Finally make a prod config and merge it with the common config

    const { merge } = require('webpack-merge');
    // other imports ...
    
    const prodConfig = {
        // all production config ...
      },
    };
    
    module.exports = merge(commonConfig, prodConfig);
    

You can check out all the configuration files here

NOTE: In the project all the sub-apps use React, but you can very well use any other library or framework in any of them

Marketing

Let's start with the simplest sub-app, the Marketing sub-app is only responsible for rendering the home, about, faq, terms-and-conditions, privacy-policy, and disclaimer pages, and doesn't have much functionality apart from this.

Just as the Micro-Frontend sub-apps should only expose generic functions to avoid library or framework dependency between sub-apps and the container, the Marketing sub-apps exposes a mount function which takes simple objects as params. It has the following signature:

type Mount = (
  mountPoint: HTMLElement,
  {
    defaultHistory?: History | MemoryHistory;
    initialPath?: string;
    isAuthenticated?: boolean;
    routes: {
      HOME: string;
      ABOUT: string;
      FAQ: string;
      TERMS_AND_CONDITIONS: string;
      PRIVACY_POLICY: string;
      DISCLAIMER: string;
      CAMPAIGNS: string;
      SIGN_IN: string;
    };
    onNavigate?: ({ pathname: string }) => void;,
  },
) => {
    onParentNavigate: ({ pathname: string }) => void
  }
Enter fullscreen mode Exit fullscreen mode

Using the mount function, the container can mount the sub-app as per requirement. defaultHistory, onNavigate and onParentNavigate are used to keep both the container and the sub-app in sync and avoid some nasty bugs.

Auth

Next up is the Auth sub-app. It uses Firebase authentication to sign-in and sign-up users and grants them the required permissions.

It works similarly as the Marketing sub-app, by exposing the mount function with a similar set of params and handling the sign-in and sign-up pages

Potential Improvements

  • Use a method to sign-in only using the MetaMask account, removing the need to sign-in in two places to get full access to the application

Blockchain

Finally, we are at the most difficult to understand sub-app of all, the Blockchain sub-app is the meat of the project, enabling users to interact with the backend & the blockchain (to interact with the blockchain, you need a MetaMask extension on your browser).

It handles the account, campaign, campaigns and create-campaign pages.

As mentioned previously, only the essential data is stored on the contracts, saving the rest on Cloud Firestore. The data from the campaigns are fetched from the addresses residing on the Blockchain, and then data from Firestore is merged to generate the complete data for a given Campaign. Only the creator of the Campaign can modify the data on Firestore or create Transaction Request to spend the available funds, which the Contributors can approve.

Potential Improvements

  • Using image uploads in place of add url to image for both the cover image and the user profile picture (skipped it as the main focus was on integrating web3 & micro-frontend)

Container

The Container is responsible for condensing all the sub-apps into a single application and controlling what is displayed on the screen.

Potential Improvements

  • Improvised UI/UX

Wrapping Up

It's finally over...

Relief

This article presented a brief overview of the project, you can always dive into the source code and check out the project line by line

GitHub logo ruppysuppy / Crypto-Crowdfund

πŸ€‘πŸ’° Crowdfunding Platform backed by Ethereum Blockchain to bring your creative projects to life

Happy Developing!

Thanks for reading

Need a Top Rated Front-End Development Freelancer to chop away your development woes? Contact me on Upwork

Want to see what I am working on? Check out my Personal Website and GitHub

Want to connect? Reach out to me on LinkedIn

I am a freelancer who will start off as a Digital Nomad in mid-2022. Want to catch the journey? Follow me on Instagram

Follow my blogs for Weekly new Tidbits on Dev

FAQ

These are a few commonly asked questions I get. So, I hope this FAQ section solves your issues.

  1. I am a beginner, how should I learn Front-End Web Dev?
    Look into the following articles:

    1. Front End Development Roadmap
    2. Front End Project Ideas
  2. Would you mentor me?

    Sorry, I am already under a lot of workload and would not have the time to mentor anyone.

  3. Would you like to collaborate on our site?

    As mentioned in the previous question, I am in a time crunch, so I would have to pass on such opportunities.

Discussion (2)

Collapse
shrav2001 profile image
shrav2001

Hey hi. Actually in campaign.ts file there is an import statement,

import campaign from '../ethereum/campaign.json';

But in the parent directory, there is no ethereum folder or the campaign.json folder. I was wondering if you can help me out here. Thank you!

Collapse
ruppysuppy profile image
Tapajyoti Bose Author • Edited on

You didn't compile the contract, run script generate-files under smart contracts