Skip to main content

Overview

The ZKScore Trust Registry is a decentralized attestation and verification system that manages trust relationships, credentials, and reputation signals on-chain. It enables verifiable claims about identities, behaviors, and achievements through cryptographically signed attestations.
The Trust Registry enables permissionless trust-building while maintaining privacy and decentralization. All attestations are cryptographically verifiable and immutable.

Contract Architecture

Core Components

The Trust Registry consists of several key components:
  1. Attestation Management: Creation and storage of attestations
  2. Verification System: Cryptographic verification of claims
  3. Trust Modules: Pluggable trust evaluation modules
  4. Reputation Tracking: Aggregation of trust signals
  5. Privacy Layer: Zero-knowledge proof integration

Trust Model

The trust model is based on:
  • Attesters: Entities that issue attestations
  • Subjects: Entities receiving attestations
  • Verifiers: Entities checking attestations
  • Trust Modules: Logic for trust evaluation
  • Reputation Scores: Aggregated trust metrics

Contract Addresses

Mainnet Deployments

// Trust Registry Contract
address: 0x4567890123456789012345678901234567890123

// Proxy Contract
address: 0x5678901234567890123456789012345678901234

// Schema Registry
address: 0x6789012345678901234567890123456789012345

Testnet Deployments

// Trust Registry Contract
address: 0x0123456789012345678901234567890123456789

// Proxy Contract
address: 0x1234567890123456789012345678901234567890

// Schema Registry
address: 0x2345678901234567890123456789012345678901

Attestation Structure

Attestation Data Model

struct Attestation {
    bytes32 uid;                // Unique attestation ID
    bytes32 schema;             // Schema identifier
    address attester;           // Who issued the attestation
    address recipient;          // Who received it
    uint64 time;                // Creation timestamp
    uint64 expirationTime;      // Expiration (0 = no expiration)
    bool revocable;             // Can be revoked
    bytes32 refUID;             // Reference to another attestation
    bytes data;                 // Encoded attestation data
    bool revoked;               // Revocation status
}

Schema Structure

struct Schema {
    bytes32 uid;                // Unique schema ID
    address resolver;           // Schema resolver contract
    bool revocable;             // Are attestations revocable
    string schema;              // Schema definition (e.g., "bool verified,string name")
}

Common Schema Types

// Identity Verification
"bool verified,uint256 verificationLevel,uint256 timestamp"

// Skill Endorsement
"string skill,uint8 level,string endorsement"

// Protocol Participation
"address protocol,uint256 activityCount,uint256 value"

// Reputation Score
"uint256 score,string category,bytes32 proof"

// Credential
"string credentialType,string issuer,uint256 expirationTime"

Contract Interface

Core Functions

// Attestation Management
function attest(AttestationRequest calldata request) external returns (bytes32);
function multiAttest(MultiAttestationRequest[] calldata requests) external returns (bytes32[] memory);
function revoke(RevocationRequest calldata request) external;
function multiRevoke(MultiRevocationRequest[] calldata requests) external;

// Queries
function getAttestation(bytes32 uid) external view returns (Attestation memory);
function getAttestationsForRecipient(address recipient) external view returns (bytes32[] memory);
function getAttestationsBySchema(bytes32 schema) external view returns (bytes32[] memory);
function isAttestationValid(bytes32 uid) external view returns (bool);

// Schema Management
function registerSchema(string calldata schema, address resolver, bool revocable) external returns (bytes32);
function getSchema(bytes32 uid) external view returns (Schema memory);

Events

// Attestation Events
event Attested(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schema);
event Revoked(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schema);

// Schema Events
event SchemaRegistered(bytes32 indexed uid, address indexed registerer);

// Trust Module Events
event TrustModuleRegistered(address indexed module, string name);
event TrustScoreUpdated(address indexed subject, uint256 oldScore, uint256 newScore);

Attestation Types

1. Identity Attestations

Verify identity characteristics:
// Human verification
Schema: "bool isHuman,string verificationType,uint256 confidence"

// KYC attestation
Schema: "bool kycPassed,uint8 level,uint256 timestamp"

// Social verification
Schema: "string platform,string username,bool verified"

2. Skill Attestations

Endorse skills and expertise:
// Skill endorsement
Schema: "string skill,uint8 proficiency,string evidence"

// Certification
Schema: "string certificate,string issuer,uint256 expiration"

// Work experience
Schema: "string role,string organization,uint256 duration"

3. Participation Attestations

Verify protocol/community participation:
// Protocol usage
Schema: "address protocol,uint256 transactions,uint256 volume"

// DAO membership
Schema: "address dao,string role,uint256 joinedAt"

// Event attendance
Schema: "string event,uint256 timestamp,string location"

4. Reputation Attestations

Signal reputation and trustworthiness:
// Trust score
Schema: "uint256 score,string category,bytes32 evidence"

// Peer review
Schema: "uint8 rating,string review,uint256 timestamp"

// Achievement verification
Schema: "uint256 achievementId,bool earned,uint256 timestamp"

Trust Modules

Module Architecture

Trust modules are pluggable contracts that evaluate trust:
interface ITrustModule {
    function evaluateTrust(address subject, bytes calldata context) external view returns (uint256);
    function getRequirements() external view returns (bytes32[] memory);
    function getName() external view returns (string memory);
}

Built-in Modules

1. Attestation Count Module

// Evaluates based on number of attestations
function evaluateTrust(address subject, bytes calldata context) external view returns (uint256) {
    uint256 count = getAttestationCount(subject);
    return min(count * 100, 1000); // Max 1000
}

2. Attester Reputation Module

// Weighs attestations by attester reputation
function evaluateTrust(address subject, bytes calldata context) external view returns (uint256) {
    Attestation[] memory attestations = getAttestations(subject);
    uint256 weightedScore = 0;
    
    for (uint i = 0; i < attestations.length; i++) {
        uint256 attesterRep = getAttesterReputation(attestations[i].attester);
        weightedScore += attesterRep;
    }
    
    return min(weightedScore / attestations.length, 1000);
}

3. Schema-Based Module

// Evaluates specific schemas
function evaluateTrust(address subject, bytes calldata context) external view returns (uint256) {
    bytes32 schema = abi.decode(context, (bytes32));
    uint256 count = getSchemaAttestationCount(subject, schema);
    
    return min(count * 200, 1000); // Higher weight for specific schemas
}

4. Time-Decay Module

// Applies time decay to attestations
function evaluateTrust(address subject, bytes calldata context) external view returns (uint256) {
    Attestation[] memory attestations = getAttestations(subject);
    uint256 score = 0;
    uint256 currentTime = block.timestamp;
    
    for (uint i = 0; i < attestations.length; i++) {
        uint256 age = currentTime - attestations[i].time;
        uint256 decayFactor = getDecayFactor(age);
        score += 100 * decayFactor / 100; // Apply decay
    }
    
    return min(score, 1000);
}

Privacy Features

Zero-Knowledge Proofs

The Trust Registry integrates ZK proofs for privacy:
// ZK proof verification
function attestWithProof(
    AttestationRequest calldata request,
    bytes calldata zkProof
) external returns (bytes32) {
    require(verifyZKProof(zkProof, request.data), "Invalid proof");
    return attest(request);
}

// Private attestation query
function hasAttestationPrivate(
    address subject,
    bytes32 schema,
    bytes calldata zkProof
) external view returns (bool) {
    require(verifyZKProof(zkProof, subject), "Invalid proof");
    return hasAttestation(subject, schema);
}

Selective Disclosure

Users can prove specific claims without revealing all data:
// Prove age > 18 without revealing exact age
function proveAgeOver18(bytes calldata proof) external view returns (bool) {
    return verifySelectiveDisclosure(proof, "age", ">", 18);
}

// Prove credential without revealing details
function proveCredential(bytes calldata proof, string memory credType) external view returns (bool) {
    return verifySelectiveDisclosure(proof, "credentialType", "==", credType);
}

Gas Optimization

Efficient Storage

// Packed attestation data
struct PackedAttestation {
    address attester;           // 20 bytes
    address recipient;          // 20 bytes
    uint64 time;                // 8 bytes
    uint64 expirationTime;      // 8 bytes
    bool revocable;             // 1 byte
    bool revoked;               // 1 byte
    bytes32 schema;             // 32 bytes
    bytes32 uid;                // 32 bytes
    // Separate storage for data
}

Batch Operations

// Batch attestations save gas
function multiAttest(MultiAttestationRequest[] calldata requests) 
    external 
    returns (bytes32[] memory) {
    bytes32[] memory uids = new bytes32[](requests.length);
    
    for (uint i = 0; i < requests.length; i++) {
        uids[i] = _attest(requests[i]);
    }
    
    return uids;
}

Gas Estimates

OperationGas CostDescription
Single Attestation~120,000Create single attestation
Multi Attestation (5)~450,000Batch 5 attestations
Revoke Attestation~40,000Revoke single attestation
Query Attestation~3,000View attestation data
Register Schema~80,000Register new schema
Verify ZK Proof~150,000Verify zero-knowledge proof

Integration Examples

Basic Attestation

import { ethers } from 'ethers';

// Contract ABI (simplified)
const TRUST_REGISTRY_ABI = [
  "function attest(tuple(bytes32 schema, tuple(address recipient, uint64 expirationTime, bool revocable, bytes32 refUID, bytes data) data) request) external returns (bytes32)",
  "function getAttestation(bytes32 uid) external view returns (tuple(bytes32 uid, bytes32 schema, address attester, address recipient, uint64 time, uint64 expirationTime, bool revocable, bytes32 refUID, bytes data, bool revoked))",
  "event Attested(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schema)"
];

// Initialize contract
const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
const contract = new ethers.Contract(
  '0x4567890123456789012345678901234567890123',
  TRUST_REGISTRY_ABI,
  provider
);

// Create attestation
async function createAttestation(recipient, schema, data) {
  const signer = provider.getSigner();
  const contractWithSigner = contract.connect(signer);
  
  const attestationRequest = {
    schema: schema,
    data: {
      recipient: recipient,
      expirationTime: 0, // No expiration
      revocable: true,
      refUID: ethers.constants.HashZero,
      data: data
    }
  };
  
  const tx = await contractWithSigner.attest(attestationRequest);
  const receipt = await tx.wait();
  
  // Get UID from event
  const event = receipt.events.find(e => e.event === 'Attested');
  const uid = event.args.uid;
  
  console.log(`Attestation created: ${uid}`);
  return uid;
}

Security Considerations

Attestation Verification

Always verify attestations before trusting:
function isValid(bytes32 uid) public view returns (bool) {
    Attestation memory attestation = getAttestation(uid);
    
    // Check expiration
    if (attestation.expirationTime > 0 && 
        attestation.expirationTime < block.timestamp) {
        return false;
    }
    
    // Check revocation
    if (attestation.revoked) {
        return false;
    }
    
    // Check attester reputation
    if (getAttesterScore(attestation.attester) < MIN_ATTESTER_SCORE) {
        return false;
    }
    
    return true;
}

Sybil Resistance

Implement Sybil attack protection:
// Require minimum stake to become attester
mapping(address => uint256) public attesterStake;
uint256 public constant MIN_STAKE = 1 ether;

function becomeAttester() external payable {
    require(msg.value >= MIN_STAKE, "Insufficient stake");
    attesterStake[msg.sender] += msg.value;
}

// Slash malicious attesters
function slashAttester(address attester, bytes calldata proof) external {
    require(verifyMaliciousActivity(proof), "Invalid proof");
    attesterStake[attester] = 0;
}

Best Practices

For Attesters

  1. Verify Claims: Thoroughly verify before attesting
  2. Use Expiration: Set appropriate expiration times
  3. Schema Standards: Follow established schemas
  4. Reputation: Build attester reputation
  5. Documentation: Document attestation criteria

For Verifiers

  1. Check Validity: Always verify attestation validity
  2. Attester Reputation: Consider attester trustworthiness
  3. Multiple Sources: Require multiple attestations
  4. Time Sensitivity: Consider attestation age
  5. Schema Matching: Verify correct schema