///! # 合规检查系统 ///! ///! Compliance Checking System ///! 提供KYC/AML和合规验证功能 ///! ///! **版本**: v1.0 ///! **模块**: charter-std/sovereignty/compliance.ch use utils::crypto::sha3_384_hash; // ============================================================================ // 合规级别枚举 // ============================================================================ /// KYC级别 pub enum KYCLevel { /// 未验证 None, /// 基础验证(姓名、邮箱) Basic, /// 中级验证(身份证件) Intermediate, /// 高级验证(生物识别) Advanced, /// 机构验证 Institutional } /// AML风险级别 pub enum AMLRiskLevel { /// 低风险 Low, /// 中风险 Medium, /// 高风险 High, /// 禁止 Prohibited } /// 合规状态 pub enum ComplianceStatus { /// 未检查 Unchecked, /// 检查中 Checking, /// 通过 Passed, /// 失败 Failed, /// 需要更新 NeedsUpdate } // ============================================================================ // 合规信息结构 // ============================================================================ /// KYC信息 struct KYCInfo { /// 用户地址 user: Address, /// KYC级别 level: KYCLevel, /// 验证时间 verified_at: Timestamp, /// 过期时间 expires_at: Timestamp, /// 验证机构 verifier: Address, /// 文档哈希 document_hash: Hash, /// 国家代码(ISO 3166-1) country_code: String, /// 是否被制裁 is_sanctioned: bool } /// AML检查记录 struct AMLCheckRecord { /// 检查ID check_id: Hash, /// 用户地址 user: Address, /// 风险级别 risk_level: AMLRiskLevel, /// 检查时间 checked_at: Timestamp, /// 检查机构 checker: Address, /// 风险评分(0-100) risk_score: u8, /// 风险因素 risk_factors: Vec, /// 报告哈希 report_hash: Hash } /// 白名单记录 struct WhitelistRecord { /// 地址 address: Address, /// 添加时间 added_at: Timestamp, /// 添加者 added_by: Address, /// 原因 reason: String, /// 过期时间(可选) expires_at: Option } /// 黑名单记录 struct BlacklistRecord { /// 地址 address: Address, /// 添加时间 added_at: Timestamp, /// 添加者 added_by: Address, /// 原因 reason: String, /// 是否永久 is_permanent: bool } /// 地域限制 struct GeoRestriction { /// 国家代码 country_code: String, /// 是否允许 is_allowed: bool, /// 原因 reason: String } // ============================================================================ // 合规事件 // ============================================================================ /// KYC验证事件 event KYCVerified { user: Address, level: KYCLevel, verifier: Address, timestamp: Timestamp } /// AML检查事件 event AMLChecked { check_id: Hash, user: Address, risk_level: AMLRiskLevel, risk_score: u8, timestamp: Timestamp } /// 白名单添加事件 event WhitelistAdded { address: Address, added_by: Address, reason: String, timestamp: Timestamp } /// 黑名单添加事件 event BlacklistAdded { address: Address, added_by: Address, reason: String, timestamp: Timestamp } /// 合规检查失败事件 event ComplianceFailed { user: Address, reason: String, timestamp: Timestamp } // ============================================================================ // 合规检查系统 // ============================================================================ /// 合规检查系统 certificate ComplianceChecker { /// KYC信息存储 (user => kyc_info) let _kyc_info: Map; /// AML检查记录 (user => check_records) let _aml_records: Map>; /// 白名单 let _whitelist: Map; /// 黑名单 let _blacklist: Map; /// 地域限制 (country_code => restriction) let _geo_restrictions: Map; /// 管理员地址 let _admin: Address; /// KYC验证机构集合 let _kyc_verifiers: Set
; /// AML检查机构集合 let _aml_checkers: Set
; /// 最低KYC级别要求 let _min_kyc_level: KYCLevel; /// 最高AML风险级别允许 let _max_aml_risk: AMLRiskLevel; // ========== 构造函数 ========== constructor() { self._admin = msg.sender; self._kyc_verifiers.insert(msg.sender); self._aml_checkers.insert(msg.sender); self._min_kyc_level = KYCLevel::Basic; self._max_aml_risk = AMLRiskLevel::Medium; } // ========== KYC管理 ========== /// 设置KYC信息 /// /// # 参数 /// - `user`: 用户地址 /// - `level`: KYC级别 /// - `expires_at`: 过期时间 /// - `document_hash`: 文档哈希 /// - `country_code`: 国家代码 /// /// # 返回 /// - `bool`: 是否成功 pub fn set_kyc( user: Address, level: KYCLevel, expires_at: Timestamp, document_hash: Hash, country_code: String ) -> bool { require(self._kyc_verifiers.contains(msg.sender), "Not a KYC verifier"); require(!user.is_zero(), "Invalid user"); require(expires_at > block.timestamp, "Invalid expiry time"); require(!country_code.is_empty(), "Country code required"); // 检查地域限制 if let Some(restriction) = self._geo_restrictions.get(country_code.clone()) { require(restriction.is_allowed, "Country not allowed"); } let kyc_info = KYCInfo { user: user, level: level, verified_at: block.timestamp, expires_at: expires_at, verifier: msg.sender, document_hash: document_hash, country_code: country_code, is_sanctioned: false }; self._kyc_info[user] = kyc_info; emit KYCVerified { user: user, level: level, verifier: msg.sender, timestamp: block.timestamp }; return true; } /// 获取KYC信息 /// /// # 参数 /// - `user`: 用户地址 /// /// # 返回 /// - `Option`: KYC信息 pub fn get_kyc(user: Address) -> Option { return self._kyc_info.get(user); } /// 检查KYC是否有效 /// /// # 参数 /// - `user`: 用户地址 /// /// # 返回 /// - `bool`: 是否有效 pub fn is_kyc_valid(user: Address) -> bool { if let Some(kyc) = self._kyc_info.get(user) { return block.timestamp < kyc.expires_at && !kyc.is_sanctioned; } return false; } /// 检查KYC级别是否满足要求 /// /// # 参数 /// - `user`: 用户地址 /// - `required_level`: 要求的级别 /// /// # 返回 /// - `bool`: 是否满足 pub fn check_kyc_level(user: Address, required_level: KYCLevel) -> bool { if let Some(kyc) = self._kyc_info.get(user) { if !self.is_kyc_valid(user) { return false; } return self._compare_kyc_level(kyc.level, required_level); } return false; } /// 标记为制裁对象 /// /// # 参数 /// - `user`: 用户地址 /// /// # 返回 /// - `bool`: 是否成功 pub fn mark_sanctioned(user: Address) -> bool { require(msg.sender == self._admin, "Only admin"); require(self._kyc_info.contains_key(user), "KYC not found"); let mut kyc = self._kyc_info[user]; kyc.is_sanctioned = true; self._kyc_info[user] = kyc; return true; } // ========== AML检查 ========== /// 执行AML检查 /// /// # 参数 /// - `user`: 用户地址 /// - `risk_level`: 风险级别 /// - `risk_score`: 风险评分 /// - `risk_factors`: 风险因素 /// - `report_hash`: 报告哈希 /// /// # 返回 /// - `Hash`: 检查ID pub fn perform_aml_check( user: Address, risk_level: AMLRiskLevel, risk_score: u8, risk_factors: Vec, report_hash: Hash ) -> Hash { require(self._aml_checkers.contains(msg.sender), "Not an AML checker"); require(!user.is_zero(), "Invalid user"); require(risk_score <= 100, "Invalid risk score"); // 生成检查ID let check_id = self._generate_check_id(user); let record = AMLCheckRecord { check_id: check_id, user: user, risk_level: risk_level, checked_at: block.timestamp, checker: msg.sender, risk_score: risk_score, risk_factors: risk_factors, report_hash: report_hash }; // 存储记录 if !self._aml_records.contains_key(user) { self._aml_records[user] = Vec::new(); } self._aml_records[user].push(record); emit AMLChecked { check_id: check_id, user: user, risk_level: risk_level, risk_score: risk_score, timestamp: block.timestamp }; return check_id; } /// 获取最新的AML检查记录 /// /// # 参数 /// - `user`: 用户地址 /// /// # 返回 /// - `Option`: AML检查记录 pub fn get_latest_aml_check(user: Address) -> Option { if let Some(records) = self._aml_records.get(user) { if records.len() > 0 { return Some(records[records.len() - 1]); } } return None; } /// 获取所有AML检查记录 /// /// # 参数 /// - `user`: 用户地址 /// /// # 返回 /// - `Vec`: AML检查记录列表 pub fn get_aml_history(user: Address) -> Vec { return self._aml_records.get(user).unwrap_or(Vec::new()); } /// 检查AML风险是否可接受 /// /// # 参数 /// - `user`: 用户地址 /// /// # 返回 /// - `bool`: 是否可接受 pub fn is_aml_acceptable(user: Address) -> bool { if let Some(record) = self.get_latest_aml_check(user) { return self._compare_aml_risk(record.risk_level, self._max_aml_risk); } return false; } // ========== 白名单管理 ========== /// 添加到白名单 /// /// # 参数 /// - `address`: 地址 /// - `reason`: 原因 /// - `expires_at`: 过期时间(可选) /// /// # 返回 /// - `bool`: 是否成功 pub fn add_to_whitelist( address: Address, reason: String, expires_at: Option ) -> bool { require(msg.sender == self._admin, "Only admin"); require(!address.is_zero(), "Invalid address"); if let Some(expiry) = expires_at { require(expiry > block.timestamp, "Invalid expiry time"); } let record = WhitelistRecord { address: address, added_at: block.timestamp, added_by: msg.sender, reason: reason.clone(), expires_at: expires_at }; self._whitelist[address] = record; emit WhitelistAdded { address: address, added_by: msg.sender, reason: reason, timestamp: block.timestamp }; return true; } /// 从白名单移除 /// /// # 参数 /// - `address`: 地址 /// /// # 返回 /// - `bool`: 是否成功 pub fn remove_from_whitelist(address: Address) -> bool { require(msg.sender == self._admin, "Only admin"); self._whitelist.remove(address); return true; } /// 检查是否在白名单 /// /// # 参数 /// - `address`: 地址 /// /// # 返回 /// - `bool`: 是否在白名单 pub fn is_whitelisted(address: Address) -> bool { if let Some(record) = self._whitelist.get(address) { // 检查是否过期 if let Some(expiry) = record.expires_at { return block.timestamp < expiry; } return true; } return false; } // ========== 黑名单管理 ========== /// 添加到黑名单 /// /// # 参数 /// - `address`: 地址 /// - `reason`: 原因 /// - `is_permanent`: 是否永久 /// /// # 返回 /// - `bool`: 是否成功 pub fn add_to_blacklist( address: Address, reason: String, is_permanent: bool ) -> bool { require(msg.sender == self._admin, "Only admin"); require(!address.is_zero(), "Invalid address"); let record = BlacklistRecord { address: address, added_at: block.timestamp, added_by: msg.sender, reason: reason.clone(), is_permanent: is_permanent }; self._blacklist[address] = record; emit BlacklistAdded { address: address, added_by: msg.sender, reason: reason, timestamp: block.timestamp }; return true; } /// 从黑名单移除 /// /// # 参数 /// - `address`: 地址 /// /// # 返回 /// - `bool`: 是否成功 pub fn remove_from_blacklist(address: Address) -> bool { require(msg.sender == self._admin, "Only admin"); if let Some(record) = self._blacklist.get(address) { require(!record.is_permanent, "Cannot remove permanent blacklist"); } self._blacklist.remove(address); return true; } /// 检查是否在黑名单 /// /// # 参数 /// - `address`: 地址 /// /// # 返回 /// - `bool`: 是否在黑名单 pub fn is_blacklisted(address: Address) -> bool { return self._blacklist.contains_key(address); } // ========== 地域限制 ========== /// 设置地域限制 /// /// # 参数 /// - `country_code`: 国家代码 /// - `is_allowed`: 是否允许 /// - `reason`: 原因 /// /// # 返回 /// - `bool`: 是否成功 pub fn set_geo_restriction( country_code: String, is_allowed: bool, reason: String ) -> bool { require(msg.sender == self._admin, "Only admin"); require(!country_code.is_empty(), "Country code required"); let restriction = GeoRestriction { country_code: country_code.clone(), is_allowed: is_allowed, reason: reason }; self._geo_restrictions[country_code] = restriction; return true; } /// 检查国家是否允许 /// /// # 参数 /// - `country_code`: 国家代码 /// /// # 返回 /// - `bool`: 是否允许 pub fn is_country_allowed(country_code: String) -> bool { if let Some(restriction) = self._geo_restrictions.get(country_code) { return restriction.is_allowed; } // 默认允许 return true; } // ========== 综合合规检查 ========== /// 执行完整的合规检查 /// /// # 参数 /// - `user`: 用户地址 /// /// # 返回 /// - `ComplianceStatus`: 合规状态 pub fn check_compliance(user: Address) -> ComplianceStatus { // 1. 检查黑名单 if self.is_blacklisted(user) { emit ComplianceFailed { user: user, reason: "User is blacklisted", timestamp: block.timestamp }; return ComplianceStatus::Failed; } // 2. 白名单用户直接通过 if self.is_whitelisted(user) { return ComplianceStatus::Passed; } // 3. 检查KYC if !self.is_kyc_valid(user) { emit ComplianceFailed { user: user, reason: "KYC not valid", timestamp: block.timestamp }; return ComplianceStatus::Failed; } if !self.check_kyc_level(user, self._min_kyc_level) { emit ComplianceFailed { user: user, reason: "KYC level insufficient", timestamp: block.timestamp }; return ComplianceStatus::Failed; } // 4. 检查AML if !self.is_aml_acceptable(user) { emit ComplianceFailed { user: user, reason: "AML risk too high", timestamp: block.timestamp }; return ComplianceStatus::Failed; } // 5. 检查地域限制 if let Some(kyc) = self.get_kyc(user) { if !self.is_country_allowed(kyc.country_code) { emit ComplianceFailed { user: user, reason: "Country not allowed", timestamp: block.timestamp }; return ComplianceStatus::Failed; } } return ComplianceStatus::Passed; } /// 检查用户是否合规 /// /// # 参数 /// - `user`: 用户地址 /// /// # 返回 /// - `bool`: 是否合规 pub fn is_compliant(user: Address) -> bool { return self.check_compliance(user) == ComplianceStatus::Passed; } // ========== 内部函数 ========== /// 生成检查ID fn _generate_check_id(user: Address) -> Hash { let mut data = Bytes::new(); data.extend(user.as_bytes()); data.extend(block.timestamp.to_bytes()); data.extend(tx.hash.as_bytes()); return sha3_384_hash(data); } /// 比较KYC级别 fn _compare_kyc_level(level: KYCLevel, required: KYCLevel) -> bool { let level_value = match level { KYCLevel::None => 0, KYCLevel::Basic => 1, KYCLevel::Intermediate => 2, KYCLevel::Advanced => 3, KYCLevel::Institutional => 4 }; let required_value = match required { KYCLevel::None => 0, KYCLevel::Basic => 1, KYCLevel::Intermediate => 2, KYCLevel::Advanced => 3, KYCLevel::Institutional => 4 }; return level_value >= required_value; } /// 比较AML风险级别 fn _compare_aml_risk(level: AMLRiskLevel, max_allowed: AMLRiskLevel) -> bool { let level_value = match level { AMLRiskLevel::Low => 1, AMLRiskLevel::Medium => 2, AMLRiskLevel::High => 3, AMLRiskLevel::Prohibited => 4 }; let max_value = match max_allowed { AMLRiskLevel::Low => 1, AMLRiskLevel::Medium => 2, AMLRiskLevel::High => 3, AMLRiskLevel::Prohibited => 4 }; return level_value <= max_value; } // ========== 管理函数 ========== /// 添加KYC验证机构 pub fn add_kyc_verifier(verifier: Address) -> bool { require(msg.sender == self._admin, "Only admin"); self._kyc_verifiers.insert(verifier); return true; } /// 移除KYC验证机构 pub fn remove_kyc_verifier(verifier: Address) -> bool { require(msg.sender == self._admin, "Only admin"); self._kyc_verifiers.remove(verifier); return true; } /// 添加AML检查机构 pub fn add_aml_checker(checker: Address) -> bool { require(msg.sender == self._admin, "Only admin"); self._aml_checkers.insert(checker); return true; } /// 移除AML检查机构 pub fn remove_aml_checker(checker: Address) -> bool { require(msg.sender == self._admin, "Only admin"); self._aml_checkers.remove(checker); return true; } /// 设置最低KYC级别 pub fn set_min_kyc_level(level: KYCLevel) -> bool { require(msg.sender == self._admin, "Only admin"); self._min_kyc_level = level; return true; } /// 设置最高AML风险级别 pub fn set_max_aml_risk(level: AMLRiskLevel) -> bool { require(msg.sender == self._admin, "Only admin"); self._max_aml_risk = level; return true; } }