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

# Identity SBT Functions

> Complete reference for all Identity SBT contract functions

## Overview

This document provides a comprehensive reference for all functions available in the ZKScore Identity SBT 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>

## Core Functions

### mint

Mint a new identity token for a user.

```solidity theme={null}
function mint(
    address to,
    string memory name,
    string memory metadataURI
) external returns (uint256 tokenId);
```

**Parameters:**

* `to` (address): The address to mint the token to
* `name` (string): The ZKS ID name (e.g., "alice.zks")
* `metadataURI` (string): URI pointing to the token metadata

**Returns:**

* `tokenId` (uint256): The ID of the newly minted token

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

**Requirements:**

* Caller must have `MINTER_ROLE`
* `to` cannot be the zero address
* `name` must be unique and valid
* `metadataURI` must be a valid URI

**Events Emitted:**

* `IdentityMinted(address indexed to, uint256 indexed tokenId, string name)`

**Example Usage:**

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

  async function mintIdentity() {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    const signer = provider.getSigner();
    
    const contract = new ethers.Contract(
      '0x1234567890123456789012345678901234567890',
      IDENTITY_SBT_ABI,
      signer
    );
    
    const tx = await contract.mint(
      '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
      'alice.zks',
      'https://api.onzks.com/metadata/alice.zks'
    );
    
    const receipt = await tx.wait();
    const event = receipt.events.find(e => e.event === 'IdentityMinted');
    const tokenId = event.args.tokenId;
    
    console.log(`Identity minted with token ID: ${tokenId}`);
    return tokenId;
  }
  ```

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

  def mint_identity():
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x1234567890123456789012345678901234567890',
          abi=IDENTITY_SBT_ABI
      )
      
      account = w3.eth.account.from_key('YOUR_PRIVATE_KEY')
      
      tx = contract.functions.mint(
          '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
          'alice.zks',
          'https://api.onzks.com/metadata/alice.zks'
      ).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 token ID from event
      event = contract.events.IdentityMinted().processReceipt(receipt)[0]
      token_id = event['args']['tokenId']
      
      print(f"Identity minted with token ID: {token_id}")
      return token_id
  ```
</CodeGroup>

### activate

Activate an identity token, making it soulbound.

```solidity theme={null}
function activate(uint256 tokenId) external;
```

**Parameters:**

* `tokenId` (uint256): The ID of the token to activate

**Returns:** None

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

**Requirements:**

* Caller must be the owner of the token
* Token must not already be activated
* Token must exist

**Events Emitted:**

* `IdentityActivated(uint256 indexed tokenId, address indexed owner)`

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function activateIdentity(tokenId) {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    const signer = provider.getSigner();
    
    const contract = new ethers.Contract(
      '0x1234567890123456789012345678901234567890',
      IDENTITY_SBT_ABI,
      signer
    );
    
    const tx = await contract.activate(tokenId);
    await tx.wait();
    
    console.log(`Identity ${tokenId} activated and made soulbound`);
  }
  ```

  ```python Python theme={null}
  def activate_identity(token_id):
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x1234567890123456789012345678901234567890',
          abi=IDENTITY_SBT_ABI
      )
      
      account = w3.eth.account.from_key('YOUR_PRIVATE_KEY')
      
      tx = contract.functions.activate(token_id).buildTransaction({
          'from': account.address,
          'gas': 100000,
          '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)
      
      print(f"Identity {token_id} activated and made soulbound")
  ```
</CodeGroup>

## View Functions

### balanceOf

Get the number of tokens owned by an address.

```solidity theme={null}
function balanceOf(address owner) external view returns (uint256);
```

**Parameters:**

* `owner` (address): The address to query

**Returns:**

* `uint256`: The number of tokens owned by the address

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

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function getBalance(address) {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    
    const contract = new ethers.Contract(
      '0x1234567890123456789012345678901234567890',
      IDENTITY_SBT_ABI,
      provider
    );
    
    const balance = await contract.balanceOf(address);
    console.log(`Balance: ${balance.toString()}`);
    return balance;
  }
  ```

  ```python Python theme={null}
  def get_balance(address):
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x1234567890123456789012345678901234567890',
          abi=IDENTITY_SBT_ABI
      )
      
      balance = contract.functions.balanceOf(address).call()
      print(f"Balance: {balance}")
      return balance
  ```
</CodeGroup>

### ownerOf

Get the owner of a specific token.

```solidity theme={null}
function ownerOf(uint256 tokenId) external view returns (address);
```

**Parameters:**

* `tokenId` (uint256): The ID of the token

**Returns:**

* `address`: The owner of the token

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

**Requirements:**

* Token must exist

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function getOwner(tokenId) {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    
    const contract = new ethers.Contract(
      '0x1234567890123456789012345678901234567890',
      IDENTITY_SBT_ABI,
      provider
    );
    
    const owner = await contract.ownerOf(tokenId);
    console.log(`Owner: ${owner}`);
    return owner;
  }
  ```

  ```python Python theme={null}
  def get_owner(token_id):
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x1234567890123456789012345678901234567890',
          abi=IDENTITY_SBT_ABI
      )
      
      owner = contract.functions.ownerOf(token_id).call()
      print(f"Owner: {owner}")
      return owner
  ```
</CodeGroup>

### isActivated

Check if a token is activated (soulbound).

```solidity theme={null}
function isActivated(uint256 tokenId) external view returns (bool);
```

**Parameters:**

* `tokenId` (uint256): The ID of the token

**Returns:**

* `bool`: True if the token is activated, false otherwise

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

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function checkActivation(tokenId) {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    
    const contract = new ethers.Contract(
      '0x1234567890123456789012345678901234567890',
      IDENTITY_SBT_ABI,
      provider
    );
    
    const isActivated = await contract.isActivated(tokenId);
    console.log(`Token ${tokenId} is ${isActivated ? 'activated' : 'not activated'}`);
    return isActivated;
  }
  ```

  ```python Python theme={null}
  def check_activation(token_id):
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x1234567890123456789012345678901234567890',
          abi=IDENTITY_SBT_ABI
      )
      
      is_activated = contract.functions.isActivated(token_id).call()
      print(f"Token {token_id} is {'activated' if is_activated else 'not activated'}")
      return is_activated
  ```
</CodeGroup>

### isSoulbound

Check if a token is soulbound (cannot be transferred).

```solidity theme={null}
function isSoulbound(uint256 tokenId) external view returns (bool);
```

**Parameters:**

* `tokenId` (uint256): The ID of the token

**Returns:**

* `bool`: True if the token is soulbound, false otherwise

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

**Note:** This function returns the same value as `isActivated()` since activation makes a token soulbound.

### tokenURI

Get the metadata URI for a token.

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

**Parameters:**

* `tokenId` (uint256): The ID of the token

**Returns:**

* `string`: The metadata URI for the token

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

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function getTokenURI(tokenId) {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    
    const contract = new ethers.Contract(
      '0x1234567890123456789012345678901234567890',
      IDENTITY_SBT_ABI,
      provider
    );
    
    const uri = await contract.tokenURI(tokenId);
    console.log(`Token URI: ${uri}`);
    return uri;
  }
  ```

  ```python Python theme={null}
  def get_token_uri(token_id):
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x1234567890123456789012345678901234567890',
          abi=IDENTITY_SBT_ABI
      )
      
      uri = contract.functions.tokenURI(token_id).call()
      print(f"Token URI: {uri}")
      return uri
  ```
</CodeGroup>

## Metadata Functions

### setTokenURI

Update the metadata URI for a token.

```solidity theme={null}
function setTokenURI(uint256 tokenId, string memory newURI) external;
```

**Parameters:**

* `tokenId` (uint256): The ID of the token
* `newURI` (string): The new metadata URI

**Returns:** None

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

**Requirements:**

* Caller must have `METADATA_ROLE` or be the token owner
* Token must exist
* Token must not be activated (metadata is immutable after activation)

**Events Emitted:**

* `MetadataUpdated(uint256 indexed tokenId, string newURI)`

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function updateTokenURI(tokenId, newURI) {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    const signer = provider.getSigner();
    
    const contract = new ethers.Contract(
      '0x1234567890123456789012345678901234567890',
      IDENTITY_SBT_ABI,
      signer
    );
    
    const tx = await contract.setTokenURI(tokenId, newURI);
    await tx.wait();
    
    console.log(`Token ${tokenId} metadata updated to: ${newURI}`);
  }
  ```

  ```python Python theme={null}
  def update_token_uri(token_id, new_uri):
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x1234567890123456789012345678901234567890',
          abi=IDENTITY_SBT_ABI
      )
      
      account = w3.eth.account.from_key('YOUR_PRIVATE_KEY')
      
      tx = contract.functions.setTokenURI(token_id, new_uri).buildTransaction({
          'from': account.address,
          'gas': 100000,
          '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)
      
      print(f"Token {token_id} metadata updated to: {new_uri}")
  ```
</CodeGroup>

## Access Control Functions

### grantRole

Grant a role to an address.

```solidity theme={null}
function grantRole(bytes32 role, address account) external;
```

**Parameters:**

* `role` (bytes32): The role to grant
* `account` (address): The address to grant the role to

**Returns:** None

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

**Requirements:**

* Caller must have the admin role for the specified role

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function grantMinterRole(account) {
    const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
    const signer = provider.getSigner();
    
    const contract = new ethers.Contract(
      '0x1234567890123456789012345678901234567890',
      IDENTITY_SBT_ABI,
      signer
    );
    
    const MINTER_ROLE = await contract.MINTER_ROLE();
    const tx = await contract.grantRole(MINTER_ROLE, account);
    await tx.wait();
    
    console.log(`Minter role granted to ${account}`);
  }
  ```

  ```python Python theme={null}
  def grant_minter_role(account):
      w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
      
      contract = w3.eth.contract(
          address='0x1234567890123456789012345678901234567890',
          abi=IDENTITY_SBT_ABI
      )
      
      account_signer = w3.eth.account.from_key('YOUR_PRIVATE_KEY')
      
      minter_role = contract.functions.MINTER_ROLE().call()
      
      tx = contract.functions.grantRole(minter_role, account).buildTransaction({
          'from': account_signer.address,
          'gas': 100000,
          'gasPrice': w3.eth.gas_price,
          'nonce': w3.eth.get_transaction_count(account_signer.address)
      })
      
      signed_tx = w3.eth.account.sign_transaction(tx, account_signer.key)
      tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
      
      receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
      
      print(f"Minter role granted to {account}")
  ```
</CodeGroup>

### revokeRole

Revoke a role from an address.

```solidity theme={null}
function revokeRole(bytes32 role, address account) external;
```

**Parameters:**

* `role` (bytes32): The role to revoke
* `account` (address): The address to revoke the role from

**Returns:** None

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

**Requirements:**

* Caller must have the admin role for the specified role

### hasRole

Check if an address has a specific role.

```solidity theme={null}
function hasRole(bytes32 role, address account) external view returns (bool);
```

**Parameters:**

* `role` (bytes32): The role to check
* `account` (address): The address to check

**Returns:**

* `bool`: True if the address has the role, false otherwise

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

## Transfer Functions

### transferFrom

Transfer a token from one address to another.

```solidity theme={null}
function transferFrom(address from, address to, uint256 tokenId) external;
```

**Parameters:**

* `from` (address): The current owner of the token
* `to` (address): The new owner of the token
* `tokenId` (uint256): The ID of the token to transfer

**Returns:** None

**Gas Estimate:** \~80,000 gas (before activation), reverts (after activation)

**Requirements:**

* Token must not be activated (soulbound)
* Caller must be authorized to transfer the token
* `to` cannot be the zero address

**Note:** This function will revert if the token is activated (soulbound).

### safeTransferFrom

Safely transfer a token from one address to another.

```solidity theme={null}
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) external;
```

**Parameters:**

* `from` (address): The current owner of the token
* `to` (address): The new owner of the token
* `tokenId` (uint256): The ID of the token to transfer
* `data` (bytes, optional): Additional data to send with the transfer

**Returns:** None

**Gas Estimate:** \~80,000 gas (before activation), reverts (after activation)

**Requirements:**

* Token must not be activated (soulbound)
* Caller must be authorized to transfer the token
* `to` cannot be the zero address

**Note:** This function will revert if the token is activated (soulbound).

## Approval Functions

### approve

Approve an address to transfer a specific token.

```solidity theme={null}
function approve(address to, uint256 tokenId) external;
```

**Parameters:**

* `to` (address): The address to approve
* `tokenId` (uint256): The ID of the token to approve

**Returns:** None

**Gas Estimate:** \~50,000 gas (before activation), reverts (after activation)

**Requirements:**

* Caller must be the owner of the token
* Token must not be activated (soulbound)

**Note:** This function will revert if the token is activated (soulbound).

### getApproved

Get the approved address for a specific token.

```solidity theme={null}
function getApproved(uint256 tokenId) external view returns (address);
```

**Parameters:**

* `tokenId` (uint256): The ID of the token

**Returns:**

* `address`: The approved address (zero address if none)

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

### setApprovalForAll

Approve or revoke approval for all tokens.

```solidity theme={null}
function setApprovalForAll(address operator, bool approved) external;
```

**Parameters:**

* `operator` (address): The address to approve or revoke
* `approved` (bool): True to approve, false to revoke

**Returns:** None

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

**Note:** This function works for all tokens, but individual transfers will still revert if the token is activated.

### isApprovedForAll

Check if an operator is approved for all tokens.

```solidity theme={null}
function isApprovedForAll(address owner, address operator) external view returns (bool);
```

**Parameters:**

* `owner` (address): The owner of the tokens
* `operator` (address): The operator to check

**Returns:**

* `bool`: True if the operator is approved, false otherwise

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

## Error Handling

### Common Errors

| Error                                      | Description                               | Solution                                        |
| ------------------------------------------ | ----------------------------------------- | ----------------------------------------------- |
| `"Token is soulbound"`                     | Attempting to transfer an activated token | Check if token is activated before transfer     |
| `"Not token owner"`                        | Caller is not the owner of the token      | Ensure caller is the token owner                |
| `"Already activated"`                      | Token is already activated                | Check activation status before calling activate |
| `"Token does not exist"`                   | Token ID does not exist                   | Verify token ID is valid                        |
| `"AccessControl: account is missing role"` | Caller lacks required role                | Grant appropriate role to caller                |

### Error Handling Examples

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function safeMint(to, name, metadataURI) {
    try {
      const tx = await contract.mint(to, name, metadataURI);
      const receipt = await tx.wait();
      return receipt;
    } catch (error) {
      if (error.message.includes('AccessControl')) {
        console.error('Insufficient permissions to mint');
      } else if (error.message.includes('name already exists')) {
        console.error('Name is already taken');
      } else {
        console.error('Minting failed:', error.message);
      }
      throw error;
    }
  }
  ```

  ```python Python theme={null}
  def safe_mint(to, name, metadata_uri):
      try:
          tx = contract.functions.mint(to, name, metadata_uri).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:
          if 'AccessControl' in str(error):
              print('Insufficient permissions to mint')
          elif 'name already exists' in str(error):
              print('Name is already taken')
          else:
              print(f'Minting failed: {error}')
          raise error
  ```
</CodeGroup>

## Gas Optimization Tips

### Batch Operations

```javascript theme={null}
// Batch multiple operations in a single transaction
async function batchMint(identities) {
  const tx = await contract.batchMint(identities);
  const receipt = await tx.wait();
  return receipt;
}
```

### Gas Estimation

```javascript theme={null}
// Estimate gas before sending transaction
async function estimateGasMint(to, name, metadataURI) {
  const gasEstimate = await contract.estimateGas.mint(to, name, metadataURI);
  console.log(`Estimated gas: ${gasEstimate.toString()}`);
  return gasEstimate;
}
```

## Related Documentation

* [Contract Overview](/contracts/identity-sbt/overview) - Contract architecture and features
* [Events Reference](/contracts/identity-sbt/events) - Event documentation
* [Integration Guide](/contracts/identity-sbt/integration) - Integration examples
* [Security Guide](/contracts/identity-sbt/security) - Security considerations
* [Deployment Guide](/contracts/identity-sbt/deployment) - Deployment instructions
