DEV Community

Cover image for Kickoff: Smart Contracts and Serverless Backend for Your Soccer Raffle (Part 1)
IG
IG

Posted on • Edited on

Kickoff: Smart Contracts and Serverless Backend for Your Soccer Raffle (Part 1)

ARTICLE 1: Smart Contracts & Backend Infrastructure

Introduction

Welcome to the first part of our three-part series on building a decentralized soccer raffle platform. In this article, we’ll lay the blockchain foundation:

  • Deploy smart contracts to the Lisk Sepolia testnet
  • Set up Firebase Cloud Functions to serve blockchain data without gas costs

By the end, you’ll have a working backend ready for a Flutter frontend to interact with.

Follow along with the repo or watch the video

What You'll Learn

  • Deploying provably fair raffle contracts
  • Creating custom ERC20 test tokens
  • Setting up serverless blockchain APIs
  • Best practices for contract security

Prerequisites

  • Node.js 18+
  • Basic Solidity knowledge
  • Firebase account
  • Lisk Sepolia testnet ETH (get from faucet)

⚠️ Note: To keep things manageable, this article is split into two parts:

  • Part 1 (this article): Deploy the raffle token and a simple raffle contract
  • Part 2: Extend the contract to accept predictions and automatically distribute prizes

Part 1: Understanding the Architecture

The Three-Layer System

┌───────────────────────────────┐
│ Layer 3: Flutter Mobile App   │
│ (User Interface - Article 2) │
└─────────────┬─────────────────┘
              │
┌─────────────▼─────────────────┐
│ Layer 2: Firebase Functions    │
│ (Serverless API - This Article)│
└─────────────┬─────────────────┘
              │
┌─────────────▼─────────────────┐
│ Layer 1: Smart Contracts       │
│ (Blockchain Logic - This Article) │
│ ├── RaffleToken (RTKN)        │
│ └── SoccerRaffle               │
└───────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Why this architecture?

  • Layer 1 (Smart Contracts): Handles money and trust — must live on-chain
  • Layer 2 (Cloud Functions): Handles reads — free for users browsing
  • Layer 3 (Flutter App): Handles UX — hides blockchain complexity

Part 2: Smart Contract Development

2.1: RaffleToken (RTKN)

Custom tokens are essential for:

  • Testing: Easy onboarding via faucet
  • Control: Manage supply and distribution
  • Branding: Custom name and symbol

We use 6 decimals to match USDT precision and avoid confusion.

Key Features:

  • decimals(): 6 → 1 RTKN = 1,000,000 units on-chain
  • faucet(): Lets anyone claim tokens for testing

Create contracts/RaffleToken.sol:


2.2: SoccerRaffle Contract

This contract manages all raffle logic. Core features include:

  • Commit-Reveal Randomness: Ensures fair winner selection
  • Emergency Draw: Allows anyone to trigger a fallback if the creator fails to reveal the seed
  • ReentrancyGuard: Protects token transfers from attacks

Create contracts/SoccerRaffle.sol:


Part 3: Hardhat Setup & Deployment

3.1: Initialize Project

mkdir soccer-raffle
cd soccer-raffle
npm init -y
npm install --save-dev hardhat @openzeppelin/contracts dotenv
npx hardhat init  # TypeScript project
Enter fullscreen mode Exit fullscreen mode

3.2: Configure Hardhat

Create hardhat.config.ts:

3.3: Environment Variables

DEPLOYER_PRIVATE_KEY=your_private_key_here
LISK_TESTNET_RPC=https://rpc.sepolia-api.lisk.com
Enter fullscreen mode Exit fullscreen mode

⚠️ Add .env to .gitignore

3.4: Deployment Scripts

  • scripts/deployRaffleToken.ts
  • scripts/deploySoccerRaffle.ts

Deploy:

npx hardhat run scripts/deployRaffleToken.ts --network liskTestnet
npx hardhat run scripts/deploySoccerRaffle.ts --network liskTestnet
Enter fullscreen mode Exit fullscreen mode

Expected output:

✅ RaffleToken deployed at: 0x07Aa1131A1C06B4680458b0547528272BB603358
✅ SoccerRaffle deployed at: 0x5c6A781D663B689b7975A6339AD3eDe910023C6d
Enter fullscreen mode Exit fullscreen mode

Part 4: Firebase Cloud Functions

Why Cloud Functions?

  • Allows users to browse raffles for free
  • Only pay gas when joining
  • Improves UX and conversion

Setup

npm install -g firebase-tools
firebase login
firebase init functions  # TypeScript, ESLint, install deps
cd functions
npm install ethers
Enter fullscreen mode Exit fullscreen mode

Create functions/src/contracts/SoccerRaffleABI.ts:

Implement functions/src/index.ts:

Deploy:

cd functions
npm run build
firebase deploy --only functions
Enter fullscreen mode Exit fullscreen mode

Test endpoints with curl or Postman.


Part 5: Creating Test Raffles

Create scripts/createTestRaffle.ts:

Run:

npx hardhat run scripts/createTestRaffle.ts --network liskTestnet
Enter fullscreen mode Exit fullscreen mode

Part 6: Security Best Practices

Implemented:

  • ReentrancyGuard
  • SafeERC20 for token transfers
  • Access control (Ownable)
  • Pausable functionality
  • Input validation

Recommendations:

  • Professional audit (OpenZeppelin / Trail of Bits)
  • Bug bounty program
  • Gradual rollout
  • Consider Nexus Mutual coverage

Deployment Checklist:

  1. Audit complete
  2. All tests passing
  3. Gas optimization done
  4. Admin keys secured (multisig)
  5. Monitoring enabled (Tenderly/Defender)
  6. Emergency pause tested
  7. Legal compliance verified

Conclusion

Deployed Infrastructure:

  • ✅ RaffleToken (RTKN) — 10M supply, 6 decimals, faucet enabled
  • ✅ SoccerRaffle Contract — commit-reveal, emergency draw
  • ✅ Firebase Functions — 8 endpoints, zero-gas reads

Key Takeaways:

  1. Test tokens simplify onboarding
  2. Commit-reveal ensures fairness
  3. Cloud functions improve UX
  4. Deploy token before raffle contract

Next Steps

Article 2: Build the Flutter mobile app:

  • Wallet creation and management
  • Seamless token approvals
  • Real-time transaction monitoring
  • Gas-free, smooth UX

Article 3: Extend contract & UI:

  • Accept user predictions
  • Determine winners automatically
  • Real-time updates and notifications
  • Polished, intuitive UX

Resources

Deployed Contracts:

  • RaffleToken: 0x07Aa1131A1C06B4680458b0547528272BB603358
  • SoccerRaffle: 0x5c6A781D663B689b7975A6339AD3eDe910023C6d

End of Article 1

Top comments (0)