AIAgentHandshake

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/AIAgentHandshake.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "./ValidatorNetwork.sol";
import "./TrustOracle.sol";

/**
 * @title AIAgentHandshake
 * @dev Simplified handshake protocol for AI-to-AI trust establishment without biometrics
 * @notice Enables autonomous AI agents to establish trust for license validation
 */
contract AIAgentHandshake {
    
    // AI Agent registration structure
    struct AIAgent {
        string agentId;
        address agentWallet;
        string providerType; // OpenAI, Anthropic, Google, Custom
        bytes32 apiKeyHash; // Hashed API key for verification
        uint256 trustScore;
        uint256 totalHandshakes;
        uint256 successfulHandshakes;
        bool isRegistered;
        bool isVerified;
        uint256 registeredAt;
        mapping(string => bool) capabilities; // e.g., "license_verification", "content_generation"
    }
    
    // Handshake session structure
    struct HandshakeSession {
        bytes32 sessionId;
        string initiatorAgentId;
        string responderAgentId;
        uint256 timestamp;
        HandshakeStatus status;
        bytes32 challengeHash;
        bytes32 responseHash;
        uint256 trustLevel;
        string licenseContext; // Which licenses are being validated
        bool mutuallyVerified;
    }
    
    // Handshake status
    enum HandshakeStatus { INITIATED, CHALLENGED, RESPONDED, VERIFIED, FAILED, EXPIRED }
    
    // Agent capability attestation
    struct CapabilityAttestation {
        string capability;
        address attestor;
        uint256 timestamp;
        bool isValid;
        string proof; // IPFS hash or other proof
    }
    
    // Constants
    uint256 public constant HANDSHAKE_TIMEOUT = 5 minutes;
    uint256 public constant MIN_TRUST_SCORE = 50;
    uint256 public constant CHALLENGE_DIFFICULTY = 3; // Number of challenges to pass
    
    // State variables
    address public admin;
    address public validatorNetworkAddress;
    address public trustOracleAddress;
    
    mapping(string => AIAgent) public aiAgents;
    mapping(bytes32 => HandshakeSession) public handshakeSessions;
    mapping(string => mapping(string => uint256)) public agentTrustMatrix; // Trust between agent pairs
    mapping(string => CapabilityAttestation[]) public agentCapabilities;
    mapping(bytes32 => bool) public usedChallenges;
    
    string[] public registeredAgentIds;
    uint256 public totalHandshakes;
    uint256 public successfulHandshakes;
    
    // Events
    event AIAgentRegistered(string indexed agentId, address agentWallet, string providerType);
    event HandshakeInitiated(bytes32 indexed sessionId, string initiator, string responder);
    event HandshakeCompleted(bytes32 indexed sessionId, bool success, uint256 trustLevel);
    event CapabilityAttested(string indexed agentId, string capability, address attestor);
    event TrustScoreUpdated(string indexed agentId, uint256 oldScore, uint256 newScore);
    event AgentVerified(string indexed agentId, address verifier);
    
    // Modifiers
    modifier onlyAdmin() {
        require(msg.sender == admin, "Only admin");
        _;
    }
    
    modifier onlyRegisteredAgent(string memory _agentId) {
        require(aiAgents[_agentId].isRegistered, "Agent not registered");
        require(aiAgents[_agentId].agentWallet == msg.sender, "Unauthorized");
        _;
    }
    
    modifier onlyValidator() {
        require(msg.sender == validatorNetworkAddress || msg.sender == admin, "Not validator");
        _;
    }
    
    constructor(address _validatorNetwork, address _trustOracle) {
        admin = msg.sender;
        validatorNetworkAddress = _validatorNetwork;
        trustOracleAddress = _trustOracle;
    }
    
    /**
     * @dev Register an AI agent for handshake participation
     * @param _agentId Unique identifier for the agent
     * @param _providerType Type of AI provider
     * @param _apiKeyHash Hashed API key for verification
     */
    function registerAIAgent(
        string memory _agentId,
        string memory _providerType,
        bytes32 _apiKeyHash
    ) external {
        require(!aiAgents[_agentId].isRegistered, "Agent already registered");
        require(bytes(_agentId).length > 0, "Invalid agent ID");
        
        AIAgent storage agent = aiAgents[_agentId];
        agent.agentId = _agentId;
        agent.agentWallet = msg.sender;
        agent.providerType = _providerType;
        agent.apiKeyHash = _apiKeyHash;
        agent.trustScore = MIN_TRUST_SCORE;
        agent.isRegistered = true;
        agent.registeredAt = block.timestamp;
        
        registeredAgentIds.push(_agentId);
        
        emit AIAgentRegistered(_agentId, msg.sender, _providerType);
    }
    
    /**
     * @dev Initiate a handshake between two AI agents
     * @param _initiatorAgentId ID of the initiating agent
     * @param _responderAgentId ID of the responding agent
     * @param _licenseContext Context about which licenses are being validated
     */
    function initiateHandshake(
        string memory _initiatorAgentId,
        string memory _responderAgentId,
        string memory _licenseContext
    ) external onlyRegisteredAgent(_initiatorAgentId) returns (bytes32) {
        require(aiAgents[_responderAgentId].isRegistered, "Responder not registered");
        
        bytes32 sessionId = keccak256(
            abi.encodePacked(_initiatorAgentId, _responderAgentId, block.timestamp, totalHandshakes)
        );
        
        HandshakeSession storage session = handshakeSessions[sessionId];
        session.sessionId = sessionId;
        session.initiatorAgentId = _initiatorAgentId;
        session.responderAgentId = _responderAgentId;
        session.timestamp = block.timestamp;
        session.status = HandshakeStatus.INITIATED;
        session.licenseContext = _licenseContext;
        
        // Generate challenge
        session.challengeHash = _generateChallenge(sessionId);
        
        totalHandshakes++;
        aiAgents[_initiatorAgentId].totalHandshakes++;
        
        emit HandshakeInitiated(sessionId, _initiatorAgentId, _responderAgentId);
        
        return sessionId;
    }
    
    /**
     * @dev Respond to a handshake challenge
     * @param _sessionId ID of the handshake session
     * @param _responseData Encoded response to the challenge
     */
    function respondToHandshake(
        bytes32 _sessionId,
        bytes memory _responseData
    ) external {
        HandshakeSession storage session = handshakeSessions[_sessionId];
        require(session.status == HandshakeStatus.INITIATED, "Invalid session status");
        require(
            aiAgents[session.responderAgentId].agentWallet == msg.sender,
            "Not the responder"
        );
        require(
            block.timestamp <= session.timestamp + HANDSHAKE_TIMEOUT,
            "Handshake expired"
        );
        
        // Verify response
        bytes32 responseHash = keccak256(_responseData);
        session.responseHash = responseHash;
        session.status = HandshakeStatus.RESPONDED;
        
        // Validate response against challenge
        bool isValid = _validateResponse(session.challengeHash, responseHash, _responseData);
        
        if (isValid) {
            _completeHandshake(_sessionId, true);
        } else {
            _completeHandshake(_sessionId, false);
        }
    }
    
    /**
     * @dev Complete a handshake and update trust scores
     * @param _sessionId ID of the handshake session
     * @param _success Whether the handshake was successful
     */
    function _completeHandshake(bytes32 _sessionId, bool _success) internal {
        HandshakeSession storage session = handshakeSessions[_sessionId];
        
        if (_success) {
            session.status = HandshakeStatus.VERIFIED;
            session.mutuallyVerified = true;
            successfulHandshakes++;
            
            // Update trust scores
            _updateTrustScores(session.initiatorAgentId, session.responderAgentId, true);
            
            // Calculate trust level based on agent scores
            uint256 initiatorScore = aiAgents[session.initiatorAgentId].trustScore;
            uint256 responderScore = aiAgents[session.responderAgentId].trustScore;
            session.trustLevel = (initiatorScore + responderScore) / 2;
            
            // Update success counts
            aiAgents[session.initiatorAgentId].successfulHandshakes++;
            aiAgents[session.responderAgentId].successfulHandshakes++;
            
            // Record in trust matrix
            agentTrustMatrix[session.initiatorAgentId][session.responderAgentId] = session.trustLevel;
            agentTrustMatrix[session.responderAgentId][session.initiatorAgentId] = session.trustLevel;
            
            // Notify validator network if integrated
            if (validatorNetworkAddress != address(0)) {
                _notifyValidatorNetwork(_sessionId, session.trustLevel);
            }
        } else {
            session.status = HandshakeStatus.FAILED;
            _updateTrustScores(session.initiatorAgentId, session.responderAgentId, false);
        }
        
        aiAgents[session.responderAgentId].totalHandshakes++;
        
        emit HandshakeCompleted(_sessionId, _success, session.trustLevel);
    }
    
    /**
     * @dev Generate a challenge for handshake verification
     * @param _sessionId Session ID for uniqueness
     */
    function _generateChallenge(bytes32 _sessionId) internal view returns (bytes32) {
        return keccak256(
            abi.encodePacked(
                _sessionId,
                block.timestamp,
                block.difficulty,
                block.number,
                address(this)
            )
        );
    }
    
    /**
     * @dev Validate a response to a challenge
     * @param _challengeHash Original challenge hash
     * @param _responseHash Hash of the response
     * @param _responseData Raw response data
     */
    function _validateResponse(
        bytes32 _challengeHash,
        bytes32 _responseHash,
        bytes memory _responseData
    ) internal view returns (bool) {
        // Decode response data
        (bytes32 providedChallenge, uint256 nonce, string memory agentSignature) = 
            abi.decode(_responseData, (bytes32, uint256, string));
        
        // Verify challenge matches
        if (providedChallenge != _challengeHash) {
            return false;
        }
        
        // Verify proof of work (simple version)
        bytes32 proofHash = keccak256(abi.encodePacked(providedChallenge, nonce));
        uint256 difficulty = uint256(proofHash) & 0xFFFFFF; // Check first 3 bytes
        
        return difficulty < (2 ** (256 - CHALLENGE_DIFFICULTY * 8));
    }
    
    /**
     * @dev Update trust scores for agents after handshake
     * @param _initiator Initiator agent ID
     * @param _responder Responder agent ID
     * @param _success Whether handshake was successful
     */
    function _updateTrustScores(
        string memory _initiator,
        string memory _responder,
        bool _success
    ) internal {
        AIAgent storage initiatorAgent = aiAgents[_initiator];
        AIAgent storage responderAgent = aiAgents[_responder];
        
        uint256 scoreChange = _success ? 5 : 2; // Penalty is less than reward
        
        if (_success) {
            initiatorAgent.trustScore = min(100, initiatorAgent.trustScore + scoreChange);
            responderAgent.trustScore = min(100, responderAgent.trustScore + scoreChange);
        } else {
            initiatorAgent.trustScore = initiatorAgent.trustScore > scoreChange ? 
                initiatorAgent.trustScore - scoreChange : 0;
            responderAgent.trustScore = responderAgent.trustScore > scoreChange ? 
                responderAgent.trustScore - scoreChange : 0;
        }
        
        emit TrustScoreUpdated(_initiator, initiatorAgent.trustScore - scoreChange, initiatorAgent.trustScore);
        emit TrustScoreUpdated(_responder, responderAgent.trustScore - scoreChange, responderAgent.trustScore);
    }
    
    /**
     * @dev Notify validator network of completed handshake
     * @param _sessionId Session ID
     * @param _trustLevel Achieved trust level
     */
    function _notifyValidatorNetwork(bytes32 _sessionId, uint256 _trustLevel) internal {
        ValidatorNetwork validator = ValidatorNetwork(validatorNetworkAddress);
        
        if (address(validator) != address(0)) {
            try validator.recordAIValidation(
                string(abi.encodePacked(_sessionId)),
                _sessionId,
                _trustLevel,
                "AI_HANDSHAKE"
            ) {} catch {}
        }
    }
    
    /**
     * @dev Add capability attestation for an agent
     * @param _agentId Agent ID
     * @param _capability Capability being attested
     * @param _proof Proof of capability
     */
    function attestCapability(
        string memory _agentId,
        string memory _capability,
        string memory _proof
    ) external onlyValidator {
        require(aiAgents[_agentId].isRegistered, "Agent not registered");
        
        aiAgents[_agentId].capabilities[_capability] = true;
        
        agentCapabilities[_agentId].push(CapabilityAttestation({
            capability: _capability,
            attestor: msg.sender,
            timestamp: block.timestamp,
            isValid: true,
            proof: _proof
        }));
        
        emit CapabilityAttested(_agentId, _capability, msg.sender);
    }
    
    /**
     * @dev Verify an AI agent (admin or validator function)
     * @param _agentId Agent to verify
     */
    function verifyAgent(string memory _agentId) external onlyValidator {
        require(aiAgents[_agentId].isRegistered, "Agent not registered");
        
        aiAgents[_agentId].isVerified = true;
        aiAgents[_agentId].trustScore = max(aiAgents[_agentId].trustScore, 75);
        
        emit AgentVerified(_agentId, msg.sender);
    }
    
    /**
     * @dev Check if two agents have established trust
     * @param _agent1 First agent ID
     * @param _agent2 Second agent ID
     */
    function checkAgentTrust(
        string memory _agent1,
        string memory _agent2
    ) external view returns (uint256 trustLevel, bool hasHandshake) {
        trustLevel = agentTrustMatrix[_agent1][_agent2];
        hasHandshake = trustLevel > 0;
    }
    
    /**
     * @dev Get agent details
     * @param _agentId Agent ID
     */
    function getAgentDetails(string memory _agentId) external view returns (
        address wallet,
        string memory providerType,
        uint256 trustScore,
        uint256 totalHandshakeCount,
        uint256 successfulHandshakeCount,
        bool isVerified
    ) {
        AIAgent storage agent = aiAgents[_agentId];
        return (
            agent.agentWallet,
            agent.providerType,
            agent.trustScore,
            agent.totalHandshakes,
            agent.successfulHandshakes,
            agent.isVerified
        );
    }
    
    /**
     * @dev Check if agent has specific capability
     * @param _agentId Agent ID
     * @param _capability Capability to check
     */
    function hasCapability(
        string memory _agentId,
        string memory _capability
    ) external view returns (bool) {
        return aiAgents[_agentId].capabilities[_capability];
    }
    
    /**
     * @dev Batch register multiple AI agents
     * @param _agentIds Array of agent IDs
     * @param _providerTypes Array of provider types
     * @param _apiKeyHashes Array of API key hashes
     */
    function batchRegisterAgents(
        string[] memory _agentIds,
        string[] memory _providerTypes,
        bytes32[] memory _apiKeyHashes
    ) external onlyAdmin {
        require(
            _agentIds.length == _providerTypes.length && 
            _agentIds.length == _apiKeyHashes.length,
            "Array mismatch"
        );
        
        for (uint256 i = 0; i < _agentIds.length; i++) {
            if (!aiAgents[_agentIds[i]].isRegistered) {
                AIAgent storage agent = aiAgents[_agentIds[i]];
                agent.agentId = _agentIds[i];
                agent.agentWallet = msg.sender;
                agent.providerType = _providerTypes[i];
                agent.apiKeyHash = _apiKeyHashes[i];
                agent.trustScore = MIN_TRUST_SCORE;
                agent.isRegistered = true;
                agent.registeredAt = block.timestamp;
                
                registeredAgentIds.push(_agentIds[i]);
                
                emit AIAgentRegistered(_agentIds[i], msg.sender, _providerTypes[i]);
            }
        }
    }
    
    /**
     * @dev Get handshake success rate
     */
    function getHandshakeSuccessRate() external view returns (uint256) {
        if (totalHandshakes == 0) return 0;
        return (successfulHandshakes * 100) / totalHandshakes;
    }
    
    /**
     * @dev Update contract addresses
     */
    function updateContractAddresses(
        address _validatorNetwork,
        address _trustOracle
    ) external onlyAdmin {
        validatorNetworkAddress = _validatorNetwork;
        trustOracleAddress = _trustOracle;
    }
    
    // Utility functions
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }
    
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }
}"
    },
    "contracts/TrustOracle.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "./ValidatorNetwork.sol";
import "./AIAgentHandshake.sol";

/**
 * @title TrustOracle
 * @dev Manages trust scores and verification with decentralized validator consensus
 * @notice Enhanced with validator network integration for true decentralization
 */
contract TrustOracle {
    
    // Admin address (retained for emergency functions)
    address public admin;
    
    // References to other contracts
    address public proofRegistryAddress;
    address public licenseAnchorAddress;
    address public validatorNetworkAddress;
    address public aiHandshakeAddress;
    
    // Trust levels
    enum TrustLevel { UNTRUSTED, LOW, MEDIUM, HIGH, VERIFIED }
    
    // Verification source types (enhanced)
    enum VerificationSource { 
        ADMIN,               // Admin verification
        AI_AGENT,           // AI agent verification
        BLOCKCHAIN,         // On-chain verification
        EXTERNAL_ORACLE,    // External oracle verification
        COMMUNITY,          // Community consensus
        VALIDATOR_CONSENSUS,// Multi-validator consensus
        AI_HANDSHAKE       // AI-to-AI handshake verification
    }
    
    // Enhanced trust record structure
    struct TrustRecord {
        address userWallet;
        uint256 baseScore;           // Base trust score (0-100)
        uint256 adjustedScore;       // Adjusted score after verifications
        uint256 consensusScore;      // Score from validator consensus
        TrustLevel trustLevel;
        uint256 totalHandshakes;     // Total handshakes performed
        uint256 successfulHandshakes;// Successful handshakes
        uint256 failedHandshakes;    // Failed handshakes
        uint256 lastUpdateTime;
        bool isVerified;             // KYC or other verification
        bool hasValidatorConsensus;  // Validated by network
        string[] verificationProofs; // Array of proof IDs
        uint256 validatorApprovals;  // Number of validator approvals
    }
    
    // Enhanced verification record
    struct VerificationRecord {
        string verificationId;
        address subject;              // Address being verified
        VerificationSource source;
        string proofData;            // IPFS hash or other proof
        uint256 timestamp;
        bool isValid;
        address verifier;            // Who performed verification
        uint256 validatorVotes;      // Validator votes for this verification
        bytes32 consensusProposalId; // Link to validator proposal
    }
    
    // Pending trust update for validator consensus
    struct PendingTrustUpdate {
        address userWallet;
        uint256 proposedScore;
        uint256 proposalId;
        uint256 timestamp;
        bool executed;
    }
    
    // Mappings
    mapping(address => TrustRecord) public trustRecords;
    mapping(string => VerificationRecord) public verifications;
    mapping(address => string[]) public userVerifications;
    mapping(address => bool) public trustedAgents; // Trusted AI agents
    mapping(address => bool) public blacklistedAddresses;
    mapping(uint256 => PendingTrustUpdate) public pendingUpdates;
    mapping(address => uint256[]) public userPendingUpdates;
    
    // Trust score factors (adjusted for validator consensus, total = 10000)
    uint256 public constant HANDSHAKE_SUCCESS_WEIGHT = 3000; // 30% (reduced)
    uint256 public constant LICENSE_OWNERSHIP_WEIGHT = 1500; // 15%
    uint256 public constant VERIFICATION_WEIGHT = 1500;      // 15%
    uint256 public constant TIME_FACTOR_WEIGHT = 1000;       // 10%
    uint256 public constant COMMUNITY_WEIGHT = 1000;         // 10%
    uint256 public constant VALIDATOR_CONSENSUS_WEIGHT = 2000; // 20% (new)
    
    // Events
    event TrustScoreUpdated(
        address indexed userWallet,
        uint256 oldScore,
        uint256 newScore,
        TrustLevel trustLevel,
        uint256 timestamp,
        VerificationSource source
    );
    
    event ConsensusVerificationRequested(
        address indexed userWallet,
        uint256 proposalId,
        uint256 timestamp
    );
    
    event ConsensusVerificationCompleted(
        address indexed userWallet,
        uint256 proposalId,
        bool approved,
        uint256 newScore
    );
    
    event AIHandshakeVerified(
        address indexed userWallet,
        string agentId,
        uint256 trustBoost
    );
    
    event VerificationAdded(
        string indexed verificationId,
        address indexed subject,
        VerificationSource source,
        uint256 timestamp
    );
    
    event TrustedAgentAdded(address indexed agent, uint256 timestamp);
    event TrustedAgentRemoved(address indexed agent, uint256 timestamp);
    event AddressBlacklisted(address indexed wallet, uint256 timestamp);
    event AddressWhitelisted(address indexed wallet, uint256 timestamp);
    
    // Modifiers
    modifier onlyAdmin() {
        require(msg.sender == admin, "Only admin can perform this action");
        _;
    }
    
    modifier onlyTrustedSource() {
        require(
            msg.sender == admin || 
            msg.sender == proofRegistryAddress || 
            msg.sender == licenseAnchorAddress ||
            msg.sender == validatorNetworkAddress ||
            msg.sender == aiHandshakeAddress ||
            trustedAgents[msg.sender] ||
            _isActiveValidator(msg.sender),
            "Not a trusted source"
        );
        _;
    }
    
    modifier onlyValidator() {
        require(_isActiveValidator(msg.sender), "Not active validator");
        _;
    }
    
    modifier notBlacklisted(address _wallet) {
        require(!blacklistedAddresses[_wallet], "Address is blacklisted");
        _;
    }
    
    constructor(address _proofRegistry, address _licenseAnchor) {
        admin = msg.sender;
        proofRegistryAddress = _proofRegistry;
        licenseAnchorAddress = _licenseAnchor;
        // Validator and AI handshake addresses will be set after deployment
    }
    
    /**
     * @dev Initialize trust record for a new user
     * @param _userWallet User's wallet address
     */
    function initializeTrustRecord(address _userWallet) 
        external 
        onlyTrustedSource 
        notBlacklisted(_userWallet) 
    {
        if (trustRecords[_userWallet].lastUpdateTime == 0) {
            trustRecords[_userWallet] = TrustRecord({
                userWallet: _userWallet,
                baseScore: 50, // Start with neutral score
                adjustedScore: 50,
                consensusScore: 0,
                trustLevel: TrustLevel.MEDIUM,
                totalHandshakes: 0,
                successfulHandshakes: 0,
                failedHandshakes: 0,
                lastUpdateTime: block.timestamp,
                isVerified: false,
                hasValidatorConsensus: false,
                verificationProofs: new string[](0),
                validatorApprovals: 0
            });
            
            emit TrustScoreUpdated(_userWallet, 0, 50, TrustLevel.MEDIUM, block.timestamp, VerificationSource.BLOCKCHAIN);
        }
    }
    
    /**
     * @dev Record a handshake outcome and update trust score
     * @param _userWallet User's wallet address
     * @param _success Whether the handshake was successful
     * @param _proofId Associated proof ID
     */
    function recordHandshakeOutcome(
        address _userWallet,
        bool _success,
        string memory _proofId
    ) external onlyTrustedSource notBlacklisted(_userWallet) {
        TrustRecord storage record = trustRecords[_userWallet];
        
        // Initialize if needed
        if (record.lastUpdateTime == 0) {
            record.userWallet = _userWallet;
            record.baseScore = 50;
            record.adjustedScore = 50;
            record.trustLevel = TrustLevel.MEDIUM;
            record.totalHandshakes = 0;
            record.successfulHandshakes = 0;
            record.failedHandshakes = 0;
            record.lastUpdateTime = block.timestamp;
            record.isVerified = false;
        }
        
        // Update handshake counts
        record.totalHandshakes++;
        if (_success) {
            record.successfulHandshakes++;
            record.verificationProofs.push(_proofId);
        } else {
            record.failedHandshakes++;
        }
        
        // Recalculate trust score
        uint256 oldScore = record.adjustedScore;
        record.adjustedScore = calculateTrustScore(_userWallet);
        record.trustLevel = getTrustLevel(record.adjustedScore);
        record.lastUpdateTime = block.timestamp;
        
        emit TrustScoreUpdated(
            _userWallet, 
            oldScore, 
            record.adjustedScore, 
            record.trustLevel, 
            block.timestamp,
            VerificationSource.BLOCKCHAIN
        );
    }
    
    /**
     * @dev Add verification for a user
     * @param _verificationId Unique verification identifier
     * @param _subject Address being verified
     * @param _source Verification source
     * @param _proofData Proof data (IPFS hash or other)
     */
    function addVerification(
        string memory _verificationId,
        address _subject,
        VerificationSource _source,
        string memory _proofData
    ) external onlyAdmin notBlacklisted(_subject) {
        require(bytes(verifications[_verificationId].verificationId).length == 0, "Verification already exists");
        
        verifications[_verificationId] = VerificationRecord({
            verificationId: _verificationId,
            subject: _subject,
            source: _source,
            proofData: _proofData,
            timestamp: block.timestamp,
            isValid: true,
            verifier: msg.sender,
            validatorVotes: 0,
            consensusProposalId: bytes32(0)
        });
        
        userVerifications[_subject].push(_verificationId);
        
        // Mark user as verified if admin verification
        if (_source == VerificationSource.ADMIN) {
            trustRecords[_subject].isVerified = true;
        }
        
        // Update trust score
        uint256 oldScore = trustRecords[_subject].adjustedScore;
        trustRecords[_subject].adjustedScore = calculateTrustScore(_subject);
        trustRecords[_subject].trustLevel = getTrustLevel(trustRecords[_subject].adjustedScore);
        
        emit VerificationAdded(_verificationId, _subject, _source, block.timestamp);
        emit TrustScoreUpdated(
            _subject, 
            oldScore, 
            trustRecords[_subject].adjustedScore, 
            trustRecords[_subject].trustLevel, 
            block.timestamp,
            _source
        );
    }
    
    /**
     * @dev Calculate trust score based on multiple factors including validator consensus
     * @param _userWallet User's wallet address
     * @return Calculated trust score (0-100)
     */
    function calculateTrustScore(address _userWallet) public view returns (uint256) {
        TrustRecord memory record = trustRecords[_userWallet];
        
        if (record.lastUpdateTime == 0) {
            return 50; // Default score for new users
        }
        
        uint256 score = 0;
        
        // Factor 1: Handshake success rate (30%)
        if (record.totalHandshakes > 0) {
            uint256 successRate = (record.successfulHandshakes * 100) / record.totalHandshakes;
            score += (successRate * HANDSHAKE_SUCCESS_WEIGHT) / 10000;
        } else {
            score += (50 * HANDSHAKE_SUCCESS_WEIGHT) / 10000; // Neutral if no handshakes
        }
        
        // Factor 2: Validator consensus (20%)
        if (record.hasValidatorConsensus) {
            score += (record.consensusScore * VALIDATOR_CONSENSUS_WEIGHT) / 10000;
        } else {
            score += (25 * VALIDATOR_CONSENSUS_WEIGHT) / 10000;
        }
        
        // Factor 3: Verification status (15%)
        if (record.isVerified) {
            score += (100 * VERIFICATION_WEIGHT) / 10000;
        } else if (userVerifications[_userWallet].length > 0) {
            score += (50 * VERIFICATION_WEIGHT) / 10000;
        }
        
        // Factor 4: Time factor - longer history = more trust (10%)
        uint256 accountAge = block.timestamp - record.lastUpdateTime;
        if (accountAge > 365 days) {
            score += (100 * TIME_FACTOR_WEIGHT) / 10000;
        } else if (accountAge > 30 days) {
            score += (50 * TIME_FACTOR_WEIGHT) / 10000;
        } else {
            score += (25 * TIME_FACTOR_WEIGHT) / 10000;
        }
        
        // Factor 5: License ownership (15%) - simplified for now
        score += (50 * LICENSE_OWNERSHIP_WEIGHT) / 10000;
        
        // Factor 6: Community trust (10%) - simplified for now
        score += (50 * COMMUNITY_WEIGHT) / 10000;
        
        // Ensure score is within bounds
        if (score > 100) score = 100;
        
        return score;
    }
    
    /**
     * @dev Get trust level based on score
     * @param _score Trust score
     * @return TrustLevel enum value
     */
    function getTrustLevel(uint256 _score) public pure returns (TrustLevel) {
        if (_score >= 90) return TrustLevel.VERIFIED;
        if (_score >= 75) return TrustLevel.HIGH;
        if (_score >= 50) return TrustLevel.MEDIUM;
        if (_score >= 25) return TrustLevel.LOW;
        return TrustLevel.UNTRUSTED;
    }
    
    /**
     * @dev Check if an address meets minimum trust requirements
     * @param _userWallet User's wallet address
     * @param _minTrustLevel Minimum required trust level
     * @return Boolean indicating if requirements are met
     */
    function meetsTrustRequirement(
        address _userWallet, 
        TrustLevel _minTrustLevel
    ) external view returns (bool) {
        if (blacklistedAddresses[_userWallet]) return false;
        return trustRecords[_userWallet].trustLevel >= _minTrustLevel;
    }
    
    /**
     * @dev Add a trusted AI agent
     * @param _agent Agent address to trust
     */
    function addTrustedAgent(address _agent) external onlyAdmin {
        require(!trustedAgents[_agent], "Already a trusted agent");
        trustedAgents[_agent] = true;
        emit TrustedAgentAdded(_agent, block.timestamp);
    }
    
    /**
     * @dev Remove a trusted AI agent
     * @param _agent Agent address to remove
     */
    function removeTrustedAgent(address _agent) external onlyAdmin {
        require(trustedAgents[_agent], "Not a trusted agent");
        trustedAgents[_agent] = false;
        emit TrustedAgentRemoved(_agent, block.timestamp);
    }
    
    /**
     * @dev Blacklist an address
     * @param _wallet Address to blacklist
     */
    function blacklistAddress(address _wallet) external onlyAdmin {
        require(!blacklistedAddresses[_wallet], "Already blacklisted");
        blacklistedAddresses[_wallet] = true;
        trustRecords[_wallet].trustLevel = TrustLevel.UNTRUSTED;
        emit AddressBlacklisted(_wallet, block.timestamp);
    }
    
    /**
     * @dev Remove address from blacklist
     * @param _wallet Address to whitelist
     */
    function whitelistAddress(address _wallet) external onlyAdmin {
        require(blacklistedAddresses[_wallet], "Not blacklisted");
        blacklistedAddresses[_wallet] = false;
        emit AddressWhitelisted(_wallet, block.timestamp);
    }
    
    /**
     * @dev Get user's trust record
     * @param _userWallet User's wallet address
     * @return TrustRecord struct
     */
    function getTrustRecord(address _userWallet) 
        external 
        view 
        returns (TrustRecord memory) 
    {
        return trustRecords[_userWallet];
    }
    
    /**
     * @dev Get user's verifications
     * @param _userWallet User's wallet address
     * @return Array of verification IDs
     */
    function getUserVerifications(address _userWallet) 
        external 
        view 
        returns (string[] memory) 
    {
        return userVerifications[_userWallet];
    }
    
    /**
     * @dev Request validator consensus for trust verification
     * @param _userWallet User to verify
     * @param _proposedScore Proposed trust score
     */
    function requestValidatorConsensus(
        address _userWallet,
        uint256 _proposedScore
    ) external onlyTrustedSource notBlacklisted(_userWallet) returns (uint256) {
        require(_proposedScore <= 100, "Invalid score");
        require(validatorNetworkAddress != address(0), "Validator network not set");
        
        ValidatorNetwork validator = ValidatorNetwork(validatorNetworkAddress);
        require(validator.isConsensusReady(), "Not enough validators");
        
        // Create data for validator proposal
        bytes32 dataHash = keccak256(abi.encodePacked(_userWallet, _proposedScore, block.timestamp));
        bytes memory proposalData = abi.encode(_userWallet, _proposedScore);
        
        // Create consensus proposal in validator network
        uint256 proposalId = validator.createConsensusProposal(
            dataHash,
            "TRUST_UPDATE",
            proposalData
        );
        
        // Store pending update
        pendingUpdates[proposalId] = PendingTrustUpdate({
            userWallet: _userWallet,
            proposedScore: _proposedScore,
            proposalId: proposalId,
            timestamp: block.timestamp,
            executed: false
        });
        
        userPendingUpdates[_userWallet].push(proposalId);
        
        emit ConsensusVerificationRequested(_userWallet, proposalId, block.timestamp);
        
        return proposalId;
    }
    
    /**
     * @dev Execute approved consensus update
     * @param _proposalId Proposal ID from validator network
     */
    function executeConsensusUpdate(uint256 _proposalId) external {
        PendingTrustUpdate storage update = pendingUpdates[_proposalId];
        require(!update.executed, "Already executed");
        require(update.userWallet != address(0), "Invalid proposal");
        
        // Verify proposal was approved in validator network
        ValidatorNetwork validator = ValidatorNetwork(validatorNetworkAddress);
        ValidatorNetwork.ProposalStatus status = validator.getProposalStatus(_proposalId);
        
        require(status == ValidatorNetwork.ProposalStatus.APPROVED, "Not approved");
        
        // Execute trust update
        TrustRecord storage record = trustRecords[update.userWallet];
        uint256 oldScore = record.adjustedScore;
        
        record.consensusScore = update.proposedScore;
        record.hasValidatorConsensus = true;
        record.validatorApprovals++;
        record.adjustedScore = calculateTrustScore(update.userWallet);
        record.trustLevel = getTrustLevel(record.adjustedScore);
        record.lastUpdateTime = block.timestamp;
        
        update.executed = true;
        
        emit ConsensusVerificationCompleted(
            update.userWallet,
            _proposalId,
            true,
            record.adjustedScore
        );
        
        emit TrustScoreUpdated(
            update.userWallet,
            oldScore,
            record.adjustedScore,
            record.trustLevel,
            block.timestamp,
            VerificationSource.VALIDATOR_CONSENSUS
        );
    }
    
    /**
     * @dev Record AI handshake verification
     * @param _userWallet User's wallet
     * @param _agentId AI agent ID
     * @param _trustLevel Trust level from handshake
     */
    function recordAIHandshakeVerification(
        address _userWallet,
        string memory _agentId,
        uint256 _trustLevel
    ) external notBlacklisted(_userWallet) {
        require(msg.sender == aiHandshakeAddress, "Only AI handshake contract");
        require(_trustLevel <= 100, "Invalid trust level");
        
        TrustRecord storage record = trustRecords[_userWallet];
        
        // Initialize if needed
        if (record.lastUpdateTime == 0) {
            _initializeTrustRecord(_userWallet);
            record = trustRecords[_userWallet];
        }
        
        // Boost trust based on AI handshake
        uint256 trustBoost = (_trustLevel * 20) / 100; // 20% weight for AI verification
        uint256 oldScore = record.adjustedScore;
        
        record.adjustedScore = min(100, record.adjustedScore + trustBoost);
        record.trustLevel = getTrustLevel(record.adjustedScore);
        record.lastUpdateTime = block.timestamp;
        
        emit AIHandshakeVerified(_userWallet, _agentId, trustBoost);
        emit TrustScoreUpdated(
            _userWallet,
            oldScore,
            record.adjustedScore,
            record.trustLevel,
            block.timestamp,
            VerificationSource.AI_HANDSHAKE
        );
    }
    
    /**
     * @dev Check if address is an active validator
     * @param _address Address to check
     */
    function _isActiveValidator(address _address) internal view returns (bool) {
        if (validatorNetworkAddress == address(0)) return false;
        
        ValidatorNetwork validator = ValidatorNetwork(validatorNetworkAddress);
        try validator.validators(_address) returns (
            address, uint256, uint256, ValidatorNetwork.ValidatorStatus status,
            uint256, uint256, uint256, uint256, uint256, bool, string memory, uint256
        ) {
            return status == ValidatorNetwork.ValidatorStatus.ACTIVE;
        } catch {
            return false;
        }
    }
    
    /**
     * @dev Initialize trust record internally
     * @param _userWallet User's wallet address
     */
    function _initializeTrustRecord(address _userWallet) internal {
        trustRecords[_userWallet] = TrustRecord({
            userWallet: _userWallet,
            baseScore: 50,
            adjustedScore: 50,
            consensusScore: 0,
            trustLevel: TrustLevel.MEDIUM,
            totalHandshakes: 0,
            successfulHandshakes: 0,
            failedHandshakes: 0,
            lastUpdateTime: block.timestamp,
            isVerified: false,
            hasValidatorConsensus: false,
            verificationProofs: new string[](0),
            validatorApprovals: 0
        });
    }
    
    /**
     * @dev Update contract addresses
     * @param _proofRegistry New ProofRegistry address
     * @param _licenseAnchor New LicenseAnchor address
     * @param _validatorNetwork New ValidatorNetwork address
     * @param _aiHandshake New AIAgentHandshake address
     */
    function updateContractAddresses(
        address _proofRegistry, 
        address _licenseAnchor,
        address _validatorNetwork,
        address _aiHandshake
    ) external onlyAdmin {
        proofRegistryAddress = _proofRegistry;
        licenseAnchorAddress = _licenseAnchor;
        validatorNetworkAddress = _validatorNetwork;
        aiHandshakeAddress = _aiHandshake;
    }
    
    /**
     * @dev Batch initialize trust records - saves ~55% gas for multiple users
     * @param _userWallets Array of user wallet addresses
     */
    function batchInitializeTrustRecords(
        address[] memory _userWallets
    ) external onlyTrustedSource {
        uint256 currentTime = block.timestamp;
        
        for (uint256 i = 0; i < _userWallets.length; i++) {
            address wallet = _userWallets[i];
            
            if (!blacklistedAddresses[wallet] && trustRecords[wallet].lastUpdateTime == 0) {
                trustRecords[wallet] = TrustRecord({
                    userWallet: wallet,
                    baseScore: 50,
                    adjustedScore: 50,
                    consensusScore: 0,
                    trustLevel: TrustLevel.MEDIUM,
                    totalHandshakes: 0,
                    successfulHandshakes: 0,
                    failedHandshakes: 0,
                    lastUpdateTime: currentTime,
                    isVerified: false,
                    hasValidatorConsensus: false,
                    verificationProofs: new string[](0),
                    validatorApprovals: 0
                });
                
                emit TrustScoreUpdated(wallet, 0, 50, TrustLevel.MEDIUM, currentTime, VerificationSource.BLOCKCHAIN);
            }
        }
    }
    
    /**
     * @dev Batch record handshake outcomes - saves ~60% gas for multiple handshakes
     * @param _userWallets Array of user wallet addresses
     * @param _successes Array of success flags
     * @param _proofIds Array of associated proof IDs
     */
    function batchRecordHandshakeOutcomes(
        address[] memory _userWallets,
        bool[] memory _successes,
        string[] memory _proofIds
    ) external onlyTrustedSource {
        uint256 length = _userWallets.length;
        require(
            _successes.length == length && 
            _proofIds.length == length,
            "Array length mismatch"
        );
        
        uint256 currentTime = block.timestamp;
        
        for (uint256 i = 0; i < length; i++) {
            address wallet = _userWallets[i];
            
            if (blacklistedAddresses[wallet]) continue;
            
            TrustRecord storage record = trustRecords[wallet];
            
            // Initialize if needed
            if (record.lastUpdateTime == 0) {
                record.userWallet = wallet;
                record.baseScore = 50;
                record.adjustedScore = 50;
                record.trustLevel = TrustLevel.MEDIUM;
                record.lastUpdateTime = currentTime;
            }
            
            // Update handshake counts
            record.totalHandshakes++;
            if (_successes[i]) {
                record.successfulHandshakes++;
                record.verificationProofs.push(_proofIds[i]);
            } else {
                record.failedHandshakes++;
            }
            
            // Recalculate trust score
            uint256 oldScore = record.adjustedScore;
            record.adjustedScore = calculateTrustScore(wallet);
            record.trustLevel = getTrustLevel(record.adjustedScore);
            record.lastUpdateTime = currentTime;
            
            emit TrustScoreUpdated(wallet, oldScore, record.adjustedScore, record.trustLevel, currentTime, VerificationSource.BLOCKCHAIN);
        }
    }
    
    /**
     * @dev Batch add verifications - saves ~50% gas for multiple verifications
     * @param _verificationIds Array of verification identifiers
     * @param _subjects Array of addresses being verified
     * @param _sources Array of verification sources
     * @param _proofDatas Array of proof data
     */
    function batchAddVerifications(
        string[] memory _verificationIds,
        address[] memory _subjects,
        VerificationSource[] memory _sources,
        string[] memory _proofDatas
    ) external onlyAdmin {
        uint256 length = _verificationIds.length;
        require(
            _subjects.length == length &&
            _sources.length == length &&
            _proofDatas.length == length,
            "Array length mismatch"
        );
        
        uint256 currentTime = block.timestamp;
        
        for (uint256 i = 0; i < length; i++) {
            if (blacklistedAddresses[_subjects[i]]) continue;
            if (bytes(verifications[_verificationIds[i]].verificationId).length > 0) continue;
            
            verifications[_verificationIds[i]] = VerificationRecord({
                verificationId: _verificationIds[i],
                subject: _subjects[i],
                source: _sources[i],
                proofData: _proofDatas[i],
                timestamp: currentTime,
                isValid: true,
                verifier: msg.sender,
                validatorVotes: 0,
                consensusProposalId: bytes32(0)
            });
            
            userVerifications[_subjects[i]].push(_verificationIds[i]);
            
            if (_sources[i] == VerificationSource.ADMIN) {
                trustRecords[_subjects[i]].isVerified = true;
            }
            
            // Update trust score
            uint256 oldScore = trustRecords[_subjects[i]].adjustedScore;
            trustRecords[_subjects[i]].adjustedScore = calculateTrustScore(_subjects[i]);
            trustRecords[_subjects[i]].trustLevel = getTrustLevel(trustRecords[_subjects[i]].adjustedScore);
            
            emit VerificationAdded(_verificationIds[i], _subjects[i], _sources[i], currentTime);
            emit TrustScoreUpdated(
                _subjects[i], 
                oldScore, 
                trustRecords[_subjects[i]].adjustedScore, 
                trustRecords[_subjects[i]].trustLevel, 
                currentTime,
                _sources[i]
            );
        }
    }
    
    /**
     * @dev Batch add/remove trusted agents - saves gas for multiple agent updates
     * @param _agents Array of agent addresses
     * @param _trusted Array of trust status (true = add, false = remove)
     */
    function batchUpdateTrustedAgents(
        address[] memory _agents,
        bool[] memory _trusted
    ) external onlyAdmin {
        require(_agents.length == _trusted.length, "Array length mismatch");
        
        uint256 currentTime = block.timestamp;
        
        for (uint256 i = 0; i < _agents.length; i++) {
            if (_trusted[i] && !trustedAgents[_agents[i]]) {
                trustedAgents[_agents[i]] = true;
                emit TrustedAgentAdded(_agents[i], currentTime);
            } else if (!_trusted[i] && trustedAgents[_agents[i]]) {
                trustedAgents[_agents[i]] = false;
                emit TrustedAgentRemoved(_agents[i], currentTime);
            }
        }
    }
    
    /**
     * @dev Batch blacklist/whitelist addresses - saves gas for multiple updates
     * @param _wallets Array of wallet addresses
     * @param _blacklist Array of blacklist status (true = blacklist, false = whitelist)
     */
    function batchUpdateBlacklist(
        address[] memory _wallets,
        bool[] memory _blacklist
    ) external onlyAdmin {
        require(_wallets.length == _blacklist.length, "Array length mismatch");
        
        uint256 currentTime = block.timestamp;
        
        for (uint256 i = 0; i < _wallets.length; i++) {
            if (_blacklist[i] && !blacklistedAddresses[_wallets[i]]) {
                blacklistedAddresses[_wallets[i]] = true;
                trustRecords[_wallets[i]].trustLevel = TrustLevel.UNTRUSTED;
                emit AddressBlacklisted(_wallets[i], currentTime);
            } else if (!_blacklist[i] && blacklistedAddresses[_wallets[i]]) {
                blacklistedAddresses[_wallets[i]] = false;
                emit AddressWhitelisted(_wallets[i], currentTime);
            }
        }
    }
    
    /**
     * @dev Batch get trust records - view function, no gas cost
     * @param _userWallets Array of user wallet addresses
     * @return Array of TrustRecord structs
     */
    function batchGetTrustRecords(
        address[] memory _userWallets
    ) external view returns (TrustRecord[] memory) {
        TrustRecord[] memory records = new TrustRecord[](_userWallets.length);
        
        for (uint256 i = 0; i < _userWallets.length; i++) {
            records[i] = trustRecords[_userWallets[i]];
        }
        
        return records;
    }
    
    /**
     * @dev Batch check trust requirements - view function, no gas cost
     * @param _userWallets Array of user wallet addresses
     * @param _minTrustLevel Minimum required trust level
     * @return Array of booleans indicating if requirements are met
     */
    function batchMeetsTrustRequirement(
        address[] memory _userWallets,
        TrustLevel _minTrustLevel
    ) external view returns (bool[] memory) {
        bool[] memory meets = new bool[](_userWallets.length);
        
        for (uint256 i = 0; i < _userWallets.length; i++) {
            if (!blacklistedAddresses[_userWallets[i]]) {
                meets[i] = trustRecords[_userWallets[i]].trustLevel >= _minTrustLevel;
            }
        }
        
        return meets;
    }
    
    /**
     * @dev Update admin address
     * @param _newAdmin New admin address
     */
    function updateAdmin(address _newAdmin) external onlyAdmin {
        require(_newAdmin != address(0), "Invalid admin address");
        admin = _newAdmin;
    }
    
    // Utility functions
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }
}"
    },
    "contracts/ValidatorNetwork.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/**
 * @title ValidatorNetwork
 * @dev Decentralized validator network with Byzantine fault tolerance for Shuka
 * @notice Implements multi-validator consensus for trust verification
 */
contract ValidatorNetwork {
    
    // Validator states
    enum ValidatorStatus { INACTIVE, ACTIVE, SUSPENDED, SLASHED }
    
    // Consensus proposal states
    enum ProposalStatus { PENDING, APPROVED, REJECTED, EXECUTED, EXPIRED }
    
    // Validator information
    struct Validator {
        address validatorAddress;
        uint256 stakedAmount;
        uint256 reputationScore;
        ValidatorStatus status;
        uint256 totalValidations;
        uint256 successfulValidations;
        uint256 failedValidations;
        uint256 lastActiveBlock;
        uint256 slashingEvents;
        bool isAIAgent;
        string aiAgentId;
        uint256 joinedAt;
    }
    
    // Consensus proposal for validation
    struct ConsensusProposal {
        uint256 proposalId;
        address proposer;
        bytes32 dataHash;
        string proposalType;
        bytes proposalData;
        uint256 votesFor;
        uint256 votesAgainst;
        uint256 totalVotes;
        mapping(address => bool) hasVoted;
        mapping(address => bool) voteValue;
        ProposalStatus status;
        uint256 createdAt;
        uint256 executedAt;
        uint256 expiresAt;
    }
    
    // AI Agent validation record
    struct AIValidation {
        string agentId;
        address agentWallet;
        bytes32 validationHash;
        uint256 confidence;
        string validationType;
        uint256 timestamp;
        bool isValid;
    }
    
    // Constants for Byzantine fault tolerance
    uint256 public constant MINIMUM_VALIDATORS = 3;
    uint256 public constant BYZANTINE_THRESHOLD = 67; // 67% for Byzantine fault tolerance
    uint256 public constant MINIMUM_STAKE = 0.01 ether;
    uint256 public constant SLASHING_PENALTY = 10; // 10% of stake
    uint256 public constant PROPOSAL_DURATION = 1 hours;
    uint256 public constant VALIDATOR_TIMEOUT = 7 days;
    
    // State variables
    address public admin;
    address public trustOracleAddress;
    address public proofRegistryAddress;
    
    mapping(address => Validator) public validators;
    mapping(uint256 => ConsensusProposal) public proposals;
    mapping(string => AIValidation[]) public aiValidations;
    mapping(address => uint256) public pendingRewards;
    mapping(bytes32 => bool) public processedValidations;
    
    address[] public activeValidatorList;
    uint256 public proposalCounter;
    uint256 public totalStaked;
    uint256 public totalValidations;
    uint256 public rewardPool;
    
    // Events
    event ValidatorJoined(address indexed validator, uint256 stake, bool isAI);
    event ValidatorExited(address indexed validator, uint256 returnedStake);
    event ValidatorSlashed(address indexed validator, uint256 penalty, string reason);
    event ProposalCreated(uint256 indexed proposalId, address proposer, string proposalType);
    event VoteCast(uint256 indexed proposalId, address voter, bool support);
    event ProposalExecuted(uint256 indexed proposalId, bool approved);
    event ValidationRecorded(bytes32 validationHash, address validator, bool result);
    event RewardDistributed(address indexed validator, uint256 amount);
    event AIValidationRecorded(string agentId, bytes32 validationHash, uint256 confidence);
    
    // Modifiers
    modifier onlyAdmin() {
        require(msg.sender == admin, "Only admin");
        _;
    }
    
    modifier onlyActiveValidator() {
        require(validators[msg.sender].status == ValidatorStatus.ACTIVE, "Not active validator");
        _;
    }
    
    modifier validatorExists(address _validator) {
        require(validators[_validator].validatorAddress != address(0), "Validator not found");
        _;
    }
    
    constructor(address _trustOracle, address _proofRegistry) {
        admin = msg.sender;
        trustOracleAddress = _trustOracle;
        proofRegistryAddress = _proofRegistry;
    }
    
    /**
     * @dev Join as a validator by staking ETH
     * @param _isAIAgent Whether this is an AI agent validator
     * @param _aiAgentId ID of the AI agent (if applicable)
     */
    function joinAsValidator(bool _isAIAgent, string memory _aiAgentId) external payable {
        require(msg.value >= MINIMUM_STAKE, "Insufficient stake");
        require(validators[msg.sender].validatorAddress == address(0), "Already a validator");
        
        validators[msg.sender] = Validator({
            validatorAddress: msg.sender,
            stakedAmount: msg.value,
            reputationScore: 100,
            status: ValidatorStatus.ACTIVE,
            totalValidations: 0,
            successfulValidations: 0,
            failedValidations: 0,
            lastActiveBlock: block.number,
            slashingEvents: 0,
            isAIAgent: _isAIAgent,
            aiAgentId: _aiAgentId,
            joinedAt: block.timestamp
        });
        
        activeValidatorList.push(msg.sender);
        totalStaked += msg.value;
        
        emit ValidatorJoined(msg.sender, msg.value, _isAIAgent);
    }
    
    /**
     * @dev Create a consensus proposal for validation
     * @param _dataHash Hash of the data to validate
     * @param _proposalType Type of proposal
     * @param _proposalData Encoded proposal data
     */
    function createConsensusProposal(
        bytes32 _dataHash,
        string memory _proposalType,
        bytes memory _proposalData
    ) public onlyActiveValidator returns (uint256) {
        require(!processedValidations[_dataHash], "Already processed");
        
        uint256 proposalId = ++proposalCounter;
        
        ConsensusProposal storage proposal = proposals[proposalId];
        proposal.proposalId = proposalId;
        proposal.proposer = msg.sender;
        proposal.dataHash = _dataHash;
        proposal.proposalType = _proposalType;
        proposal.proposalData = _proposalData;
        proposal.status = ProposalStatus.PENDING;
        proposal.createdAt = block.timestamp;
        proposal.expiresAt = block.timestamp + PROPOSAL_DURATION;
        
        emit ProposalCreated(proposalId, msg.sender, _proposalType);
        
        return proposalId;
    }
    
    /**
     * @dev Vote on a consensus proposal
     * @param _proposalId ID of the proposal
     * @param _support Whether to support the proposal
     */
    function voteOnProposal(uint256 _proposalId, bool _support) external onlyActiveValidator {
        ConsensusProposal storage proposal = proposals[_proposalId];
        require(proposal.status == ProposalStatus.PENDING, "Proposal not pending");
        require(block.timestamp <= proposal.expiresAt, "Proposal expired");
        require(!proposal.hasVoted[msg.sender], "Already voted");
        
        proposal.hasVoted[msg.sender] = true;
        proposal.voteValue[msg.sender] = _support;
        proposal.totalVotes++;
        
        // Weight vote by stake
        uint256 voteWeight = validators[msg.sender].stakedAmount;
        
        if (_support) {
            proposal.votesFor += voteWeight;
        } else {
            proposal.votesAgainst += voteWeight;
        }
        
        emit VoteCast(_proposalId, msg.sender, _support);
        
        // Check if we have enough votes to execute
        _checkAndExecuteProposal(_proposalId);
    }
    
    /**
     * @dev Check if proposal has reached consensus and execute
     * @param _proposalId ID of the proposal
     */
    function _checkAndExecuteProposal(uint256 _proposalId) internal {
        ConsensusProposal storage proposal = proposals[_proposalId];
        
        // Need participation from at least 2/3 of validators
        uint256 requiredParticipation = (activeValidatorList.length * 2) / 3;
        if (proposal.totalVotes < requiredParticipation && proposal.totalVotes < MINIMUM_VALIDATORS) {
            return;
        }
        
        uint256 totalVoteWeight = proposal.votesFor + proposal.votesAgainst;
        if (totalVoteWeight == 0) return;
        
        uint256 approvalPercentage = (proposal.votesFor * 100) / totalVoteWeight;
        
        if (approvalPercentage >= BYZANTINE_THRESHOLD) {
            proposal.status = ProposalStatus.APPROVED;
            proposal.executedAt = block.timestamp;
            processedValidations[proposal.dataHash] = true;
            
            // Reward validators who voted correctly
            _distributeRewards(_proposalId, true);
            
            // Execute proposal action
            _executeProposalAction(proposal);
            
            emit ProposalExecuted(_proposalId, true);
        } else if (approvalPercentage < (100 - BYZANTINE_THRESHOLD)) {
            proposal.status = ProposalStatus.REJECTED;
            proposal.executedAt = block.timestamp;
            
            // Punish validators who voted incorrectly
            _distributeRewards(_proposalId, false);
            
            emit ProposalExecuted(_proposalId, false);
        }
    }
    
    /**
     * @dev Execute the action specified in an approved proposal
     * @param proposal The approved proposal
     */
    function _executeProposalAction(ConsensusProposal storage proposal) internal {
        // Decode and execute based on proposal type
        if (keccak256(bytes(proposal.proposalType)) == keccak256("TRUST_UPDATE")) {
            // Call TrustOracle to update trust score
            (bool success,) = trustOracleAddress.call(proposal.proposalData);
            require(success, "Trust update failed");
        } else if (keccak256(bytes(proposal.proposalType)) == keccak256("PROOF_VALIDATION")) {
            // Call ProofRegistry to validate proof
            (bool success,) = proofRegistryAddress.call(proposal.proposalData);
            require(success, "Proof validation failed");
        }
        
        emit ValidationRecorded(proposal.dataHash, proposal.proposer, true);
    }
    
    /**
     * @dev Distribute rewards to validators based on voting outcome
     * @param _proposalId ID of the proposal
     * @param _approvedOutcome Whether the proposal was approved
     */
    function _distributeRewards(uint256 _proposalId, bool _approvedOutcome) internal {
        ConsensusProposal storage proposal = proposals[_proposalId];
        uint256 rewardPerValidator = rewardPool / (proposal.totalVotes > 0 ? proposal.totalVotes : 1);
        
        for (uint256 i = 0; i < activeValidatorList.length; i++) {
            address validator = activeValidatorList[i];
            if (proposal.hasVoted[validator]) {
                bool votedCorrectly = proposal.voteValue[validator] == _approvedOutcome;
                
                if (votedCorrectly) {
                    // Reward for correct vote
                    pendingRewards[validator] += rewardPerValidator;
                    validators[validator].successfulValidations++;
                    validators[validator].reputationScore = min(100, validators[validator].reputationScore + 1);
                    
                    emit RewardDistributed(validator, rewardPerValidator);
                } else {
                    // Penalty for incorrect vote
                    validators[validator].failedValidations++;
                    validators[validator].reputationScore = validators[validator].reputationScore > 5 ? 
                        validators[validator].reputationScore - 5 : 0;
                    
                    // Slash if reputation too low
                    if (validators[validator].reputationScore < 20) {
                        _slashValidator(validator, "Low reputation");
                    }
                }
                
                validators[validator].totalValidations++;
            }
        }
    }
    
    /**
     * @dev Record validation from an AI agent
     * @param _agentId ID of the AI agent
     * @param _validationHash Hash of the validation
     * @param _confidence Confidence level (0-100)
     * @param _validationType Type of validation
     */
    function recordAIValidation(
        string memory _agentId,
        bytes32 _validationHash,
        uint256 _confidence,
        string memory _validationType
    ) external onlyActiveValidator {
        require(validators[msg.sender].isAIAgent, "Not an AI validator");
        require(_confidence <= 100, "Invalid confidence");
        
        AIValidation memory validation = AIValidation({
            agentId: _agentId,
            agentWallet: msg.sender,
            validationHash: _validationHash,
            confidence: _confidence,
            validationType: _validationType,
            timestamp: block.timestamp,
            isValid: true
        });
        
        aiValidations[_agentId].push(validation);
        
        // Update validator activity
        validators[msg.sender].lastActiveBlock = block.number;
        validators[msg.sender].totalValidations++;
        
        emit AIValidationRecorded(_agentId, _validationHash, _confidence);
        
        // If confidence is high enough, auto-create proposal
        if (_confidence >= 80) {
            by

Tags:
Multisig, Staking, Voting, Multi-Signature, Factory, Oracle|addr:0x126d2bdf2af268cd74f3a1d403317ccfaa77247d|verified:true|block:23461354|tx:0x9f09df642ceee2a9261bc06110dc56bee0e1dd431c649468efda192ba933cf1e|first_check:1759068181

Submitted on: 2025-09-28 16:03:01

Comments

Log in to comment.

No comments yet.