// ACC-Valuation: 资产估值协议(Valuation Protocol) // // NAC原生的资产估值标准,用于资产价值评估和管理 // 100% NAC原生协议,不是任何现有标准的实现 use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// 估值方法 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum ValuationMethod { /// 市场法 MarketApproach, /// 收益法 IncomeApproach, /// 成本法 CostApproach, /// 其他 Other(String), } /// 估值记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ValuationRecord { /// 估值ID pub valuation_id: String, /// 资产ID pub asset_id: String, /// 估值方法 pub method: ValuationMethod, /// 估值金额(USD,以分为单位) pub value: u128, /// 估值师地址 pub appraiser: String, /// 估值时间 pub timestamp: u64, /// 有效期(秒) pub validity_period: u64, /// 备注 pub notes: Vec, } /// 估值错误类型 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum ValuationError { /// 估值记录不存在 RecordNotFound, /// 估值记录已存在 RecordAlreadyExists, /// 估值已过期 ValuationExpired, /// 无效的估值金额 InvalidValue, /// 未授权操作 Unauthorized, } /// 估值状态 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ValuationState { /// 估值记录映射 (valuation_id -> ValuationRecord) pub valuations: HashMap, /// 资产估值历史 (asset_id -> [valuation_ids]) pub asset_valuations: HashMap>, } /// ACC-Valuation接口 pub trait ACCValuation { /// 添加估值记录 fn add_valuation(&mut self, record: ValuationRecord) -> Result<(), ValuationError>; /// 获取估值记录 fn get_valuation(&self, valuation_id: &str) -> Result; /// 获取资产的最新估值 fn get_latest_valuation(&self, asset_id: &str) -> Result; /// 获取资产的估值历史 fn get_valuation_history(&self, asset_id: &str) -> Vec; /// 检查估值是否有效 fn is_valuation_valid(&self, valuation_id: &str) -> bool; /// 计算平均估值 fn calculate_average_valuation(&self, asset_id: &str, period: u64) -> Option; /// 更新估值备注 fn add_note(&mut self, valuation_id: &str, note: String) -> Result<(), ValuationError>; } /// ACC-Valuation标准实现 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ValuationToken { state: ValuationState, } impl ValuationToken { /// 创建新的估值管理器 pub fn new() -> Self { Self { state: ValuationState { valuations: HashMap::new(), asset_valuations: HashMap::new(), }, } } /// 获取状态的可变引用 pub fn state_mut(&mut self) -> &mut ValuationState { &mut self.state } /// 获取状态的不可变引用 pub fn state(&self) -> &ValuationState { &self.state } } impl Default for ValuationToken { fn default() -> Self { Self::new() } } impl ACCValuation for ValuationToken { fn add_valuation(&mut self, mut record: ValuationRecord) -> Result<(), ValuationError> { if self.state.valuations.contains_key(&record.valuation_id) { return Err(ValuationError::RecordAlreadyExists); } if record.value == 0 { return Err(ValuationError::InvalidValue); } // 如果timestamp为0,使用当前时间 if record.timestamp == 0 { record.timestamp = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); } let valuation_id = record.valuation_id.clone(); let asset_id = record.asset_id.clone(); self.state .valuations .insert(valuation_id.clone(), record); self.state .asset_valuations .entry(asset_id) .or_insert_with(Vec::new) .push(valuation_id); Ok(()) } fn get_valuation(&self, valuation_id: &str) -> Result { self.state .valuations .get(valuation_id) .cloned() .ok_or(ValuationError::RecordNotFound) } fn get_latest_valuation(&self, asset_id: &str) -> Result { let valuation_ids = self .state .asset_valuations .get(asset_id) .ok_or(ValuationError::RecordNotFound)?; if valuation_ids.is_empty() { return Err(ValuationError::RecordNotFound); } // 获取所有估值记录并按时间排序 let mut valuations: Vec = valuation_ids .iter() .filter_map(|id| self.state.valuations.get(id).cloned()) .collect(); valuations.sort_by(|a, b| b.timestamp.cmp(&a.timestamp)); valuations .into_iter() .next() .ok_or(ValuationError::RecordNotFound) } fn get_valuation_history(&self, asset_id: &str) -> Vec { self.state .asset_valuations .get(asset_id) .map(|valuation_ids| { let mut valuations: Vec = valuation_ids .iter() .filter_map(|id| self.state.valuations.get(id).cloned()) .collect(); valuations.sort_by(|a, b| b.timestamp.cmp(&a.timestamp)); valuations }) .unwrap_or_default() } fn is_valuation_valid(&self, valuation_id: &str) -> bool { if let Ok(record) = self.get_valuation(valuation_id) { let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); now <= record.timestamp + record.validity_period } else { false } } fn calculate_average_valuation(&self, asset_id: &str, period: u64) -> Option { let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); let valuations = self.get_valuation_history(asset_id); let recent_valuations: Vec<&ValuationRecord> = valuations .iter() .filter(|v| now - v.timestamp <= period) .collect(); if recent_valuations.is_empty() { return None; } let sum: u128 = recent_valuations.iter().map(|v| v.value).sum(); Some(sum / recent_valuations.len() as u128) } fn add_note(&mut self, valuation_id: &str, note: String) -> Result<(), ValuationError> { let mut record = self.get_valuation(valuation_id)?; record.notes.push(note); self.state .valuations .insert(valuation_id.to_string(), record); Ok(()) } } #[cfg(test)] mod tests { use super::*; fn create_test_valuation() -> ValuationRecord { let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); ValuationRecord { valuation_id: "VAL-001".to_string(), asset_id: "RWA-001".to_string(), method: ValuationMethod::MarketApproach, value: 1000000_00, appraiser: "appraiser1".to_string(), timestamp: now, validity_period: 31536000, // 1年 notes: Vec::new(), } } #[test] fn test_add_valuation() { let mut valuation = ValuationToken::new(); let record = create_test_valuation(); assert!(valuation.add_valuation(record).is_ok()); } #[test] fn test_get_latest_valuation() { let mut valuation = ValuationToken::new(); let record = create_test_valuation(); valuation.add_valuation(record).unwrap(); assert!(valuation.get_latest_valuation("RWA-001").is_ok()); } #[test] fn test_is_valuation_valid() { let mut valuation = ValuationToken::new(); let record = create_test_valuation(); valuation.add_valuation(record).unwrap(); assert!(valuation.is_valuation_valid("VAL-001")); } #[test] fn test_calculate_average_valuation() { let mut valuation = ValuationToken::new(); let mut record1 = create_test_valuation(); record1.valuation_id = "VAL-001".to_string(); record1.value = 1000000_00; valuation.add_valuation(record1).unwrap(); let mut record2 = create_test_valuation(); record2.valuation_id = "VAL-002".to_string(); record2.value = 1200000_00; valuation.add_valuation(record2).unwrap(); let avg = valuation.calculate_average_valuation("RWA-001", 31536000); assert!(avg.is_some()); assert_eq!(avg.unwrap(), 1100000_00); } #[test] fn test_add_note() { let mut valuation = ValuationToken::new(); let record = create_test_valuation(); valuation.add_valuation(record).unwrap(); assert!(valuation .add_note("VAL-001", "Test note".to_string()) .is_ok()); assert_eq!( valuation.get_valuation("VAL-001").unwrap().notes.len(), 1 ); } }