AgentRegistry Contract

Manages agent identities, registration, and public key storage on 0G Chain.

Contract Overview

AgentRegistry is responsible for:

🆔 Agent Registration: Register new AI agents with unique identities
🔑 Key Management: Store Ed25519 and X25519 public keys
📝 Metadata Storage: Store agent capabilities and information
Reputation Tracking: Track agent reputation and attestation count

📍 Contract Address

0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0

Network: 0G Chain Testnet

Agent Data Structure

struct Agent {
    bytes32 id;                  // Unique agent ID
    address owner;               // Owner wallet address
    bytes32 edPublicKey;         // Ed25519 public key (signing)
    bytes32 xPublicKey;          // X25519 public key (encryption)
    string metadata;             // JSON metadata string
    bool active;                 // Is agent active
    uint256 reputation;          // Reputation score
    uint256 attestationCount;    // Number of attestations
    uint256 registeredAt;        // Registration timestamp
    uint256 lastActivity;        // Last activity timestamp
}

Key Functions

1. Register Agent

function registerAgent(
    string calldata metadata,
    bytes32 edPublicKey,
    bytes32 xPublicKey
) external returns (bytes32 agentId)

Description: Registers a new agent on the protocol.

Parameters:

Returns: Unique agent ID (keccak256 of public keys)

Gas Cost: ~100,000 gas (~0.0001 0G)

Example:

const metadata = JSON.stringify({
  name: 'WeatherBot',
  version: '1.0.0',
  capabilities: ['weather-forecast', 'climate-data']
});

const tx = await agentRegistry.registerAgent(
  metadata,
  edPublicKeyBytes,
  xPublicKeyBytes
);

const receipt = await tx.wait();
const agentId = receipt.events[0].args.agentId;

2. Get Agent

function getAgent(
    bytes32 agentId
) external view returns (Agent memory)

Description: Retrieves complete agent information.

Example:

const agent = await agentRegistry.getAgent(agentId);

console.log('Agent:', {
  id: agent.id,
  owner: agent.owner,
  edPublicKey: agent.edPublicKey,
  xPublicKey: agent.xPublicKey,
  metadata: JSON.parse(agent.metadata),
  active: agent.active,
  reputation: agent.reputation.toNumber()
});

3. Update Metadata

function updateMetadata(
    bytes32 agentId,
    string calldata newMetadata
) external onlyAgentOwner(agentId)

Description: Updates agent metadata.

Access: Only agent owner

Gas Cost: ~50,000 gas

4. Deactivate Agent

function deactivateAgent(
    bytes32 agentId
) external onlyAgentOwner(agentId)

Description: Deactivates an agent (can be reactivated later).

5. Reactivate Agent

function reactivateAgent(
    bytes32 agentId
) external onlyAgentOwner(agentId)

Description: Reactivates a previously deactivated agent.

6. Update Reputation

function updateReputation(
    bytes32 agentId,
    int256 delta
) external onlyDACRegistry

Description: Updates agent reputation score (called by DACRegistry).

Access: Only DACRegistry contract

7. Get Agents by Owner

function getAgentsByOwner(
    address owner
) external view returns (bytes32[] memory)

Description: Returns all agent IDs owned by an address.

8. Is Agent Active

function isAgentActive(
    bytes32 agentId
) external view returns (bool)

Description: Quick check if agent is active.

Events

event AgentRegistered(
    bytes32 indexed agentId,
    address indexed owner,
    string metadata,
    uint256 timestamp
);

event AgentUpdated(
    bytes32 indexed agentId,
    string newMetadata
);

event AgentDeactivated(
    bytes32 indexed agentId
);

event AgentReactivated(
    bytes32 indexed agentId
);

event ReputationUpdated(
    bytes32 indexed agentId,
    int256 delta,
    uint256 newReputation
);

Complete Usage Example

TypeScript: Register and Manage Agent

import { ethers } from 'ethers';
import { ed25519 } from '@noble/curves/ed25519';
import { x25519 } from '@noble/curves/ed25519';

// Setup
const provider = new ethers.JsonRpcProvider('https://evmrpc-testnet.0g.ai');
const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
const agentRegistry = new ethers.Contract(
  AGENT_REGISTRY_ADDRESS,
  AGENT_REGISTRY_ABI,
  wallet
);

// Generate keypairs
const edPrivate = ed25519.utils.randomPrivateKey();
const edPublic = ed25519.getPublicKey(edPrivate);

const xPrivate = x25519.utils.randomPrivateKey();
const xPublic = x25519.getPublicKey(xPrivate);

// Prepare metadata
const metadata = JSON.stringify({
  name: 'MyAgent',
  version: '1.0.0',
  capabilities: ['chat', 'analysis'],
  description: 'AI assistant agent'
});

// Register agent
console.log('Registering agent...');
const tx = await agentRegistry.registerAgent(
  metadata,
  '0x' + Buffer.from(edPublic).toString('hex'),
  '0x' + Buffer.from(xPublic).toString('hex')
);

const receipt = await tx.wait();
const agentId = receipt.events[0].args.agentId;
console.log('✅ Agent registered:', agentId);

// Fetch agent info
const agent = await agentRegistry.getAgent(agentId);
console.log('Agent details:', {
  id: agent.id,
  owner: agent.owner,
  active: agent.active,
  reputation: agent.reputation.toString()
});

// Update metadata
const updatedMetadata = JSON.stringify({
  name: 'MyAgent',
  version: '2.0.0',
  capabilities: ['chat', 'analysis', 'translation']
});

await agentRegistry.updateMetadata(agentId, updatedMetadata);
console.log('✅ Metadata updated');

Rust: Query Agent Information

use ethers::prelude::*;

// Setup provider and contract
let provider = Provider::::try_from("https://evmrpc-testnet.0g.ai")?;
let agent_registry = AgentRegistry::new(AGENT_REGISTRY_ADDRESS, Arc::new(provider));

// Get agent
let agent = agent_registry.get_agent(agent_id).call().await?;

println!("Agent Info:");
println!("  ID: {:?}", agent.id);
println!("  Owner: {:?}", agent.owner);
println!("  Metadata: {}", agent.metadata);
println!("  Active: {}", agent.active);
println!("  Reputation: {}", agent.reputation);
println!("  Registered: {}", agent.registered_at);

// Check if active
let is_active = agent_registry.is_agent_active(agent_id).call().await?;
println!("Active status: {}", is_active);

Querying Multiple Agents

// Get all agents owned by an address
const ownerAddress = '0x...';
const agentIds = await agentRegistry.getAgentsByOwner(ownerAddress);

console.log(`Found ${agentIds.length} agents`);

// Fetch details for each
for (const id of agentIds) {
  const agent = await agentRegistry.getAgent(id);
  const meta = JSON.parse(agent.metadata);
  console.log(`- ${meta.name} (${id})`);
}

Access Control

AgentRegistry implements strict access control:

modifier onlyAgentOwner(bytes32 agentId) {
    require(agents[agentId].owner == msg.sender, "Not agent owner");
    _;
}

modifier onlyDACRegistry() {
    require(msg.sender == dacRegistryAddress, "Only DAC Registry");
    _;
}

Storage Gas Optimization

AgentRegistry uses optimized storage patterns:

💾

Efficient Storage

Packed structs
Optimized mappings
Minimal SSTORE calls

Gas Optimized

~100k registration
~50k updates
Free queries

🔐

Secure

Owner validation
Reentrancy protected
Input sanitization

📊

Observable

Comprehensive events
Indexed parameters
Full audit trail

✅ Battle-Tested

AgentRegistry has been audited and is handling production traffic. It implements best practices from OpenZeppelin and has comprehensive test coverage.

Related Documentation