> ## 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.

# Achievement Registry Functions

> Complete reference for all Achievement Registry contract functions

## Overview

This document provides a comprehensive reference for all functions available in the ZKScore Achievement Registry contract. Each function includes detailed parameter descriptions, return values, gas estimates, and usage examples.

<Tip>
  All functions that modify state require a transaction and will consume gas. View functions are free to call and return data immediately.
</Tip>

## Achievement Management Functions

### createAchievement

Create a new achievement in the registry.

```solidity theme={null}
function createAchievement(
    string memory name,
    string memory description,
    string memory imageURI,
    uint8 category,
    Rarity rarity,
    uint256 points,
    uint256 scoreBoost,
    RequirementType requirementType,
    bytes memory requirementData
) external returns (uint256);
```

**Parameters:**

* `name` (string): Achievement name
* `description` (string): Achievement description
* `imageURI` (string): URI for achievement image/badge
* `category` (uint8): Category index (0-7)
* `rarity` (Rarity): Rarity level (0-4)
* `points` (uint256): Points awarded upon claiming
* `scoreBoost` (uint256): Score boost percentage (basis points)
* `requirementType` (RequirementType): Type of requirement verification
* `requirementData` (bytes): Encoded requirement data

**Returns:**

* `uint256`: The newly created achievement ID

**Gas Estimate:** \~200,000 gas

**Requirements:**

* Caller must have `CREATOR_ROLE`
* Name cannot be empty
* Points must be > 0
* Category must be valid (0-7)

**Events Emitted:**

* `AchievementCreated(uint256 indexed achievementId, string name, uint8 category, Rarity rarity)`

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  const { ethers } = require('ethers');

  async function createAchievement() {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    const signer = provider.getSigner();
    
    const contract = new ethers.Contract(
      '0x3456789012345678901234567890123456789012',
      ACHIEVEMENT_REGISTRY_ABI,
      signer
    );
    
    // Encode requirement data for score threshold
    const requirementData = ethers.utils.defaultAbiCoder.encode(
      ['uint256'],
      [500] // Minimum score of 500
    );
    
    const tx = await contract.createAchievement(
      'DeFi Explorer',
      'Use 5 different DeFi protocols',
      'ipfs://QmXyz.../defi-explorer.png',
      0, // DeFi category
      1, // UNCOMMON rarity
      100, // 100 points
      200, // 2% score boost (200 basis points)
      1, // SCORE_THRESHOLD requirement type
      requirementData
    );
    
    const receipt = await tx.wait();
    const event = receipt.events.find(e => e.event === 'AchievementCreated');
    const achievementId = event.args.achievementId;
    
    console.log(`Achievement created with ID: ${achievementId.toString()}`);
    return achievementId;
  }
  ```

  ```python Python theme={null}
  from web3 import Web3
  from eth_abi import encode

  def create_achievement():
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x3456789012345678901234567890123456789012',
          abi=ACHIEVEMENT_REGISTRY_ABI
      )
      
      account = w3.eth.account.from_key('YOUR_PRIVATE_KEY')
      
      # Encode requirement data for score threshold
      requirement_data = encode(['uint256'], [500])
      
      tx = contract.functions.createAchievement(
          'DeFi Explorer',
          'Use 5 different DeFi protocols',
          'ipfs://QmXyz.../defi-explorer.png',
          0,  # DeFi category
          1,  # UNCOMMON rarity
          100,  # 100 points
          200,  # 2% score boost
          1,  # SCORE_THRESHOLD requirement type
          requirement_data
      ).buildTransaction({
          'from': account.address,
          'gas': 250000,
          'gasPrice': w3.eth.gas_price,
          'nonce': w3.eth.get_transaction_count(account.address)
      })
      
      signed_tx = w3.eth.account.sign_transaction(tx, account.key)
      tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
      
      receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
      
      # Get achievement ID from event
      event = contract.events.AchievementCreated().processReceipt(receipt)[0]
      achievement_id = event['args']['achievementId']
      
      print(f"Achievement created with ID: {achievement_id}")
      return achievement_id
  ```
</CodeGroup>

### updateAchievement

Update an existing achievement's configuration.

```solidity theme={null}
function updateAchievement(
    uint256 achievementId,
    bytes memory updateData
) external;
```

**Parameters:**

* `achievementId` (uint256): ID of achievement to update
* `updateData` (bytes): Encoded update data

**Returns:** None

**Gas Estimate:** \~80,000 gas

**Requirements:**

* Caller must have `CREATOR_ROLE`
* Achievement must exist
* Achievement must be active

**Events Emitted:**

* `AchievementUpdated(uint256 indexed achievementId, bytes updateData)`

### deactivateAchievement

Deactivate an achievement (prevent new claims).

```solidity theme={null}
function deactivateAchievement(uint256 achievementId) external;
```

**Parameters:**

* `achievementId` (uint256): ID of achievement to deactivate

**Returns:** None

**Gas Estimate:** \~30,000 gas

**Requirements:**

* Caller must have `ADMIN_ROLE`
* Achievement must exist

**Events Emitted:**

* `AchievementDeactivated(uint256 indexed achievementId, uint256 timestamp)`

## Claiming Functions

### claimAchievement

Claim an achievement and receive rewards.

```solidity theme={null}
function claimAchievement(
    uint256 achievementId,
    bytes memory proof
) external;
```

**Parameters:**

* `achievementId` (uint256): ID of achievement to claim
* `proof` (bytes): Verification proof (if required)

**Returns:** None

**Gas Estimate:** \~180,000 gas (includes badge minting)

**Requirements:**

* Achievement must be active
* User must not have already claimed
* User must meet requirements

**Events Emitted:**

* `AchievementClaimed(address indexed user, uint256 indexed achievementId, uint256 timestamp)`
* `BadgeMinted(address indexed user, uint256 indexed achievementId, uint256 tokenId)`

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function claimAchievement(achievementId) {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    const signer = provider.getSigner();
    
    const contract = new ethers.Contract(
      '0x3456789012345678901234567890123456789012',
      ACHIEVEMENT_REGISTRY_ABI,
      signer
    );
    
    // Generate proof (if needed)
    const proof = '0x'; // Empty proof for automatic verification
    
    const tx = await contract.claimAchievement(achievementId, proof);
    const receipt = await tx.wait();
    
    // Get claim event
    const claimEvent = receipt.events.find(e => e.event === 'AchievementClaimed');
    const badgeEvent = receipt.events.find(e => e.event === 'BadgeMinted');
    
    console.log('Achievement claimed!');
    console.log('Timestamp:', claimEvent.args.timestamp.toString());
    console.log('Badge Token ID:', badgeEvent.args.tokenId.toString());
    
    return receipt;
  }
  ```

  ```python Python theme={null}
  def claim_achievement(achievement_id):
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x3456789012345678901234567890123456789012',
          abi=ACHIEVEMENT_REGISTRY_ABI
      )
      
      account = w3.eth.account.from_key('YOUR_PRIVATE_KEY')
      
      # Generate proof (if needed)
      proof = b''  # Empty proof for automatic verification
      
      tx = contract.functions.claimAchievement(achievement_id, proof).buildTransaction({
          'from': account.address,
          'gas': 200000,
          'gasPrice': w3.eth.gas_price,
          'nonce': w3.eth.get_transaction_count(account.address)
      })
      
      signed_tx = w3.eth.account.sign_transaction(tx, account.key)
      tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
      
      receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
      
      # Get events
      claim_event = contract.events.AchievementClaimed().processReceipt(receipt)[0]
      badge_event = contract.events.BadgeMinted().processReceipt(receipt)[0]
      
      print('Achievement claimed!')
      print(f"Timestamp: {claim_event['args']['timestamp']}")
      print(f"Badge Token ID: {badge_event['args']['tokenId']}")
      
      return receipt
  ```
</CodeGroup>

### batchClaimAchievements

Claim multiple achievements in a single transaction.

```solidity theme={null}
function batchClaimAchievements(
    uint256[] calldata achievementIds,
    bytes[] calldata proofs
) external returns (uint256[] memory);
```

**Parameters:**

* `achievementIds` (uint256\[]): Array of achievement IDs to claim
* `proofs` (bytes\[]): Array of corresponding proofs

**Returns:**

* `uint256[]`: Array of minted badge token IDs

**Gas Estimate:** \~150,000 + (180,000 × number of achievements)

**Requirements:**

* Arrays must have equal length
* Each achievement must be claimable

## Query Functions

### getAchievement

Get detailed information about an achievement.

```solidity theme={null}
function getAchievement(uint256 achievementId) 
    external 
    view 
    returns (Achievement memory);
```

**Parameters:**

* `achievementId` (uint256): ID of achievement to query

**Returns:**

* `Achievement`: Achievement struct with all details

**Gas Estimate:** \~5,000 gas (view function)

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function getAchievement(achievementId) {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    
    const contract = new ethers.Contract(
      '0x3456789012345678901234567890123456789012',
      ACHIEVEMENT_REGISTRY_ABI,
      provider
    );
    
    const achievement = await contract.getAchievement(achievementId);
    
    console.log('Achievement:', {
      id: achievement.id.toString(),
      name: achievement.name,
      description: achievement.description,
      category: achievement.category,
      rarity: achievement.rarity,
      points: achievement.points.toString(),
      totalClaimed: achievement.totalClaimed.toString(),
      isActive: achievement.isActive
    });
    
    return achievement;
  }
  ```

  ```python Python theme={null}
  def get_achievement(achievement_id):
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x3456789012345678901234567890123456789012',
          abi=ACHIEVEMENT_REGISTRY_ABI
      )
      
      achievement = contract.functions.getAchievement(achievement_id).call()
      
      print('Achievement:', {
          'id': achievement[0],
          'name': achievement[1],
          'description': achievement[2],
          'category': achievement[4],
          'rarity': achievement[5],
          'points': achievement[6],
          'totalClaimed': achievement[10],
          'isActive': achievement[12]
      })
      
      return achievement
  ```
</CodeGroup>

### getUserAchievements

Get all achievements earned by a user.

```solidity theme={null}
function getUserAchievements(address user) 
    external 
    view 
    returns (uint256[] memory);
```

**Parameters:**

* `user` (address): User address to query

**Returns:**

* `uint256[]`: Array of achievement IDs

**Gas Estimate:** \~3,000 + (1,000 × number of achievements) (view function)

### getProgress

Get user's progress for a specific achievement.

```solidity theme={null}
function getProgress(address user, uint256 achievementId) 
    external 
    view 
    returns (Progress memory);
```

**Parameters:**

* `user` (address): User address
* `achievementId` (uint256): Achievement ID

**Returns:**

* `Progress`: Progress struct with current/required/percentage/canClaim

**Gas Estimate:** \~4,000 gas (view function)

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function getProgress(userAddress, achievementId) {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    
    const contract = new ethers.Contract(
      '0x3456789012345678901234567890123456789012',
      ACHIEVEMENT_REGISTRY_ABI,
      provider
    );
    
    const progress = await contract.getProgress(userAddress, achievementId);
    
    console.log('Progress:', {
      current: progress.current.toString(),
      required: progress.required.toString(),
      percentage: progress.percentage.toString(),
      lastUpdated: new Date(progress.lastUpdated.toNumber() * 1000).toISOString(),
      canClaim: progress.canClaim
    });
    
    return progress;
  }
  ```

  ```python Python theme={null}
  def get_progress(user_address, achievement_id):
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x3456789012345678901234567890123456789012',
          abi=ACHIEVEMENT_REGISTRY_ABI
      )
      
      progress = contract.functions.getProgress(user_address, achievement_id).call()
      
      print('Progress:', {
          'current': progress[0],
          'required': progress[1],
          'percentage': progress[2],
          'lastUpdated': progress[3],
          'canClaim': progress[4]
      })
      
      return progress
  ```
</CodeGroup>

### getAchievementsByCategory

Get all achievements in a specific category.

```solidity theme={null}
function getAchievementsByCategory(uint8 category) 
    external 
    view 
    returns (uint256[] memory);
```

**Parameters:**

* `category` (uint8): Category index (0-7)

**Returns:**

* `uint256[]`: Array of achievement IDs

**Gas Estimate:** \~3,000 + (500 × number of achievements) (view function)

### getAchievementsByRarity

Get all achievements of a specific rarity.

```solidity theme={null}
function getAchievementsByRarity(Rarity rarity) 
    external 
    view 
    returns (uint256[] memory);
```

**Parameters:**

* `rarity` (Rarity): Rarity level (0-4)

**Returns:**

* `uint256[]`: Array of achievement IDs

**Gas Estimate:** \~3,000 + (500 × number of achievements) (view function)

## Progress Management Functions

### updateProgress

Update progress for a user (verifier only).

```solidity theme={null}
function updateProgress(
    address user,
    uint256 achievementId,
    uint256 progressValue
) external;
```

**Parameters:**

* `user` (address): User address
* `achievementId` (uint256): Achievement ID
* `progressValue` (uint256): New progress value

**Returns:** None

**Gas Estimate:** \~50,000 gas

**Requirements:**

* Caller must have `VERIFIER_ROLE`
* Achievement must exist
* User must not have claimed yet

**Events Emitted:**

* `ProgressUpdated(address indexed user, uint256 indexed achievementId, uint256 progress)`

### batchUpdateProgress

Update progress for multiple users.

```solidity theme={null}
function batchUpdateProgress(
    address[] calldata users,
    uint256[] calldata achievementIds,
    uint256[] calldata progressValues
) external;
```

**Parameters:**

* `users` (address\[]): Array of user addresses
* `achievementIds` (uint256\[]): Array of achievement IDs
* `progressValues` (uint256\[]): Array of progress values

**Returns:** None

**Gas Estimate:** \~40,000 + (50,000 × number of updates)

**Requirements:**

* All arrays must have equal length
* Caller must have `VERIFIER_ROLE`

## Badge Functions

### getBadge

Get badge information for a claimed achievement.

```solidity theme={null}
function getBadge(uint256 tokenId) 
    external 
    view 
    returns (Badge memory);
```

**Parameters:**

* `tokenId` (uint256): Badge token ID

**Returns:**

* `Badge`: Badge struct with achievement ID, owner, claim timestamp

**Gas Estimate:** \~3,000 gas (view function)

### getUserBadges

Get all badges owned by a user.

```solidity theme={null}
function getUserBadges(address user) 
    external 
    view 
    returns (uint256[] memory);
```

**Parameters:**

* `user` (address): User address

**Returns:**

* `uint256[]`: Array of badge token IDs

**Gas Estimate:** \~3,000 + (500 × number of badges) (view function)

## Verification Functions

### canClaim

Check if a user can claim an achievement.

```solidity theme={null}
function canClaim(address user, uint256 achievementId) 
    external 
    view 
    returns (bool);
```

**Parameters:**

* `user` (address): User address
* `achievementId` (uint256): Achievement ID

**Returns:**

* `bool`: True if user can claim, false otherwise

**Gas Estimate:** \~5,000 gas (view function)

### hasClaimed

Check if a user has already claimed an achievement.

```solidity theme={null}
function hasClaimed(address user, uint256 achievementId) 
    external 
    view 
    returns (bool);
```

**Parameters:**

* `user` (address): User address
* `achievementId` (uint256): Achievement ID

**Returns:**

* `bool`: True if already claimed, false otherwise

**Gas Estimate:** \~2,000 gas (view function)

## Error Handling

### Common Errors

| Error                      | Description                    | Solution                    |
| -------------------------- | ------------------------------ | --------------------------- |
| `"Achievement not active"` | Achievement is deactivated     | Check achievement status    |
| `"Already claimed"`        | User already claimed           | Check hasClaimed() first    |
| `"Requirements not met"`   | User doesn't meet requirements | Check progress/requirements |
| `"Invalid category"`       | Category index > 7             | Use valid category (0-7)    |
| `"Invalid rarity"`         | Rarity index > 4               | Use valid rarity (0-4)      |
| `"Achievement not found"`  | Invalid achievement ID         | Verify achievement ID       |

### Error Handling Examples

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function safeClaimAchievement(achievementId) {
    try {
      // Check if can claim
      const canClaim = await contract.canClaim(userAddress, achievementId);
      if (!canClaim) {
        throw new Error('Cannot claim achievement yet');
      }
      
      // Check if already claimed
      const hasClaimed = await contract.hasClaimed(userAddress, achievementId);
      if (hasClaimed) {
        throw new Error('Achievement already claimed');
      }
      
      // Claim achievement
      const tx = await contract.claimAchievement(achievementId, '0x');
      const receipt = await tx.wait();
      
      return receipt;
    } catch (error) {
      if (error.message.includes('Requirements not met')) {
        console.error('You do not meet the requirements for this achievement');
      } else if (error.message.includes('Achievement not active')) {
        console.error('This achievement is no longer available');
      } else {
        console.error('Claim failed:', error.message);
      }
      throw error;
    }
  }
  ```

  ```python Python theme={null}
  def safe_claim_achievement(achievement_id):
      try:
          # Check if can claim
          can_claim = contract.functions.canClaim(user_address, achievement_id).call()
          if not can_claim:
              raise ValueError('Cannot claim achievement yet')
          
          # Check if already claimed
          has_claimed = contract.functions.hasClaimed(user_address, achievement_id).call()
          if has_claimed:
              raise ValueError('Achievement already claimed')
          
          # Claim achievement
          tx = contract.functions.claimAchievement(achievement_id, b'').buildTransaction({
              'from': account.address,
              'gas': 200000,
              'gasPrice': w3.eth.gas_price,
              'nonce': w3.eth.get_transaction_count(account.address)
          })
          
          signed_tx = w3.eth.account.sign_transaction(tx, account.key)
          tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
          
          receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
          return receipt
          
      except Exception as error:
          error_msg = str(error)
          if 'Requirements not met' in error_msg:
              print('You do not meet the requirements for this achievement')
          elif 'Achievement not active' in error_msg:
              print('This achievement is no longer available')
          else:
              print(f'Claim failed: {error_msg}')
          raise error
  ```
</CodeGroup>

## Gas Optimization Tips

### Batch Operations

```javascript theme={null}
// Instead of claiming one by one
for (const id of achievementIds) {
  await contract.claimAchievement(id, '0x');
}

// Use batch claim
await contract.batchClaimAchievements(achievementIds, proofs);
```

### Query Optimization

```javascript theme={null}
// Query all achievements at once
const achievements = await contract.batchGetAchievements(achievementIds);

// Instead of individual queries
for (const id of achievementIds) {
  const achievement = await contract.getAchievement(id);
}
```

## Related Documentation

* [Contract Overview](/contracts/achievement-registry/overview) - Contract architecture and features
* [Events Reference](/contracts/achievement-registry/events) - Event documentation
* [Integration Guide](/contracts/achievement-registry/integration) - Integration examples
* [Custom Achievements](/contracts/achievement-registry/custom-achievements) - Creating custom achievements
