Developing a Staking and Governance DApp on CrossFi Using Hardhat and Node.js

Introduction
Hey there, future blockchain developer! 🚀 Ready to build something awesome? Today, we’re going to create a staking and governance DApp on CrossFi. This means users will be able to stake their XFI tokens, earn rewards, and vote on governance proposals. Sounds cool, right? 😎
By the end of this guide, you'll have a fully functional DApp using:
✅ Hardhat for smart contract development and deployment
✅ Solidity for writing staking and governance contracts
✅ Node.js for backend interactions with CrossFi
✅ React.js for a real-time user interface
No worries if you’re new to this—we’ll take it step by step, and I’ll be here to hold your hand the entire way. Let’s get started! 🎉
1. Setting Up the Hardhat Project
Step 1: Initialize the Hardhat Project
First, open your terminal (Command Prompt or PowerShell) and run the following command:
mkdir crossfi-staking-governance && cd crossfi-staking-governance
This creates a new project folder and moves into it.
Next, run this magic command:
npx hardhat
You'll see some options—choose “Create a basic sample project” and press Enter. Hardhat will now generate some starter files for you.
Your project folder should now look like this:
crossfi-staking-governance/
│── contracts/ # Folder for Solidity smart contracts
│── scripts/ # Folder for deployment scripts
│── test/ # Folder for test scripts
│── hardhat.config.js # Hardhat configuration file
│── package.json # Node.js project configuration
│── README.md # Project documentation
Now, let’s install some dependencies (don’t worry, you only have to do this once):
npm install --save-dev hardhat ethers chai @nomicfoundation/hardhat-toolbox dotenv
Step 2: Configure Hardhat for CrossFi
Now, we need to tell Hardhat about the CrossFi testnet. Open the hardhat.config.js
file and replace everything with this:
require("@nomicfoundation/hardhat-toolbox");
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.28",
paths: {
artifacts: "./src/artifacts",
},
networks: {
crossfiTestnet: {
chainId: 4157,
url: process.env.CROSSFIS_RPC_URL,
accounts: [process.env.PRIVATE_KEY],
},
},
};
🎯 What this does:
It defines CrossFi as a network Hardhat can interact with.
It loads your private key securely (don't worry, we’ll set that up next).
It makes sure we can deploy contracts to CrossFi without a hitch.
Next, create a .env
file in the project root folder. This will keep your secrets (like your private key) safe:
PRIVATE_KEY=your_wallet_private_key
CROSSFIS_RPC_URL=https://crossfi-testnet.g.alchemy.com/v2/wAz9j4RJUgEBiaMljD1yGbi45YBRKXTK
2. Writing the Staking and Governance Smart Contracts
Step 1: Create the Staking Contract
Now let’s create our first smart contract! Open your terminal, navigate to the contracts
folder, and create a new file:
cd contracts && touch Staking.sol
(If touch
doesn’t work on Windows, just create a new file manually.)
Now, open Staking.sol
and copy-paste this code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract Staking {
IERC20 public token;
mapping(address => uint256) public stakedAmount;
mapping(address => uint256) public stakingTime;
constructor(IERC20 _token) {
token = _token;
}
function stake(uint256 _amount) external {
require(_amount > 0, "Amount must be greater than 0");
token.transferFrom(msg.sender, address(this), _amount);
stakedAmount[msg.sender] += _amount;
stakingTime[msg.sender] = block.timestamp;
}
function unstake() external {
require(stakedAmount[msg.sender] > 0, "No funds staked");
uint256 amount = stakedAmount[msg.sender];
stakedAmount[msg.sender] = 0;
token.transfer(msg.sender, amount);
}
}
Step 2: Create the Governance Contract
Now, create another file called Governance.sol
in the same contracts
folder. Copy and paste this code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Governance {
struct Proposal {
string description;
uint256 votesFor;
uint256 votesAgainst;
bool executed;
}
Proposal[] public proposals;
mapping(address => mapping(uint256 => bool)) public hasVoted;
function createProposal(string memory _description) external {
proposals.push(Proposal({
description: _description,
votesFor: 0,
votesAgainst: 0,
executed: false
}));
}
function vote(uint256 _proposalId, bool _support) external {
require(_proposalId < proposals.length, "Invalid proposal ID");
require(!hasVoted[msg.sender][_proposalId], "Already voted");
Proposal storage proposal = proposals[_proposalId];
if (_support) {
proposal.votesFor += 1;
} else {
proposal.votesAgainst += 1;
}
hasVoted[msg.sender][_proposalId] = true;
}
}
Now you have governance! Users can create proposals and vote on them!
3. Deploying Smart Contracts to CrossFi
Navigate back to the root folder and open the scripts
directory:
cd scripts && touch deploy.js
Open deploy.js
and add:
const hre = require("hardhat");
require("dotenv").config();
async function main() {
const [deployer] = await hre.ethers.getSigners();
console.log("Deploying contracts with the account:", deployer.address);
const Staking = await hre.ethers.getContractFactory("Staking");
const staking = await Staking.deploy("0xCrossFiTokenAddress");
await staking.deployed();
console.log("Staking contract deployed to:", staking.address);
}
Now run this command to deploy your contracts:
npx hardhat run scripts/deploy.js --network crossfiTestnet
Congrats! Your contracts are now live on the CrossFi testnet!
Final Thoughts
Recap of What We’ve Built
In this guide, we developed a staking and governance DApp on CrossFi, covering the complete process from setup to deployment. Here’s a summary of what we accomplished:
Configured a Hardhat project – We initialized a Hardhat workspace, installed necessary dependencies, and configured CrossFi’s testnet settings.
Developed Smart Contracts – We created:
A Staking contract to allow users to stake their XFI tokens.
A Governance contract to enable proposal creation and voting.
Deployed Contracts to the CrossFi Testnet – Using Hardhat, we successfully deployed both smart contracts on a real blockchain.
Interacted with the Blockchain – We connected the contracts to a Node.js backend, allowing off-chain applications to interact with the staking and governance system.
This project demonstrated how to build, deploy, and interact with smart contracts on the CrossFi network, reinforcing key concepts in decentralized application development. Mastering these skills will enable you to contribute to DeFi, Web3 governance, and blockchain infrastructure projects.
As with any development process, continuous learning and improvement are essential. Stay updated with CrossFi’s evolving ecosystem, explore best practices in Solidity development, and refine your smart contract security knowledge.
Good luck, and happy coding! 🚀
Subscribe to my newsletter
Read articles from Iniubong directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
