838 lines
21 KiB
Plaintext
838 lines
21 KiB
Plaintext
///! # 合规检查系统
|
||
///!
|
||
///! 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<String>,
|
||
|
||
/// 报告哈希
|
||
report_hash: Hash
|
||
}
|
||
|
||
/// 白名单记录
|
||
struct WhitelistRecord {
|
||
/// 地址
|
||
address: Address,
|
||
|
||
/// 添加时间
|
||
added_at: Timestamp,
|
||
|
||
/// 添加者
|
||
added_by: Address,
|
||
|
||
/// 原因
|
||
reason: String,
|
||
|
||
/// 过期时间(可选)
|
||
expires_at: Option<Timestamp>
|
||
}
|
||
|
||
/// 黑名单记录
|
||
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<Address, KYCInfo>;
|
||
|
||
/// AML检查记录 (user => check_records)
|
||
let _aml_records: Map<Address, Vec<AMLCheckRecord>>;
|
||
|
||
/// 白名单
|
||
let _whitelist: Map<Address, WhitelistRecord>;
|
||
|
||
/// 黑名单
|
||
let _blacklist: Map<Address, BlacklistRecord>;
|
||
|
||
/// 地域限制 (country_code => restriction)
|
||
let _geo_restrictions: Map<String, GeoRestriction>;
|
||
|
||
/// 管理员地址
|
||
let _admin: Address;
|
||
|
||
/// KYC验证机构集合
|
||
let _kyc_verifiers: Set<Address>;
|
||
|
||
/// AML检查机构集合
|
||
let _aml_checkers: Set<Address>;
|
||
|
||
/// 最低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<KYCInfo>`: KYC信息
|
||
pub fn get_kyc(user: Address) -> Option<KYCInfo> {
|
||
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<String>,
|
||
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<AMLCheckRecord>`: AML检查记录
|
||
pub fn get_latest_aml_check(user: Address) -> Option<AMLCheckRecord> {
|
||
if let Some(records) = self._aml_records.get(user) {
|
||
if records.len() > 0 {
|
||
return Some(records[records.len() - 1]);
|
||
}
|
||
}
|
||
return None;
|
||
}
|
||
|
||
/// 获取所有AML检查记录
|
||
///
|
||
/// # 参数
|
||
/// - `user`: 用户地址
|
||
///
|
||
/// # 返回
|
||
/// - `Vec<AMLCheckRecord>`: AML检查记录列表
|
||
pub fn get_aml_history(user: Address) -> Vec<AMLCheckRecord> {
|
||
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<Timestamp>
|
||
) -> 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;
|
||
}
|
||
}
|