DEV Community

Cover image for πŸ‹οΈ Day 10 of #30DaysOfSolidity β€” Building a Decentralized Fitness Tracker with Events & Milestones
Saurav Kumar
Saurav Kumar

Posted on

πŸ‹οΈ Day 10 of #30DaysOfSolidity β€” Building a Decentralized Fitness Tracker with Events & Milestones

Introduction

Today we’re building FitTrack, a decentralized fitness tracker on Ethereum! πŸƒβ€β™‚οΈπŸ’ͺ

The goal: allow users to log workouts, track progress, and unlock on-chain milestones like β€œ10 workouts in a week” or β€œ500 total minutes exercised.”

This project demonstrates how to use:

  • Events to log activity
  • Indexed parameters for efficient off-chain filtering
  • Structs and mappings for user data
  • Emitting events to notify milestones

Think of it as a backend for a decentralized fitness app, fully on-chain.


Key Concepts

  1. Events – Log important actions on the blockchain for transparency.
  2. Logging Data – Track user workouts with type, duration, calories, and timestamp.
  3. Indexed Parameters – Make events filterable by user for frontends or analytics tools.
  4. Emitting Events – Notify when users reach milestones.

Source Code

// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; /// @title FitTrack - A Decentralized Fitness Tracker /// @author Saurav /// @notice Log your workouts and unlock fitness milestones on-chain /// @dev Demonstrates event indexing, mappings, and user data tracking contract FitTrack { struct Workout { string workoutType; uint256 duration; // in minutes uint256 calories; uint256 timestamp; } struct UserStats { uint256 totalWorkouts; uint256 totalMinutes; uint256 totalCalories; uint256 lastWeekWorkouts; uint256 lastWeekStart; } mapping(address => Workout[]) private workouts; mapping(address => UserStats) public userStats; /// @notice Emitted when a workout is logged event WorkoutLogged(address indexed user, string workoutType, uint256 duration, uint256 calories); /// @notice Emitted when user reaches 10 workouts in a week event WeeklyGoalReached(address indexed user, uint256 workoutsCount); /// @notice Emitted when user reaches 500 total minutes milestone event TotalMinutesMilestone(address indexed user, uint256 totalMinutes); /// @dev Log a workout session function logWorkout(string memory _type, uint256 _duration, uint256 _calories) external { require(_duration > 0, "Duration must be greater than 0"); Workout memory newWorkout = Workout({ workoutType: _type, duration: _duration, calories: _calories, timestamp: block.timestamp }); workouts[msg.sender].push(newWorkout); UserStats storage stats = userStats[msg.sender]; stats.totalWorkouts += 1; stats.totalMinutes += _duration; stats.totalCalories += _calories; // Weekly logic if (block.timestamp > stats.lastWeekStart + 7 days) { stats.lastWeekStart = block.timestamp; stats.lastWeekWorkouts = 0; } stats.lastWeekWorkouts += 1; emit WorkoutLogged(msg.sender, _type, _duration, _calories); // Check milestones if (stats.lastWeekWorkouts == 10) { emit WeeklyGoalReached(msg.sender, stats.lastWeekWorkouts); } if (stats.totalMinutes >= 500 && (stats.totalMinutes - _duration) < 500) { emit TotalMinutesMilestone(msg.sender, stats.totalMinutes); } } /// @notice Get all workouts of a user function getWorkouts(address _user) external view returns (Workout[] memory) { return workouts[_user]; } /// @notice Get user's current stats function getUserStats(address _user) external view returns (UserStats memory) { return userStats[_user]; } } 
Enter fullscreen mode Exit fullscreen mode

How It Works

  1. Users call logWorkout() with:
  • workoutType (e.g., Running, Yoga)
  • duration in minutes
  • calories burned
  1. The contract updates UserStats (total workouts, minutes, calories).

  2. Events are emitted:

  • WorkoutLogged β†’ every workout
  • WeeklyGoalReached β†’ 10 workouts in a week
  • TotalMinutesMilestone β†’ when total minutes reach 500
  1. Frontends or analytics tools can filter events by user using the indexed parameters for dashboards or notifications.

Key Learnings

  • How to structure user data with structs and mappings.
  • Implement time-based logic (weekly progress).
  • Create on-chain achievement systems.
  • Use events with indexed parameters for real-time tracking.

Next Steps

  • Integrate a frontend DApp to visualize workouts and achievements.
  • Mint NFT badges for milestones.
  • Add reward tokens for consistency.
  • Create leaderboards for global competition.

πŸ’‘ Takeaway: Solidity isn’t just for finance β€” you can build fitness trackers, games, and lifestyle apps on-chain using the same principles.

Top comments (0)