How I Built a Dapp Token Farm

Sohum Padhye
CoinsBench
Published in
7 min readFeb 2, 2022

--

Here’s an overview of what this article will feature:

  • Preface
  • Development Environment
  • Challenges
  • Project Walkthrough
  • Demo
  • Takeaways from this Project
  • Next Steps

Preface

What is a Dapp?

Decentralized Finance (DeFi), is an emerging financial technology with a goal to remove intermediaries in financial transactions.

As I mentioned in my previous article where I give an introduction to smart contracts, a Decentralized application (Dapp) is essentially an application built on a decentralized network. A smart contract, on the other hand, is simply a piece of code on the blockchain. In this article, I’ll show you how I built an awesome Dapp that uses smart contracts to run a token farm.

What is a Token Farm?

By definition, a token farm is essentially a place where you can do yield farming — lending or staking your cryptocurrencies or tokens to get rewards. In the project, I built a place where you can stake tokens, and then use those staked tokens to issue tokens for a Dapp.

Why Did I Want to Build this?

I wanted to use a DeFi app tutorial that would allow me to expand my knowledge and skills on programming in Solidity. In reviewing the tutorial, I found that it would help me understand the technology behind a typical Dapp, and how actual token farm applications are built.

Development Environment

To build this application, I used a tutorial by Dapp University. Dapp University is the YouTube channel that made this awesome tutorial, so I definitely suggest you go check it out! I also tried making an election app with it, and it has taught me a lot about coding with Solidity.

Below are the key components of my environment:

Solidity

Solidity is the programming language used in the Ethereum network. It is a Turing-complete language, meaning it is possible to program any logic into it. Solidity is very close to the programming language JavaScript, and I used it for making the smart contracts in the project.

Ganache

Ganache is a personal blockchain that allows you to develop, deploy, and test your decentralized applications in an Ethereum environment. You can use Ganache in two ways: User Interface (UI) or Command-Line Interface (CLI). I used the UI because it’s much easier to navigate.

Metamask

Metamask is a browser extension and mobile app that is essentially a place where you can keep all your Ethereum wallets. I used Metamask to easily access the Ethereum wallets I was using for testing with Ganache.

React

React is an open-source application normally used for building one-page applications on the web. The advantage of React over other tools with web development is the fact that it can render separate components individually.

Node JS

JavaScript was originally made for frontend development along with HTML, but Node allows it to be used on the backend as well for server-side programming. It is a JavaScript runtime built on Chrome’s V8 JavaScript engine.

Visual Studio Code

Visual Studio Code (VS Code) is the code editor that I used for this project. While code editors don’t really matter much, I find that VS Code is the best editor in general because of its great flexibility and debugging capabilities. It also has a wide range of extensions and themes that can be added to make the coding experience much better.

Challenges

While it may sound that it was easy enough to follow, it actually wasn’t. It took me two months and I faced several challenges along the way, and below are just a few examples of them.

Solidity Versions

The first part of these challenges that I faced was the fact that I was using a different version of Solidity than the one being used in the tutorial, as the tutorial was made over a year ago. This caused some version conflicts and warnings relating to deprecation. Many of these I could resolve by finding newer ways to achieve the same result. Solidity is still a relatively new language, and the developers are constantly adding new features to it.

Metamask RPC Error

The challenge that took me the longest to resolve was to overcome the following error:

After a lot of digging around, I still wasn’t able to find the solution. I even downloaded the GitHub repository, but the Dapp still didn’t work.

The problem essentially was the fact that the function which staked the tokens was not asynchronous, meaning you basically had 0 seconds to confirm the transaction with Metamask.

How I Overcame This Problem

This challenge was not easy to overcome. I just wasn’t able to figure out where exactly in the code, and why, this error was occurring. When I saw that it was a Metamask RPC Error, I thought the problem had to be with Metamask, and the Ganache network it was running on. I tried researching around the chainID that went on the Ganache network, but that didn’t help. This was not the case.

I searched this error up and tried applying solutions from various websites like Stack Overflow, YouTube, Reddit, and Github, but that didn’t work either. I reached out to various people in the blockchain community and was finally able to pinpoint the problem and find the solution.

stakeTokens = (amount) => {  this.setState({ loading: true })   this.state.daiToken.methods.approve(this.state.tokenFarm._address, amount).send({ from: this.state.account }).on('transactionHash', async (hash) => {    this.state.tokenFarm.methods.stakeTokens(amount).send({ from: this.state.account }).on('transactionHash', (hash) => {      this.setState({ loading: false })
})
})}

This was my stakeTokens function originally. It didn’t have any async’s or await’s, although they were essential to the code working. But what really are async’s and await’s?

When adding an async keyword to a function, it defines that function as asynchronous. Asynchronous means that the function isn’t executed immediately, and it may take more time to go through all the lines of code. We then use the await keyword on certain lines of code to show that these are the lines we must wait for to be executed.

After implementing these changes, here’s the new code that works.

stakeTokens = async (amount) => {  this.setState({ loading: true })  await this.state.daiToken.methods.approve(this.state.tokenFarm._address, amount).send({ from: this.state.account }).on('transactionHash', async (hash) => {    await this.state.tokenFarm.methods.stakeTokens(amount).send({ from: this.state.account }).on('transactionHash', (hash) => {      this.setState({ loading: false })    })  })}

The difference between the two blocks of code is that now I’m waiting for the lines to be executed before doing anything else.

In retrospect, I am quite sure that the problem was with the fact that Metamask’s API had probably changed since the tutorial was made.

Project Walkthrough

Folder Structure

  • The migrations folder stores the files needed for migrating and deploying the contracts onto the blockchain.
  • The node_modules folder stores all of the dependencies we’re using for the project. This folder gets created when you install dependencies for the project.
  • The public folder contains the files required for the frontend.
  • The scripts folder contains scripts necessary for yield farming.
  • The src (source) folder contains most of the code we’re writing, like all the smart contracts in Solidity, and all the React components we’re using.
  • The test folder is used to make sure there are no possible bugs before we deploy the contract.

Source Folder

This folder is the place where all of the source code is located.

  • The abis folder stores all of the Application Binary Interface (ABI) files, which are essentially the smart contracts converted into JSON code. Each ABI file corresponds to a smart contract.
  • The components folder stores all of our React components needed for the frontend.
  • The contracts folder stores all of the smart contracts we deploy to the blockchain.

Demo

Here is a quick video that demonstrates how this Dapp works.

Takeaways from this Project

Here are some things I took note of while working on this project:

Environmental Factors

The blockchain software environment is continuously changing. Over the course of just over a year, the Solidity version changed from 0.8.0 to 0.8.11. In the same way, Metamask and Ganache are undergoing changes. The best way to work around these types of changes is to always look at the documentation.

Solidity is constantly being developed, and many times things don’t work as expected because of the rapidly changing environmental challenges. For example, compatibility, minor changes in API, deprecations, and the list goes on. The best way to work around these types of changes is to always look at the documentation.

Metamask

I learned a lot about how Metamask works, specifically with importing accounts by using the private key. I never knew this was an option in Metamask, and it certainly will help me the next time I need test accounts for a project.

Ganache vs Other Options

I have been successful using Ganache so far, but other platforms for testing code on blockchains exist, like Hardhat or OpenZeppelin that I would like to try out next.

Utilize your Community

The way I solved this problem was by reaching out to other people in the blockchain development community. I got help from various people who helped me solve the problem, and it was thanks to those people that I was able to see the Dapp actually work.

Next Steps

I’ve learned a lot about development in the Web3 space over the course of these past few weeks. For my next project, I’ll build a Dapp that utilizes Rust and React, and is deployed on the Solana blockchain. This will allow me to learn similarities and differences in building apps on different platforms and will push me further to becoming a blockchain developer who is skilled in many languages.

--

--