// ACC-RWA: 真实世界资产协议(Real World Asset Protocol) // // NAC原生的RWA资产标准,专为真实世界资产上链设计 // 100% NAC原生协议,不是任何现有标准的实现 use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// RWA资产类型 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum RWAAssetType { /// 不动产(房地产、土地) RealEstate, /// 贵金属(黄金、白银、铂金) PreciousMetal, /// 艺术品(绘画、雕塑、古董) Artwork, /// 股权(公司股权、基金份额) Equity, /// 债券(政府债券、企业债券) Bond, /// 大宗商品(石油、天然气、农产品) Commodity, /// 知识产权(专利、商标、版权) IntellectualProperty, /// 收藏品(邮票、钱币、珠宝) Collectible, /// 其他 Other(String), } /// RWA资产状态 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum RWAAssetStatus { /// 待审核 Pending, /// 已激活 Active, /// 已冻结 Frozen, /// 已注销 Deactivated, } /// RWA资产信息 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RWAAssetInfo { /// 资产ID pub asset_id: String, /// 资产类型 pub asset_type: RWAAssetType, /// 资产名称 pub name: String, /// 资产描述 pub description: String, /// 资产DNA(NAC原生,简化为String) pub asset_dna: String, /// GNACS分类编码(NAC原生) pub gnacs_code: String, /// 所有者地址 pub owner: String, /// 估值(USD,以分为单位) pub valuation_usd: u128, /// 资产状态 pub status: RWAAssetStatus, /// 物理位置 pub physical_location: Option, /// 法律文件哈希列表(简化为String列表) pub legal_documents: Vec, /// 创建时间(Unix时间戳) pub created_at: u64, /// 更新时间(Unix时间戳) pub updated_at: u64, /// 最后审计时间 pub last_audited_at: Option, } /// RWA资产错误类型 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum RWAError { /// 资产不存在 AssetNotFound, /// 资产已存在 AssetAlreadyExists, /// 无效的所有者 InvalidOwner, /// 资产已冻结 AssetFrozen, /// 未授权操作 Unauthorized, /// 无效的资产DNA InvalidAssetDNA, /// 无效的GNACS编码 InvalidGNACSCode, /// 估值过期 ValuationExpired, /// 法律文件缺失 MissingLegalDocuments, } /// RWA资产状态 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RWAState { /// 资产映射 (asset_id -> RWAAssetInfo) pub assets: HashMap, /// 所有者资产列表 (owner -> [asset_ids]) pub owner_assets: HashMap>, /// 资产DNA索引 (dna_hash -> asset_id) pub dna_index: HashMap, /// GNACS索引 (gnacs_code -> [asset_ids]) pub gnacs_index: HashMap>, } /// ACC-RWA接口 pub trait ACCRwa { /// 注册RWA资产 fn register_asset(&mut self, asset_info: RWAAssetInfo) -> Result<(), RWAError>; /// 获取RWA资产信息 fn get_asset(&self, asset_id: &str) -> Result; /// 更新资产估值 fn update_valuation(&mut self, asset_id: &str, new_valuation: u128) -> Result<(), RWAError>; /// 转移资产所有权 fn transfer_ownership(&mut self, asset_id: &str, new_owner: String) -> Result<(), RWAError>; /// 冻结资产 fn freeze_asset(&mut self, asset_id: &str) -> Result<(), RWAError>; /// 解冻资产 fn unfreeze_asset(&mut self, asset_id: &str) -> Result<(), RWAError>; /// 注销资产 fn deactivate_asset(&mut self, asset_id: &str) -> Result<(), RWAError>; /// 添加法律文件 fn add_legal_document(&mut self, asset_id: &str, document_hash: String) -> Result<(), RWAError>; /// 获取所有者的资产列表 fn get_owner_assets(&self, owner: &str) -> Vec; /// 按GNACS编码查询资产 fn get_assets_by_gnacs(&self, gnacs_code: &str) -> Vec; /// 按资产类型查询资产 fn get_assets_by_type(&self, asset_type: RWAAssetType) -> Vec; /// 更新审计时间 fn update_audit_time(&mut self, asset_id: &str) -> Result<(), RWAError>; } /// ACC-RWA标准实现 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RwaToken { state: RWAState, } impl RwaToken { /// 创建新的RWA资产管理器 pub fn new() -> Self { Self { state: RWAState { assets: HashMap::new(), owner_assets: HashMap::new(), dna_index: HashMap::new(), gnacs_index: HashMap::new(), }, } } /// 获取状态的可变引用 pub fn state_mut(&mut self) -> &mut RWAState { &mut self.state } /// 获取状态的不可变引用 pub fn state(&self) -> &RWAState { &self.state } /// 生成资产DNA(简化实现) fn generate_asset_dna(&self, asset_id: &str) -> String { format!("DNA-{}", asset_id) } /// 验证资产DNA fn validate_asset_dna(&self, dna: &str) -> bool { dna.starts_with("DNA-") && dna.len() > 4 } /// 验证GNACS编码 fn validate_gnacs_code(&self, code: &str) -> bool { // 简化验证:检查格式(应为NAC-XXXX-XXXX格式) code.starts_with("NAC-") && code.len() >= 8 } } impl Default for RwaToken { fn default() -> Self { Self::new() } } impl ACCRwa for RwaToken { fn register_asset(&mut self, mut asset_info: RWAAssetInfo) -> Result<(), RWAError> { // 检查资产是否已存在 if self.state.assets.contains_key(&asset_info.asset_id) { return Err(RWAError::AssetAlreadyExists); } // 验证GNACS编码 if !self.validate_gnacs_code(&asset_info.gnacs_code) { return Err(RWAError::InvalidGNACSCode); } // 生成资产DNA if asset_info.asset_dna.is_empty() { asset_info.asset_dna = self.generate_asset_dna(&asset_info.asset_id); } // 验证资产DNA if !self.validate_asset_dna(&asset_info.asset_dna) { return Err(RWAError::InvalidAssetDNA); } let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); asset_info.created_at = now; asset_info.updated_at = now; asset_info.status = RWAAssetStatus::Active; let asset_id = asset_info.asset_id.clone(); let owner = asset_info.owner.clone(); let dna = asset_info.asset_dna.clone(); let gnacs_code = asset_info.gnacs_code.clone(); // 保存资产信息 self.state.assets.insert(asset_id.clone(), asset_info); // 更新所有者资产列表 self.state .owner_assets .entry(owner) .or_insert_with(Vec::new) .push(asset_id.clone()); // 更新DNA索引 self.state.dna_index.insert(dna, asset_id.clone()); // 更新GNACS索引 self.state .gnacs_index .entry(gnacs_code) .or_insert_with(Vec::new) .push(asset_id); Ok(()) } fn get_asset(&self, asset_id: &str) -> Result { self.state .assets .get(asset_id) .cloned() .ok_or(RWAError::AssetNotFound) } fn update_valuation(&mut self, asset_id: &str, new_valuation: u128) -> Result<(), RWAError> { let mut asset = self.get_asset(asset_id)?; if asset.status == RWAAssetStatus::Frozen { return Err(RWAError::AssetFrozen); } let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); asset.valuation_usd = new_valuation; asset.updated_at = now; self.state.assets.insert(asset_id.to_string(), asset); Ok(()) } fn transfer_ownership(&mut self, asset_id: &str, new_owner: String) -> Result<(), RWAError> { let mut asset = self.get_asset(asset_id)?; if asset.status == RWAAssetStatus::Frozen { return Err(RWAError::AssetFrozen); } let old_owner = asset.owner.clone(); asset.owner = new_owner.clone(); let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); asset.updated_at = now; // 更新所有者资产列表 if let Some(assets) = self.state.owner_assets.get_mut(&old_owner) { assets.retain(|id| id != asset_id); } self.state .owner_assets .entry(new_owner) .or_insert_with(Vec::new) .push(asset_id.to_string()); self.state.assets.insert(asset_id.to_string(), asset); Ok(()) } fn freeze_asset(&mut self, asset_id: &str) -> Result<(), RWAError> { let mut asset = self.get_asset(asset_id)?; let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); asset.status = RWAAssetStatus::Frozen; asset.updated_at = now; self.state.assets.insert(asset_id.to_string(), asset); Ok(()) } fn unfreeze_asset(&mut self, asset_id: &str) -> Result<(), RWAError> { let mut asset = self.get_asset(asset_id)?; let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); asset.status = RWAAssetStatus::Active; asset.updated_at = now; self.state.assets.insert(asset_id.to_string(), asset); Ok(()) } fn deactivate_asset(&mut self, asset_id: &str) -> Result<(), RWAError> { let mut asset = self.get_asset(asset_id)?; let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); asset.status = RWAAssetStatus::Deactivated; asset.updated_at = now; self.state.assets.insert(asset_id.to_string(), asset); Ok(()) } fn add_legal_document(&mut self, asset_id: &str, document_hash: String) -> Result<(), RWAError> { let mut asset = self.get_asset(asset_id)?; let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); asset.legal_documents.push(document_hash); asset.updated_at = now; self.state.assets.insert(asset_id.to_string(), asset); Ok(()) } fn get_owner_assets(&self, owner: &str) -> Vec { self.state .owner_assets .get(owner) .map(|asset_ids| { asset_ids .iter() .filter_map(|id| self.state.assets.get(id).cloned()) .collect() }) .unwrap_or_default() } fn get_assets_by_gnacs(&self, gnacs_code: &str) -> Vec { self.state .gnacs_index .get(gnacs_code) .map(|asset_ids| { asset_ids .iter() .filter_map(|id| self.state.assets.get(id).cloned()) .collect() }) .unwrap_or_default() } fn get_assets_by_type(&self, asset_type: RWAAssetType) -> Vec { self.state .assets .values() .filter(|asset| asset.asset_type == asset_type) .cloned() .collect() } fn update_audit_time(&mut self, asset_id: &str) -> Result<(), RWAError> { let mut asset = self.get_asset(asset_id)?; let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(); asset.last_audited_at = Some(now); asset.updated_at = now; self.state.assets.insert(asset_id.to_string(), asset); Ok(()) } } #[cfg(test)] mod tests { use super::*; fn create_test_asset() -> RWAAssetInfo { RWAAssetInfo { asset_id: "RWA-001".to_string(), asset_type: RWAAssetType::RealEstate, name: "Test Property".to_string(), description: "A test real estate asset".to_string(), asset_dna: String::new(), gnacs_code: "NAC-RE-001".to_string(), owner: "alice".to_string(), valuation_usd: 1000000_00, status: RWAAssetStatus::Pending, physical_location: Some("123 Main St".to_string()), legal_documents: vec!["doc1".to_string()], created_at: 0, updated_at: 0, last_audited_at: None, } } #[test] fn test_register_asset() { let mut rwa = RwaToken::new(); let asset = create_test_asset(); assert!(rwa.register_asset(asset).is_ok()); } #[test] fn test_update_valuation() { let mut rwa = RwaToken::new(); let asset = create_test_asset(); rwa.register_asset(asset).unwrap(); assert!(rwa.update_valuation("RWA-001", 1200000_00).is_ok()); assert_eq!(rwa.get_asset("RWA-001").unwrap().valuation_usd, 1200000_00); } #[test] fn test_transfer_ownership() { let mut rwa = RwaToken::new(); let asset = create_test_asset(); rwa.register_asset(asset).unwrap(); assert!(rwa.transfer_ownership("RWA-001", "bob".to_string()).is_ok()); assert_eq!(rwa.get_asset("RWA-001").unwrap().owner, "bob"); } #[test] fn test_freeze_unfreeze_asset() { let mut rwa = RwaToken::new(); let asset = create_test_asset(); rwa.register_asset(asset).unwrap(); assert!(rwa.freeze_asset("RWA-001").is_ok()); assert_eq!(rwa.get_asset("RWA-001").unwrap().status, RWAAssetStatus::Frozen); assert!(rwa.unfreeze_asset("RWA-001").is_ok()); assert_eq!(rwa.get_asset("RWA-001").unwrap().status, RWAAssetStatus::Active); } #[test] fn test_add_legal_document() { let mut rwa = RwaToken::new(); let asset = create_test_asset(); rwa.register_asset(asset).unwrap(); assert!(rwa.add_legal_document("RWA-001", "doc2".to_string()).is_ok()); assert_eq!(rwa.get_asset("RWA-001").unwrap().legal_documents.len(), 2); } #[test] fn test_get_owner_assets() { let mut rwa = RwaToken::new(); let asset = create_test_asset(); rwa.register_asset(asset).unwrap(); let assets = rwa.get_owner_assets("alice"); assert_eq!(assets.len(), 1); } #[test] fn test_get_assets_by_gnacs() { let mut rwa = RwaToken::new(); let asset = create_test_asset(); rwa.register_asset(asset).unwrap(); let assets = rwa.get_assets_by_gnacs("NAC-RE-001"); assert_eq!(assets.len(), 1); } }