// ACC-1155: 多类型资产协议(Multi-Token Protocol) // // NAC原生的多类型资产标准,专为RWA资产设计 // 不是ERC-1155的实现,是完全独立的NAC原生协议 use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// ACC-1155错误类型 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum ACC1155Error { /// 余额不足 InsufficientBalance, /// 无效的接收地址 InvalidRecipient, /// 无效的金额 InvalidAmount, /// 资产类型不存在 TokenTypeNotFound, /// 未授权操作 Unauthorized, } /// ACC-1155资产状态 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ACC1155State { /// 账户余额映射 (account -> token_id -> balance) pub balances: HashMap>, /// 操作员授权映射 (owner -> operator -> bool) pub operator_approvals: HashMap>, /// 资产URI映射 (token_id -> uri) pub token_uris: HashMap, } /// ACC-1155接口 pub trait ACC1155 { /// 获取账户指定资产类型的余额 fn balance_of(&self, account: &str, token_id: &str) -> u128; /// 批量获取余额 fn balance_of_batch(&self, accounts: &[String], token_ids: &[String]) -> Vec; /// 转移资产 fn safe_transfer_from( &mut self, from: &str, to: &str, token_id: &str, amount: u128, ) -> Result<(), ACC1155Error>; /// 批量转移资产 fn safe_batch_transfer_from( &mut self, from: &str, to: &str, token_ids: &[String], amounts: &[u128], ) -> Result<(), ACC1155Error>; /// 设置操作员授权 fn set_approval_for_all( &mut self, owner: &str, operator: &str, approved: bool, ) -> Result<(), ACC1155Error>; /// 检查操作员授权 fn is_approved_for_all(&self, owner: &str, operator: &str) -> bool; /// 铸造资产 fn mint(&mut self, to: &str, token_id: &str, amount: u128) -> Result<(), ACC1155Error>; /// 批量铸造资产 fn mint_batch( &mut self, to: &str, token_ids: &[String], amounts: &[u128], ) -> Result<(), ACC1155Error>; /// 销毁资产 fn burn(&mut self, from: &str, token_id: &str, amount: u128) -> Result<(), ACC1155Error>; /// 获取资产URI fn uri(&self, token_id: &str) -> Option; } /// ACC-1155标准实现 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ACC1155Token { state: ACC1155State, } impl ACC1155Token { /// 创建新的ACC-1155资产集合 pub fn new() -> Self { Self { state: ACC1155State { balances: HashMap::new(), operator_approvals: HashMap::new(), token_uris: HashMap::new(), }, } } /// 获取状态的可变引用 pub fn state_mut(&mut self) -> &mut ACC1155State { &mut self.state } /// 获取状态的不可变引用 pub fn state(&self) -> &ACC1155State { &self.state } } impl Default for ACC1155Token { fn default() -> Self { Self::new() } } impl ACC1155 for ACC1155Token { fn balance_of(&self, account: &str, token_id: &str) -> u128 { self.state .balances .get(account) .and_then(|tokens| tokens.get(token_id)) .copied() .unwrap_or(0) } fn balance_of_batch(&self, accounts: &[String], token_ids: &[String]) -> Vec { accounts .iter() .zip(token_ids.iter()) .map(|(account, token_id)| self.balance_of(account, token_id)) .collect() } fn safe_transfer_from( &mut self, from: &str, to: &str, token_id: &str, amount: u128, ) -> Result<(), ACC1155Error> { if amount == 0 { return Err(ACC1155Error::InvalidAmount); } let from_balance = self.balance_of(from, token_id); if from_balance < amount { return Err(ACC1155Error::InsufficientBalance); } // 更新发送方余额 self.state .balances .entry(from.to_string()) .or_insert_with(HashMap::new) .insert(token_id.to_string(), from_balance - amount); // 更新接收方余额 let to_balance = self.balance_of(to, token_id); self.state .balances .entry(to.to_string()) .or_insert_with(HashMap::new) .insert(token_id.to_string(), to_balance + amount); Ok(()) } fn safe_batch_transfer_from( &mut self, from: &str, to: &str, token_ids: &[String], amounts: &[u128], ) -> Result<(), ACC1155Error> { if token_ids.len() != amounts.len() { return Err(ACC1155Error::InvalidAmount); } for (token_id, &amount) in token_ids.iter().zip(amounts.iter()) { self.safe_transfer_from(from, to, token_id, amount)?; } Ok(()) } fn set_approval_for_all( &mut self, owner: &str, operator: &str, approved: bool, ) -> Result<(), ACC1155Error> { self.state .operator_approvals .entry(owner.to_string()) .or_insert_with(HashMap::new) .insert(operator.to_string(), approved); Ok(()) } fn is_approved_for_all(&self, owner: &str, operator: &str) -> bool { self.state .operator_approvals .get(owner) .and_then(|approvals| approvals.get(operator)) .copied() .unwrap_or(false) } fn mint(&mut self, to: &str, token_id: &str, amount: u128) -> Result<(), ACC1155Error> { let to_balance = self.balance_of(to, token_id); self.state .balances .entry(to.to_string()) .or_insert_with(HashMap::new) .insert(token_id.to_string(), to_balance + amount); Ok(()) } fn mint_batch( &mut self, to: &str, token_ids: &[String], amounts: &[u128], ) -> Result<(), ACC1155Error> { if token_ids.len() != amounts.len() { return Err(ACC1155Error::InvalidAmount); } for (token_id, &amount) in token_ids.iter().zip(amounts.iter()) { self.mint(to, token_id, amount)?; } Ok(()) } fn burn(&mut self, from: &str, token_id: &str, amount: u128) -> Result<(), ACC1155Error> { let from_balance = self.balance_of(from, token_id); if from_balance < amount { return Err(ACC1155Error::InsufficientBalance); } self.state .balances .entry(from.to_string()) .or_insert_with(HashMap::new) .insert(token_id.to_string(), from_balance - amount); Ok(()) } fn uri(&self, token_id: &str) -> Option { self.state.token_uris.get(token_id).cloned() } } #[cfg(test)] mod tests { use super::*; #[test] fn test_mint_and_balance() { let mut token = ACC1155Token::new(); assert!(token.mint("alice", "1", 1000).is_ok()); assert_eq!(token.balance_of("alice", "1"), 1000); } #[test] fn test_transfer() { let mut token = ACC1155Token::new(); token.mint("alice", "1", 1000).unwrap(); assert!(token.safe_transfer_from("alice", "bob", "1", 500).is_ok()); assert_eq!(token.balance_of("alice", "1"), 500); assert_eq!(token.balance_of("bob", "1"), 500); } #[test] fn test_batch_transfer() { let mut token = ACC1155Token::new(); token.mint("alice", "1", 1000).unwrap(); token.mint("alice", "2", 2000).unwrap(); let token_ids = vec!["1".to_string(), "2".to_string()]; let amounts = vec![500, 1000]; assert!(token .safe_batch_transfer_from("alice", "bob", &token_ids, &amounts) .is_ok()); assert_eq!(token.balance_of("alice", "1"), 500); assert_eq!(token.balance_of("alice", "2"), 1000); assert_eq!(token.balance_of("bob", "1"), 500); assert_eq!(token.balance_of("bob", "2"), 1000); } #[test] fn test_burn() { let mut token = ACC1155Token::new(); token.mint("alice", "1", 1000).unwrap(); assert!(token.burn("alice", "1", 500).is_ok()); assert_eq!(token.balance_of("alice", "1"), 500); } #[test] fn test_approval() { let mut token = ACC1155Token::new(); assert!(token .set_approval_for_all("alice", "bob", true) .is_ok()); assert!(token.is_approved_for_all("alice", "bob")); assert!(token .set_approval_for_all("alice", "bob", false) .is_ok()); assert!(!token.is_approved_for_all("alice", "bob")); } }