> ## Documentation Index
> Fetch the complete documentation index at: https://core.anylayer.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Score Calculator Events

> Complete reference for all Score Calculator contract events

## Overview

The ZKScore Score Calculator contract emits events for all significant score changes and configuration updates. These events are essential for tracking score evolution, monitoring calculation activity, and building real-time applications.

<Tip>
  Events are stored on the blockchain and can be efficiently queried by indexers. They provide a reliable audit trail for all score changes and system updates.
</Tip>

## Score Events

### ScoreCalculated

Emitted when a new score is calculated for a user.

```solidity theme={null}
event ScoreCalculated(
    address indexed user,
    uint256 totalScore,
    uint256 timestamp
);
```

**Parameters:**

* `user` (address indexed): The user whose score was calculated
* `totalScore` (uint256): The calculated total score (0-1000)
* `timestamp` (uint256): Block timestamp of calculation

**When Emitted:**

* When `calculateScore()` is called
* During batch score calculations
* When scores are automatically refreshed

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Listen for score calculation events
  contract.on('ScoreCalculated', (user, totalScore, timestamp, event) => {
    console.log(`Score calculated for ${user}: ${totalScore.toString()}`);
    console.log(`Timestamp: ${new Date(timestamp.toNumber() * 1000).toISOString()}`);
    console.log(`Block: ${event.blockNumber}`);
  });

  // Filter for specific user
  const filter = contract.filters.ScoreCalculated('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb');
  contract.on(filter, (user, totalScore, timestamp, event) => {
    console.log(`Alice's score updated: ${totalScore.toString()}`);
  });

  // Get historical score calculations
  async function getScoreHistory(userAddress) {
    const filter = contract.filters.ScoreCalculated(userAddress);
    const events = await contract.queryFilter(filter);
    
    return events.map(event => ({
      score: event.args.totalScore.toString(),
      timestamp: event.args.timestamp.toNumber(),
      blockNumber: event.blockNumber,
      transactionHash: event.transactionHash
    }));
  }
  ```

  ```python Python theme={null}
  # Listen for score calculation events
  def handle_score_calculated(event):
      user = event['args']['user']
      total_score = event['args']['totalScore']
      timestamp = event['args']['timestamp']
      
      print(f"Score calculated for {user}: {total_score}")
      print(f"Timestamp: {timestamp}")
      print(f"Block: {event['blockNumber']}")

  # Set up event listener
  contract.events.ScoreCalculated().on('data', handle_score_calculated)

  # Filter for specific user
  filter = contract.events.ScoreCalculated.createFilter(
      fromBlock='latest',
      argument_filters={'user': '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'}
  )

  # Get historical score calculations
  def get_score_history(user_address):
      filter = contract.events.ScoreCalculated.createFilter(
          fromBlock=0,
          argument_filters={'user': user_address}
      )
      events = filter.get_all_entries()
      
      return [{
          'score': event['args']['totalScore'],
          'timestamp': event['args']['timestamp'],
          'blockNumber': event['blockNumber'],
          'transactionHash': event['transactionHash'].hex()
      } for event in events]
  ```
</CodeGroup>

### ScoreUpdated

Emitted when a user's score changes.

```solidity theme={null}
event ScoreUpdated(
    address indexed user,
    uint256 oldScore,
    uint256 newScore
);
```

**Parameters:**

* `user` (address indexed): The user whose score changed
* `oldScore` (uint256): Previous score value
* `newScore` (uint256): New score value

**When Emitted:**

* When score recalculation results in a different value
* After category score updates
* During manual score refreshes

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Monitor score changes
  contract.on('ScoreUpdated', (user, oldScore, newScore, event) => {
    const change = newScore.sub(oldScore);
    const direction = change.isNegative() ? 'decreased' : 'increased';
    
    console.log(`Score ${direction} for ${user}`);
    console.log(`Old: ${oldScore.toString()}, New: ${newScore.toString()}`);
    console.log(`Change: ${Math.abs(change.toNumber())}`);
  });

  // Track score improvements
  async function trackScoreImprovements() {
    const filter = contract.filters.ScoreUpdated();
    const events = await contract.queryFilter(filter);
    
    const improvements = events.filter(event => 
      event.args.newScore.gt(event.args.oldScore)
    );
    
    console.log(`${improvements.length} score improvements detected`);
    return improvements;
  }
  ```

  ```python Python theme={null}
  # Monitor score changes
  def handle_score_updated(event):
      user = event['args']['user']
      old_score = event['args']['oldScore']
      new_score = event['args']['newScore']
      
      change = new_score - old_score
      direction = 'decreased' if change < 0 else 'increased'
      
      print(f"Score {direction} for {user}")
      print(f"Old: {old_score}, New: {new_score}")
      print(f"Change: {abs(change)}")

  # Set up event listener
  contract.events.ScoreUpdated().on('data', handle_score_updated)

  # Track score improvements
  def track_score_improvements():
      filter = contract.events.ScoreUpdated.createFilter(fromBlock=0)
      events = filter.get_all_entries()
      
      improvements = [e for e in events if e['args']['newScore'] > e['args']['oldScore']]
      
      print(f"{len(improvements)} score improvements detected")
      return improvements
  ```
</CodeGroup>

### CategoryScoreUpdated

Emitted when a category score is updated.

```solidity theme={null}
event CategoryScoreUpdated(
    address indexed user,
    uint8 indexed category,
    uint256 score
);
```

**Parameters:**

* `user` (address indexed): The user whose category score was updated
* `category` (uint8 indexed): Category index (0-7)
* `score` (uint256): New category score (0-1000)

**Category Mapping:**

* 0: DeFi
* 1: NFT
* 2: Social
* 3: Trading
* 4: Governance
* 5: Gaming
* 6: Identity
* 7: Trust

**When Emitted:**

* When `updateCategoryScore()` is called
* During batch category updates
* When individual category recalculation occurs

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Monitor category score updates
  const categories = ['DeFi', 'NFT', 'Social', 'Trading', 'Governance', 'Gaming', 'Identity', 'Trust'];

  contract.on('CategoryScoreUpdated', (user, category, score, event) => {
    console.log(`${categories[category]} score for ${user}: ${score.toString()}`);
  });

  // Track DeFi score updates
  const defiFilter = contract.filters.CategoryScoreUpdated(null, 0); // 0 = DeFi
  contract.on(defiFilter, (user, category, score, event) => {
    console.log(`DeFi score updated for ${user}: ${score.toString()}`);
  });

  // Get category score history
  async function getCategoryHistory(userAddress, category) {
    const filter = contract.filters.CategoryScoreUpdated(userAddress, category);
    const events = await contract.queryFilter(filter);
    
    return events.map(event => ({
      category: categories[event.args.category],
      score: event.args.score.toString(),
      blockNumber: event.blockNumber,
      timestamp: event.args.timestamp
    }));
  }
  ```

  ```python Python theme={null}
  # Monitor category score updates
  categories = ['DeFi', 'NFT', 'Social', 'Trading', 'Governance', 'Gaming', 'Identity', 'Trust']

  def handle_category_score_updated(event):
      user = event['args']['user']
      category = event['args']['category']
      score = event['args']['score']
      
      print(f"{categories[category]} score for {user}: {score}")

  # Set up event listener
  contract.events.CategoryScoreUpdated().on('data', handle_category_score_updated)

  # Track DeFi score updates
  defi_filter = contract.events.CategoryScoreUpdated.createFilter(
      fromBlock='latest',
      argument_filters={'category': 0}  # 0 = DeFi
  )

  # Get category score history
  def get_category_history(user_address, category):
      filter = contract.events.CategoryScoreUpdated.createFilter(
          fromBlock=0,
          argument_filters={'user': user_address, 'category': category}
      )
      events = filter.get_all_entries()
      
      return [{
          'category': categories[event['args']['category']],
          'score': event['args']['score'],
          'blockNumber': event['blockNumber']
      } for event in events]
  ```
</CodeGroup>

## Configuration Events

### CategoryWeightUpdated

Emitted when a category weight is changed.

```solidity theme={null}
event CategoryWeightUpdated(
    uint8 indexed category,
    uint256 oldWeight,
    uint256 newWeight
);
```

**Parameters:**

* `category` (uint8 indexed): Category index (0-7)
* `oldWeight` (uint256): Previous weight in basis points
* `newWeight` (uint256): New weight in basis points

**When Emitted:**

* When `updateCategoryWeight()` is called
* During batch weight updates
* When category weights are reconfigured

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Monitor weight changes
  contract.on('CategoryWeightUpdated', (category, oldWeight, newWeight, event) => {
    const categories = ['DeFi', 'NFT', 'Social', 'Trading', 'Governance', 'Gaming', 'Identity', 'Trust'];
    
    console.log(`${categories[category]} weight changed`);
    console.log(`Old: ${oldWeight.toNumber() / 100}%`);
    console.log(`New: ${newWeight.toNumber() / 100}%`);
  });

  // Get all weight changes
  async function getWeightChanges() {
    const filter = contract.filters.CategoryWeightUpdated();
    const events = await contract.queryFilter(filter);
    
    return events.map(event => ({
      category: event.args.category,
      oldWeight: event.args.oldWeight.toNumber() / 100,
      newWeight: event.args.newWeight.toNumber() / 100,
      blockNumber: event.blockNumber
    }));
  }
  ```

  ```python Python theme={null}
  # Monitor weight changes
  categories = ['DeFi', 'NFT', 'Social', 'Trading', 'Governance', 'Gaming', 'Identity', 'Trust']

  def handle_weight_updated(event):
      category = event['args']['category']
      old_weight = event['args']['oldWeight']
      new_weight = event['args']['newWeight']
      
      print(f"{categories[category]} weight changed")
      print(f"Old: {old_weight / 100}%")
      print(f"New: {new_weight / 100}%")

  # Set up event listener
  contract.events.CategoryWeightUpdated().on('data', handle_weight_updated)

  # Get all weight changes
  def get_weight_changes():
      filter = contract.events.CategoryWeightUpdated.createFilter(fromBlock=0)
      events = filter.get_all_entries()
      
      return [{
          'category': event['args']['category'],
          'oldWeight': event['args']['oldWeight'] / 100,
          'newWeight': event['args']['newWeight'] / 100,
          'blockNumber': event['blockNumber']
      } for event in events]
  ```
</CodeGroup>

### CalculatorConfigured

Emitted when the calculator is configured or reconfigured.

```solidity theme={null}
event CalculatorConfigured(
    address indexed admin,
    uint256 timestamp
);
```

**Parameters:**

* `admin` (address indexed): Admin who performed the configuration
* `timestamp` (uint256): Configuration timestamp

**When Emitted:**

* During initial deployment configuration
* When major configuration changes occur
* When admin reconfigures the calculator

## Event Monitoring

### Real-time Score Tracking

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Comprehensive score monitoring
  class ScoreMonitor {
    constructor(contract) {
      this.contract = contract;
      this.scoreHistory = new Map();
      this.setupListeners();
    }
    
    setupListeners() {
      // Track all score calculations
      this.contract.on('ScoreCalculated', (user, totalScore, timestamp, event) => {
        this.recordScore(user, totalScore, timestamp, event);
      });
      
      // Track score updates
      this.contract.on('ScoreUpdated', (user, oldScore, newScore, event) => {
        this.recordScoreChange(user, oldScore, newScore, event);
      });
      
      // Track category updates
      this.contract.on('CategoryScoreUpdated', (user, category, score, event) => {
        this.recordCategoryUpdate(user, category, score, event);
      });
    }
    
    recordScore(user, totalScore, timestamp, event) {
      if (!this.scoreHistory.has(user)) {
        this.scoreHistory.set(user, []);
      }
      
      this.scoreHistory.get(user).push({
        score: totalScore.toString(),
        timestamp: timestamp.toNumber(),
        blockNumber: event.blockNumber,
        type: 'calculated'
      });
      
      console.log(`Score calculated: ${user} - ${totalScore.toString()}`);
    }
    
    recordScoreChange(user, oldScore, newScore, event) {
      const change = newScore.sub(oldScore).toNumber();
      const percentChange = ((change / oldScore.toNumber()) * 100).toFixed(2);
      
      console.log(`Score changed: ${user}`);
      console.log(`  ${oldScore.toString()} → ${newScore.toString()}`);
      console.log(`  Change: ${change} (${percentChange}%)`);
    }
    
    recordCategoryUpdate(user, category, score, event) {
      const categories = ['DeFi', 'NFT', 'Social', 'Trading', 'Governance', 'Gaming', 'Identity', 'Trust'];
      console.log(`${categories[category]} updated: ${user} - ${score.toString()}`);
    }
    
    getUserHistory(user) {
      return this.scoreHistory.get(user) || [];
    }
    
    getTopPerformers(limit = 10) {
      const performers = [];
      
      for (const [user, history] of this.scoreHistory.entries()) {
        if (history.length > 0) {
          const latestScore = parseInt(history[history.length - 1].score);
          performers.push({ user, score: latestScore });
        }
      }
      
      return performers.sort((a, b) => b.score - a.score).slice(0, limit);
    }
  }

  // Usage
  const monitor = new ScoreMonitor(contract);
  ```

  ```python Python theme={null}
  # Comprehensive score monitoring
  class ScoreMonitor:
      def __init__(self, contract):
          self.contract = contract
          self.score_history = {}
          self.setup_listeners()
      
      def setup_listeners(self):
          # Track all score calculations
          self.contract.events.ScoreCalculated().on('data', self.record_score)
          
          # Track score updates
          self.contract.events.ScoreUpdated().on('data', self.record_score_change)
          
          # Track category updates
          self.contract.events.CategoryScoreUpdated().on('data', self.record_category_update)
      
      def record_score(self, event):
          user = event['args']['user']
          total_score = event['args']['totalScore']
          timestamp = event['args']['timestamp']
          
          if user not in self.score_history:
              self.score_history[user] = []
          
          self.score_history[user].append({
              'score': total_score,
              'timestamp': timestamp,
              'blockNumber': event['blockNumber'],
              'type': 'calculated'
          })
          
          print(f"Score calculated: {user} - {total_score}")
      
      def record_score_change(self, event):
          user = event['args']['user']
          old_score = event['args']['oldScore']
          new_score = event['args']['newScore']
          
          change = new_score - old_score
          percent_change = (change / old_score * 100) if old_score > 0 else 0
          
          print(f"Score changed: {user}")
          print(f"  {old_score} → {new_score}")
          print(f"  Change: {change} ({percent_change:.2f}%)")
      
      def record_category_update(self, event):
          user = event['args']['user']
          category = event['args']['category']
          score = event['args']['score']
          
          categories = ['DeFi', 'NFT', 'Social', 'Trading', 'Governance', 'Gaming', 'Identity', 'Trust']
          print(f"{categories[category]} updated: {user} - {score}")
      
      def get_user_history(self, user):
          return self.score_history.get(user, [])
      
      def get_top_performers(self, limit=10):
          performers = []
          
          for user, history in self.score_history.items():
              if history:
                  latest_score = history[-1]['score']
                  performers.append({'user': user, 'score': latest_score})
          
          return sorted(performers, key=lambda x: x['score'], reverse=True)[:limit]

  # Usage
  monitor = ScoreMonitor(contract)
  ```
</CodeGroup>

### Event Analytics

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Analyze score trends
  async function analyzeScoreTrends() {
    const currentBlock = await provider.getBlockNumber();
    const startBlock = currentBlock - 100000; // Last 100k blocks
    
    const filter = contract.filters.ScoreCalculated();
    const events = await contract.queryFilter(filter, startBlock, currentBlock);
    
    const analytics = {
      totalCalculations: events.length,
      uniqueUsers: new Set(events.map(e => e.args.user)).size,
      averageScore: 0,
      scoreDistribution: { low: 0, medium: 0, high: 0 },
      topScorers: []
    };
    
    // Calculate average
    const totalScore = events.reduce((sum, e) => sum + e.args.totalScore.toNumber(), 0);
    analytics.averageScore = totalScore / events.length;
    
    // Distribution
    events.forEach(event => {
      const score = event.args.totalScore.toNumber();
      if (score < 300) analytics.scoreDistribution.low++;
      else if (score < 700) analytics.scoreDistribution.medium++;
      else analytics.scoreDistribution.high++;
    });
    
    // Top scorers
    const userScores = new Map();
    events.forEach(event => {
      userScores.set(event.args.user, event.args.totalScore.toNumber());
    });
    
    analytics.topScorers = Array.from(userScores.entries())
      .sort((a, b) => b[1] - a[1])
      .slice(0, 10)
      .map(([user, score]) => ({ user, score }));
    
    return analytics;
  }
  ```

  ```python Python theme={null}
  # Analyze score trends
  def analyze_score_trends():
      current_block = w3.eth.block_number
      start_block = current_block - 100000  # Last 100k blocks
      
      filter = contract.events.ScoreCalculated.createFilter(
          fromBlock=start_block,
          toBlock=current_block
      )
      events = filter.get_all_entries()
      
      analytics = {
          'totalCalculations': len(events),
          'uniqueUsers': len(set(e['args']['user'] for e in events)),
          'averageScore': 0,
          'scoreDistribution': {'low': 0, 'medium': 0, 'high': 0},
          'topScorers': []
      }
      
      # Calculate average
      total_score = sum(e['args']['totalScore'] for e in events)
      analytics['averageScore'] = total_score / len(events) if events else 0
      
      # Distribution
      for event in events:
          score = event['args']['totalScore']
          if score < 300:
              analytics['scoreDistribution']['low'] += 1
          elif score < 700:
              analytics['scoreDistribution']['medium'] += 1
          else:
              analytics['scoreDistribution']['high'] += 1
      
      # Top scorers
      user_scores = {}
      for event in events:
          user_scores[event['args']['user']] = event['args']['totalScore']
      
      analytics['topScorers'] = sorted(
          [{'user': user, 'score': score} for user, score in user_scores.items()],
          key=lambda x: x['score'],
          reverse=True
      )[:10]
      
      return analytics
  ```
</CodeGroup>

## Best Practices

### Event Handling

1. **Use Indexed Parameters**: Filter events efficiently using indexed parameters
2. **Batch Processing**: Process multiple events in batches
3. **Error Handling**: Implement robust error handling for event listeners
4. **Performance**: Limit block ranges for large queries
5. **Storage**: Store important event data in a database

### Monitoring Strategy

1. **Real-time Alerts**: Set up alerts for significant score changes
2. **Historical Analysis**: Regularly analyze historical event data
3. **User Tracking**: Track individual user score evolution
4. **System Health**: Monitor event emission rates
5. **Anomaly Detection**: Detect unusual score patterns

## Related Documentation

* [Contract Overview](/contracts/score-calculator/overview) - Contract architecture and features
* [Functions Reference](/contracts/score-calculator/functions) - Complete function documentation
* [Integration Guide](/contracts/score-calculator/integration) - Integration examples
* [Identity SBT](/contracts/identity-sbt/overview) - Identity contract documentation
