Building Your First Token-Gated Staking App on Rootstock (With RIF Tokens & Thirdweb)

Let me tell you about the time I built my first token-gated staking dApp on Rootstock. It was one of those projects that started as a "what if" idea and turned into a really rewarding learning experience.

I remember sitting there with my coffee, staring at the Rootstock documentation, wondering how to combine Bitcoin's security with Ethereum's smart contract flexibility.

Turns out, it's not as complicated as I thought - and I'm going to walk you through exactly how to do it.

Why This Project Changed How I Think About Web3

When I first heard about token-gating, I'll admit I was skeptical.

But after implementing it with RIF tokens, I saw how powerful it can be for creating exclusive communities. What really surprised me was how smoothly everything worked on Rootstock.

The Bitcoin-level security gave me peace of mind, while the EVM compatibility meant I could use all my favorite Ethereum tools.

Getting Started: What You'll Need

Before we dive in, let's get your workspace ready:

  • Node.js v18+ (Trust me, try Bun - it's like npm but after three cups of coffee)

  • MetaMask (We'll configure it for Rootstock together)

  • A Thirdweb account (It's free, and it saved me hours of deployment headaches)

  • Basic React/Solidity knowledge (Don't worry, we'll take it step by step)

I remember when I first set this up - I spent an embarrassing amount of time trying to configure MetaMask before realizing I'd typoed the Chain ID. Learn from my mistakes!

Step 1: Why Rootstock and RIF Tokens?

Here's what got me excited: Rootstack isn't just another Ethereum clone. It's:

  • Secured by Bitcoin's mining power (through something called merged mining)

  • EVM-compatible (meaning all your Ethereum tools work)

  • Uses RBTC for gas (which is pegged 1:1 with Bitcoin)

And RIF tokens? They're like the Swiss Army knife of the Rootstock ecosystem. We'll use them to create our token-gating mechanism - only RIF holders can stake in our dApp.

Step 2: Setting Up Your Environment

Installing Bun (My New Favorite Tool)

Remember when package installations took forever? Bun changes that. Just run:

“`curl -fsSL https://bun.sh/install | bash`”

The first time I ran this, I may or may not have fist-pumped when I saw how fast it was.

Configuring MetaMask for Rootstock

Here are the settings that worked for me:

Pro tip:

Getting the Starter Code

git clone https://github.com/lovesonnuel/TokenGated.git

You can also add Rootstock Networks to MetaMask Automatically

bun install

When I first cloned this, I was pleasantly surprised by how clean the structure was. It saved me so much boilerplate setup.

Step 3: Building the Staking Contract

This is where things get interesting. Let me share the key insights I learned while building the token-gating mechanism.

The RIF Balance Check (This Took Me a Few Tries)

Here's the implementation that finally worked for me:

solidity

// SPDX-License-Identifier: MIT pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract RIFGatedStaking { // RIF Token Addresses - I messed these up the first time! address public constant RIF_TESTNET = 0x19F64674D8A5B4E652319F5e239eFd3bc969A1fE; address public constant RIF_MAINNET = 0x2aCc95758f8b5F583470bA265Eb685a8f45fC9D5;

mapping(address => uint256) public stakingBalance;

function stake(uint256 amount) external {

require(

checkRIFBalance(msg.sender) >= 1 ether,

"You need at least 1 RIF to stake - go grab some first!"

);

_stake(msg.sender, amount);

}

function checkRIFBalance(address user) internal view returns (uint256) {

IERC20 rifToken = IERC20(RIF_TESTNET); // Remember to change to mainnet!

return rifToken.balanceOf(user);

}

function _stake(address user, uint256 amount) internal {

// Actual staking logic goes here

stakingBalance[user] += amount;

}

}

The first time I tested this, I forgot to switch to testnet RIF tokens in my wallet. Rookie mistake!

Step 4: Deploying with Thirdweb

I was skeptical about using another platform for deployment, but Thirdweb genuinely surprised me. Here's how it went:

  1. Go to Thirdweb Dashboard

  2. Selected "Deploy New Contract" → "Staking" template

  3. Configured with:

    • Name: My First RIF Staking

    • Description: Learning as I go!

  4. Click deploy and confirmed in MetaMask

The whole process took about 3 minutes. I timed it.

Step 5: Building the Frontend

This was the fun part - seeing everything come together. Here's the component that made me feel like a real Web3 developer:

javascript

import { useContract, useContractRead } from "@thirdweb-dev/react";

function StakingInterface() { const { contract } = useContract("YOUR_CONTRACT_ADDRESS"); const { data: stakedBalance } = useContractRead( contract, "getStakingBalance", [userAddress] );

const stakeTokens = async (amount) => { try { await contract.call("stake", [amount]); alert("Success! Your tokens are now staked."); } catch (error) { console.error("Oops, something went wrong:", error); } };

return (

Your Staked Balance: stakedBalance | '0'

<button onClick={() => stakeTokens(10)}> Stake 10 Tokens </button>

);}

The first time I saw "Success!" alert pop up? Magical.

Lessons Learned (The Hard Way)

  1. Testnet vs Mainnet: I once wasted an hour debugging before realizing I was on the wrong network. Now I always double-check.

  2. Gas Estimates: Rootstock transactions need a bit more gas than I initially thought. Adding 20% to the estimate solved my failed transactions.

  3. Token Addresses: Writing down the correct RIF addresses saved me countless headaches:

    • Testnet: 0x19F64674D8A5B4E652319F5e239eFd3bc969A1fE

    • Mainnet: 0x2aCc95758f8b5F583470bA265Eb685a8f45fC9D5

Where to Go From Here

This project opened my eyes to what's possible with Rootstock. Some ideas I'm playing with next:

  • Adding tiered rewards for long-term stakers

  • Creating a leaderboard for top stakers

  • Integrating with RIF's other services like storage

If you're as excited about this as I am, come join the conversation in the Rootstock Discord. I'm there pretty regularly, usually asking questions or sharing what I've learned.

Remember, every expert was once a beginner. My first staking contract had bugs that would make you laugh (they still make me cringe). But each mistake taught me something valuable. So dive in, make mistakes, and most importantly - have fun building!

Got stuck? Hit me up on Twitter @lovesonnuel. I'm happy to help fellow developers navigate these waters.

Enjoy!

Wrapping Up

You’ve just built a secure, token-gated staking dApp on Rootstock!

GitHub Repository Link: https://github.com/lovesonnuel/TokenGated.git

What’s Next?

  • Dive deeper into Rootstock’s docs [here] https://dev.rootstock.io

  • Optimize gas costs with transaction batching.

  • Join the Rootstock Discord for help and ideas!

Useful Links

Stuck? Ask in the Rootstock Discord https://discord.gg/rootstock

Other important links

Start experimenting with the Rootstock testnet today.

Developers Overview https://dev.rootstock.io/developers/

Testnet https://explorer.testnet.rootstock.io/

Engage with Rootstock on social media, join webinars, and participate in discussions.

Socials:

Follow on X: https://x.com/rootstock_io?s=21

Follow on Instagram: https://www.instagram.com/rootstock_io?igsh=OW0ydHBlNTQyZmZo

Discord: https://discord.com/invite/rootstock

0
Subscribe to my newsletter

Read articles from Emmanuel Uzodinma directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Emmanuel Uzodinma
Emmanuel Uzodinma