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 │
└───────────────────────────────┘
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
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
⚠️ Add .env to .gitignore
3.4: Deployment Scripts
scripts/deployRaffleToken.tsscripts/deploySoccerRaffle.ts
Deploy:
npx hardhat run scripts/deployRaffleToken.ts --network liskTestnet
npx hardhat run scripts/deploySoccerRaffle.ts --network liskTestnet
Expected output:
✅ RaffleToken deployed at: 0x07Aa1131A1C06B4680458b0547528272BB603358
✅ SoccerRaffle deployed at: 0x5c6A781D663B689b7975A6339AD3eDe910023C6d
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
Create functions/src/contracts/SoccerRaffleABI.ts:
Implement functions/src/index.ts:
Deploy:
cd functions
npm run build
firebase deploy --only functions
Test endpoints with curl or Postman.
Part 5: Creating Test Raffles
Create scripts/createTestRaffle.ts:
Run:
npx hardhat run scripts/createTestRaffle.ts --network liskTestnet
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:
- Audit complete
- All tests passing
- Gas optimization done
- Admin keys secured (multisig)
- Monitoring enabled (Tenderly/Defender)
- Emergency pause tested
- 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:
- Test tokens simplify onboarding
- Commit-reveal ensures fairness
- Cloud functions improve UX
- 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
- Lisk Docs
- OpenZeppelin Contracts
- Firebase Functions
- Ethers.js
- Lisk Faucet
- Blockscout Explorer
- Hardhat
Deployed Contracts:
- RaffleToken:
0x07Aa1131A1C06B4680458b0547528272BB603358 - SoccerRaffle:
0x5c6A781D663B689b7975A6339AD3eDe910023C6d
End of Article 1
Top comments (0)