Skip to content

Latest commit

 

History

History
707 lines (559 loc) · 24.3 KB

File metadata and controls

707 lines (559 loc) · 24.3 KB

Suibotics DID

A production-ready decentralized identity and credential management system built on the Sui blockchain, designed specifically for IoT devices and robotics applications with full W3C DID Core specification compliance.

Overview

Suibotics DID provides a comprehensive framework for managing digital identities and verifiable credentials in IoT ecosystems. The system enables secure device authentication, credential issuance, and trust establishment between IoT devices, certificate authorities, and service providers. Built with type safety, comprehensive validation, production-grade error handling, and advanced batch operations for efficient fleet management.

Features

Decentralized Identity (DID) Management

  • DID Registration: Create unique decentralized identifiers for IoT devices
  • Key Management: Add, revoke, and manage cryptographic keys with type-safe dynamic field handling
  • Service Endpoints: Complete service lifecycle management (add, update, remove)
  • Controller Verification: Ensure only authorized entities can modify DID documents
  • W3C DID Document Resolution: Full compliance with W3C DID Core specification
  • Type-Safe Architecture: Prevents key/service ID collisions with wrapper structs

Batch Operations ✨ NEW

  • Bulk DID Registration: Register up to 50 DIDs in a single transaction for device fleet onboarding
  • Batch Key Management: Add or revoke keys across multiple DIDs simultaneously
  • Batch Service Operations: Bulk add, update, or remove service endpoints across device fleets
  • Batch Credential Operations: Issue or revoke credentials in bulk for fleet-wide operations
  • Partial Success Handling: Individual operation failures don't affect successful operations
  • Gas Optimization: Significant cost savings for fleet management operations
  • Detailed Result Tracking: Complete success/failure reporting for each operation

Verifiable Credentials

  • Credential Issuance: Issue tamper-proof credentials to devices
  • Schema Validation: Support for structured credential schemas
  • Revocation Management: Revoke credentials when necessary
  • Timestamp Tracking: Track credential issuance and revocation times
  • Credential Discovery: Multi-dimensional indexing for efficient credential lookup

Security Features

  • Input Validation: Comprehensive validation for all inputs
  • Access Control: Role-based access control for DID and credential operations
  • Event Logging: Immutable event logs for all operations with comprehensive change tracking
  • Error Handling: Robust error handling with descriptive error codes
  • Type Safety: Dynamic field type confusion prevention with KeyFieldKey/ServiceFieldKey wrappers

W3C Standards Compliance

  • DID Documents: Full W3C DID Core specification compliance
  • Verification Methods: Support for multiple key types and purposes
  • Service Endpoints: Standards-compliant service registration and management
  • Resolution: Complete DID document resolution from on-chain data

Architecture

The system consists of three focused modules with clean separation of concerns:

  1. identity_types (sources/identity_types.move): Core data structures, validation logic, and W3C DID document building
  2. did_registry (sources/did_registry.move): DID registration, key management, service lifecycle, and batch operations
  3. credential_registry (sources/credential_registry.move): Credential issuance, revocation, discovery, and batch operations

Key Architectural Improvements

  • Type-Safe Dynamic Fields: Separate namespaces for keys and services prevent ID collisions
  • DID Document Resolution: On-chain data structures that build W3C-compliant DID documents
  • Service Lifecycle Management: Complete add → update → remove workflow with audit trails
  • Batch Processing: Efficient bulk operations with partial success handling
  • Production-Ready Patterns: Comprehensive error handling, validation, and event emission

Dual Registry System

Suibotics DID uses two separate registry systems that serve distinct but complementary purposes:

DID Registry (did_registry)

Purpose: Manages Decentralized Identifiers (DIDs) and their associated identity data

What it stores:

  • DID documents with verification methods (public keys)
  • Service endpoints (like MQTT brokers, API endpoints)
  • Name-to-address mappings for human-readable DID names
  • Key management (add, revoke keys)

Key functions:

// Register a new DID identity
did_registry::register_did(registry, name, pubkey, purpose, ctx)

// Add keys for different purposes (authentication, assertion, etc.)
did_registry::add_key(did, key_id, pubkey, purpose, ctx)

// Manage service endpoints
did_registry::add_service(did, service_id, service_type, endpoint, ctx)
did_registry::update_service(did, service_id, new_type, new_endpoint, ctx)
did_registry::remove_service(did, service_id, ctx)

// Build W3C-compliant DID documents
did_registry::build_did_document(did, did_string, key_ids, service_ids)

// ✨ NEW: Batch operations for fleet management
did_registry::register_dids_batch(registry, names, pubkeys, purposes, ctx)
did_registry::add_keys_batch(dids, key_ids, pubkeys, purposes, ctx)
did_registry::revoke_keys_batch(dids, key_ids, ctx)
did_registry::add_services_batch(dids, service_ids, types, endpoints, ctx)
did_registry::update_services_batch(dids, service_ids, new_types, new_endpoints, ctx)

// ⭐ NEW: Reverse lookup capabilities for registry queries
did_registry::get_did_controller_by_name(registry, name)
did_registry::get_dids_by_controller(registry, controller)
did_registry::get_dids_by_service_type(registry, service_type)
did_registry::get_dids_by_key_purpose(registry, purpose)
did_registry::get_dids_by_time_range(registry, start_time, end_time)
did_registry::get_registry_stats(registry)
did_registry::did_name_exists(registry, name)

Credential Registry (credential_registry)

Purpose: Manages Verifiable Credentials and enables credential discovery

What it stores:

  • Credential metadata (issuer, subject, schema, timestamps)
  • Discovery indices (by subject, issuer, schema, time ranges)
  • Revocation status tracking
  • Registry statistics (total credentials, active, revoked)

Key functions:

// Issue credentials to subjects
credential_registry::issue_credential(registry, subject, schema, data_hash, ctx)

// Revoke credentials
credential_registry::revoke_credential(registry, credential, ctx)

// Discovery functions
credential_registry::get_credentials_by_subject(registry, subject)
credential_registry::get_credentials_by_issuer(registry, issuer)
credential_registry::get_credentials_by_schema(registry, schema)
credential_registry::get_active_credentials_by_subject(registry, subject)

// ✨ NEW: Batch operations for fleet management
credential_registry::issue_credentials_batch(registry, subjects, issuers, schemas, hashes, ctx)
credential_registry::revoke_credentials_batch(credentials, ctx)

Batch Operations Architecture

Both registries support efficient batch processing with the following design principles:

Batch Result Tracking

public struct BatchResult has copy, drop {
    index: u64,      // Operation index in the batch
    success: bool,   // Whether this operation succeeded
    error_code: u64, // Error code if operation failed
}

Partial Success Handling

  • Individual failures don't affect successful operations
  • Detailed tracking of which operations succeeded/failed
  • Granular error codes for debugging
  • Size limits (max 50 operations) prevent gas issues

Utility Functions

// Count successful operations
count_batch_successes(results: &vector<BatchResult>): u64

// Get indices of failed operations
get_batch_failures(results: &vector<BatchResult>): vector<u64>

// Check if entire batch succeeded
is_batch_fully_successful(results: &vector<BatchResult>): bool

Architectural Comparison

Aspect DID Registry Credential Registry
Data Focus Identity & verification methods Attestations & claims
Ownership DIDs owned by controllers Credentials owned by subjects
Discovery Name-based lookup Multi-dimensional indexing
Lifecycle Create → Update → (Keys/Services) Issue → Verify → Revoke
Batch Ops Device fleet onboarding Bulk credential management
Standards W3C DID Core specification W3C VC Data Model

Why Separate Registries?

  1. Separation of Concerns: Identity management vs. credential management are distinct functions
  2. Scalability: Each registry can be optimized for its specific access patterns
  3. Security: Different access controls and validation rules
  4. Standards Compliance: Each follows different W3C specifications

How They Work Together

// 1. Alice registers her DID (identity)
did_registry::register_did(&mut did_registry, b"alice_ca", pubkey, b"authentication", ctx);

// 2. Alice issues a credential to Bob (using her DID as issuer)
credential_registry::issue_credential(&mut cred_registry, BOB, b"DeviceCert", hash, ctx);

// 3. Bob can discover all credentials issued to him
let bobs_creds = credential_registry::get_credentials_by_subject(&cred_registry, BOB);

// 4. Anyone can resolve Alice's DID to verify her keys
let alice_did_doc = did_registry::build_did_document(&alice_did, did_string, key_ids, service_ids);

// ✨ 5. NEW: Bulk operations for fleet management
// Register 25 IoT devices in one transaction
let results = did_registry::register_dids_batch(&mut registry, device_names, pubkeys, purposes, ctx);

// Issue firmware attestations to the fleet
let cred_results = credential_registry::issue_credentials_batch(
    &mut cred_registry, devices, issuers, schemas, hashes, ctx
);

This separation makes the system more modular, secure, and allows each registry to be optimized for its specific use case, while batch operations enable efficient fleet management.

Prerequisites

  • Sui CLI: Version 1.49.1 or later
  • Move Language: Compatible with Sui Move framework

Installing Sui CLI

# macOS (using Homebrew)
brew install sui

# Or update existing installation
brew update && brew upgrade sui

# Verify installation
sui --version

Setup

  1. Clone the repository:

    git clone <repository-url>
    cd suibotics_did
  2. Build the project:

    sui move build
  3. Run tests:

    sui move test

Testing

The project includes comprehensive test suites covering all major functionality with extensive edge case testing:

Test Files

  • tests/did_registry_tests.move: 17 tests covering DID registration, key management, service lifecycle, and W3C compliance
  • tests/simple_test.move: 6 integration tests covering basic workflows
  • tests/suibotics_core_tests.move: 2 end-to-end scenario tests
  • tests/batch_operations_tests.move: 6 tests covering all batch operations functionality ✨ NEW
  • tests/reverse_lookup_tests.move: 6 tests covering all reverse lookup functionality ⭐ NEW

Running Tests

# Run all tests
sui move test

# Run specific test module
sui move test did_registry_tests

# Run batch operations tests
sui move test batch_operations_tests

# Run with verbose output
sui move test --verbose

Test Coverage

33/33 tests passing - 100% test success rate

Test Categories:

  • DID Registration and Management
  • Key Addition and Revocation
  • Service Endpoint Lifecycle Management (add/update/remove)
  • W3C DID Document Resolution
  • Type-Safe Dynamic Field Handling
  • Credential Issuance and Revocation
  • ✨ Batch Operations (DID and Credential) - 6 comprehensive tests
  • ✨ Partial Success Handling - Edge cases and validation
  • ✨ Batch Result Utilities - Success/failure tracking
  • ✨ Essential Reverse Lookup - 3 practical tests ⭐ SIMPLIFIED
  • Access Control and Security
  • Input Validation and Error Handling
  • Edge Cases and Collision Prevention

Usage Examples

Registering a DID

// Initialize the DID registry
did_registry::test_init(ctx);

// Register a new DID
did_registry::register_did(
    &mut registry,
    b"device_001",           // DID name
    device_public_key,       // Device's public key
    b"authentication",       // Key purpose
    ctx
);

Managing Keys

// Add a new key for signing operations
did_registry::add_key(
    &mut did_info,
    b"signing_key",          // Key identifier
    signing_public_key,      // Public key
    b"assertion",            // Key purpose
    ctx
);

// Revoke a key
did_registry::revoke_key(
    &mut did_info,
    b"signing_key",          // Key identifier to revoke
    ctx
);

Service Lifecycle Management

// Add an MQTT service endpoint
did_registry::add_service(
    &mut did_info,
    b"mqtt_broker",          // Service ID
    b"MQTTBroker",          // Service type
    b"mqtt://device.local:1883", // Endpoint URL
    ctx
);

// Update the service endpoint
did_registry::update_service(
    &mut did_info,
    b"mqtt_broker",          // Service ID
    b"MQTTBroker",          // New service type
    b"mqtt://device.local:8883", // New endpoint URL
    ctx
);

// Remove the service
did_registry::remove_service(
    &mut did_info,
    b"mqtt_broker",          // Service ID to remove
    ctx
);

W3C DID Document Resolution

// Build a complete W3C-compliant DID document
let did_document = did_registry::build_did_document(
    &did_info,
    verification_methods,    // Custom verification methods
    services,               // Custom services
);

// Or build with basic configuration
let basic_document = did_registry::build_basic_did_document(&did_info);

Issuing Credentials

// Issue a firmware attestation credential
credential_registry::issue_credential(
    device_address,          // Credential subject
    b"FirmwareAttestation",  // Credential schema
    firmware_hash,           // Data hash
    ctx
);

✨ NEW: Batch Operations

Batch DID Registration (Fleet Onboarding)

// Register 25 IoT devices in a single transaction
let device_names = vector[b"sensor_001", b"sensor_002", /*...*/];
let device_pubkeys = vector[pubkey1, pubkey2, /*...*/];
let purposes = vector[b"auth", b"auth", /*...*/];

let results = did_registry::register_dids_batch(
    &mut registry,
    device_names,
    device_pubkeys, 
    purposes,
    ctx
);

// Check results
let success_count = did_registry::count_batch_successes(&results);
let failures = did_registry::get_batch_failures(&results);
assert!(success_count == 25, 1); // All devices registered successfully

Batch Credential Issuance (Fleet Management)

// Issue firmware attestation credentials to device fleet
let subjects = vector[device1_addr, device2_addr, device3_addr];
let issuers = vector[ca_addr, ca_addr, ca_addr];
let schemas = vector[b"FirmwareAttest", b"FirmwareAttest", b"FirmwareAttest"];
let hashes = vector[fw_hash1, fw_hash2, fw_hash3];

let results = credential_registry::issue_credentials_batch(
    &mut cred_registry,
    subjects,
    issuers,
    schemas,
    hashes,
    ctx
);

// Verify all credentials issued successfully
assert!(credential_registry::is_batch_fully_successful(&results), 1);

Batch Key Management (Security Operations)

// Revoke compromised keys across multiple devices
let compromised_key_ids = vector[b"backup_key", b"backup_key", b"backup_key"];

let results = did_registry::revoke_keys_batch(
    &mut device_dids,
    compromised_key_ids,
    ctx
);

// Track which devices had keys successfully revoked
let revoked_count = did_registry::count_batch_successes(&results);

Handling Partial Success

// Batch operation with mixed results
let results = did_registry::register_dids_batch(
    &mut registry,
    names_with_duplicate,  // One name already exists
    pubkeys,
    purposes,
    ctx
);

// Check which operations failed
if (!did_registry::is_batch_fully_successful(&results)) {
    let failures = did_registry::get_batch_failures(&results);
    // failures = [2] - indicates index 2 failed (duplicate name)
    
    let success_count = did_registry::count_batch_successes(&results);
    // success_count = 2 out of 3 operations succeeded
}

✨ SIMPLIFIED: Essential Reverse Lookup

The DID registry now provides simplified, practical reverse lookup capabilities for fleet management. We focus on the essential use cases without over-engineering.

Find DID by Name

// Look up DID controller by human-readable name
let controller_opt = did_registry::get_did_controller_by_name(&registry, b"alice_device");
if (option::is_some(&controller_opt)) {
    let controller = option::extract(&mut controller_opt);
    // Found DID controller: 0xa11ce...
};

// Check if a DID name exists (useful for validation before registration)
let exists = did_registry::did_name_exists(&registry, b"device_name");
assert!(!exists, 1); // Ensure name is available

Find DIDs by Controller (Multi-Device Management)

// Find all devices owned by a specific address - essential for IoT fleet management
let alice_devices = did_registry::get_dids_by_controller(&registry, ALICE);
let device_count = vector::length(&alice_devices);

// Iterate through devices for management operations
let mut i = 0;
while (i < device_count) {
    let device_id = *vector::borrow(&alice_devices, i);
    // Perform fleet operations on device_id
    i = i + 1;
};

Registry Statistics

// Get total DID count for monitoring and dashboards
let total_devices = did_registry::get_registry_stats(&registry);

Design Philosophy:

  • Keep it simple: Only the functions that provide real business value
  • Fleet management: Essential for multi-device scenarios
  • Practical use cases: No premature optimization or complex indexing
  • Efficient queries: Direct lookups without scanning large datasets

Error Codes

The system uses standardized error codes for consistent error handling across all modules:

Core Validation Errors (1-9)

  • 1: Invalid controller (unauthorized access)
  • 2: Key not found
  • 3: Key already exists
  • 4: Name already exists
  • 5: Invalid public key
  • 6: Invalid data hash
  • 7: Empty field
  • 8: Field too long
  • 9: Invalid address

Batch Operation Errors (10-19)

  • 10: Batch too large (max 50 operations) ✨ IMPROVED
  • 11: Batch size mismatch (input vector lengths don't match) ✨ NEW
  • 12: Batch empty (reserved for future use) ✨ NEW

Credential-Specific Errors (20-29) ✨ NEW

  • 20: Credential not found
  • 21: Credential already revoked ✨ IMPROVED
  • 22: Unauthorized revocation (only issuer or subject can revoke) ✨ IMPROVED
  • 23: Invalid schema
  • 24: Credential expired (reserved for future use)

Service Management Errors (30-39) ✨ NEW

  • 30: Service not found ✨ IMPROVED
  • 31: Service already exists ✨ IMPROVED
  • 32: Invalid service type (reserved for future use)
  • 33: Invalid endpoint (reserved for future use)

Registry Errors (40-49) ✨ RESERVED

  • 40-49: Reserved for future registry-specific errors

Error Handling Improvements ✨ NEW

Consistent Error Patterns:

  • Standardized Error Constants: All modules use the same error codes from identity_types
  • Error Code Accessor Functions: Clean API with functions like e_invalid_controller()
  • Comprehensive Documentation: Every error code is documented with clear descriptions
  • Semantic Error Codes: Specific errors for different contexts (service vs key vs credential)
  • Future-Proof: Reserved error code ranges for expansion

Before vs After:

// ❌ Before: Inconsistent hardcoded errors
assert!(valid, 1);           // What does 1 mean?
assert!(batch_size <= 50, 10); // Hardcoded values

// ✅ After: Standardized semantic errors
assert!(valid, e_invalid_controller());     // Clear meaning
assert!(batch_size <= max_batch_size(), e_batch_too_large()); // Consistent patterns

Events

The system emits comprehensive events for all major operations with detailed change tracking:

DID Events

  • DIDRegistered: When a new DID is registered
  • KeyAdded: When a key is added to a DID
  • KeyRevoked: When a key is revoked
  • ServiceAdded: When a service endpoint is added
  • ServiceUpdated: When a service endpoint is updated (with old/new values)
  • ServiceRemoved: When a service endpoint is removed

Credential Events

  • CredentialIssued: When a credential is issued
  • CredentialRevoked: When a credential is revoked

Note: Batch operations emit individual events for each successful operation, providing complete audit trails.

Development

Project Structure

suibotics_did/
├── sources/
│   ├── identity_types.move     # Core data structures & W3C DID document building
│   ├── did_registry.move       # DID management, service lifecycle & batch operations
│   └── credential_registry.move # Credential management, discovery & batch operations
├── tests/
│   ├── did_registry_tests.move    # DID functionality tests (17 tests)
│   ├── simple_test.move           # Integration tests (6 tests)
│   ├── suibotics_core_tests.move  # End-to-end tests (2 tests)
│   └── batch_operations_tests.move # Batch operations tests (6 tests) ✨ NEW
│   └── reverse_lookup_tests.move   # Reverse lookup tests (6 tests) ⭐ NEW
├── Move.toml                   # Project configuration
├── deploy_testnet.sh           # Comprehensive testnet deployment script
├── deploy_simple.sh            # Simple testnet deployment script
└── README.md                   # This file

Code Statistics

  • Total Source Code: ~45KB across 3 modules (significant expansion for batch operations)
  • Lines of Code: 1,400+ lines (includes comprehensive batch operations)
  • Test Coverage: 36 comprehensive tests (6 batch + 6 reverse lookup tests)
  • Production Readiness: Type-safe, well-documented, follows Sui best practices
  • Batch Operations: Full fleet management capabilities with partial success handling

Deployment

Testnet Deployment

Two deployment scripts are provided for testnet deployment:

Option 1: Comprehensive Deployment (Recommended)

./deploy_testnet.sh

This script provides:

  • ✅ Comprehensive pre-deployment checks
  • ✅ Automatic environment setup
  • ✅ Gas balance verification and faucet requests
  • ✅ Build and test validation
  • ✅ Detailed logging and error handling
  • ✅ Post-deployment verification
  • ✅ Explorer links and deployment info

Option 2: Quick Deployment

./deploy_simple.sh

This script provides:

  • ⚡ Fast deployment with minimal checks
  • 🎯 Essential steps only
  • 📦 Package ID extraction
  • 🔗 Explorer links

Prerequisites for Deployment

  • Sui CLI installed (version 1.49.1+)
  • Active Sui wallet
  • jq installed for JSON parsing (optional but recommended)

Manual Deployment

If you prefer manual deployment:

# Switch to testnet
sui client switch --env testnet

# Request testnet tokens
sui client faucet

# Build and test
sui move build
sui move test

# Deploy
sui client publish --gas-budget 100000000

Post-Deployment

After successful deployment, you'll receive:

  • Package ID: Use this to interact with your deployed modules
  • Transaction Digest: For verification on blockchain explorers
  • Explorer Links: View your deployment on Sui explorers

The deployment information is automatically saved to deployment_info.json for future reference.

Standards Compliance

W3C DID Core Specification

  • ✅ DID Method Implementation
  • ✅ DID Document Structure
  • ✅ Verification Method Support
  • ✅ Service Endpoint Management
  • ✅ Controller Authorization
  • ✅ Resolution Interface

Security Best Practices

  • ✅ Type-Safe Dynamic Field Access
  • ✅ Comprehensive Input Validation
  • ✅ Access Control Enforcement
  • ✅ Event Logging and Audit Trails
  • ✅ Error Handling and Recovery
  • ✅ Batch Operation Security (size limits, partial success)

Contributing

  1. Ensure all tests pass: sui move test
  2. Follow Move coding conventions
  3. Add tests for new functionality
  4. Update documentation as needed
  5. Maintain type safety and validation patterns
  6. Test batch operations with various edge cases

License

[Add your license information here]