//! NAC ACC-1594 Protocol Implementation //! NAC ACC-1594协议实现 - 基于GNACS数字基因的核心收益与资产操作协议 //! //! ACC-1594在继承ACC-1400的基础上,增加了: //! 1. 资产生命周期操作(发行、赎回) //! 2. 收益分配系统(分红、领取) //! 3. GNACS收益扩展编码(80位) //! 4. 宪法收据强制验证 //! 5. AI驱动的收益计算 pub mod error; pub mod types; pub use error::{Acc1594Error, Result}; pub use types::*; use nac_acc_1400::Acc1400; use nac_acc_1410::Acc1410; use std::collections::HashMap; /// ACC-1594核心收益与资产操作协议 #[derive(Debug)] pub struct Acc1594 { /// 基础ACC-1400实例 #[allow(dead_code)] base: Acc1400, /// ACC-1410实例(用于访问底层方法) base1410: Acc1410, /// 资产GNACS(含收益扩展) asset_gnacs: FullDividendGNACS, /// 是否可发行 is_issuable: bool, /// 发行上限 issuance_limit: Option, /// 发行记录 issuance_records: Vec, /// 赎回记录 redemption_records: Vec, /// 分红记录(按分区) dividend_records: HashMap>, /// 可领取分红(账户 -> 分区 -> 金额) claimable_dividends: HashMap>, /// 账户持有开始时间(用于检查最低持有期) holding_start_time: HashMap, /// 授权角色(角色名 -> 地址列表) authorized_roles: HashMap>, } impl Acc1594 { /// 创建新的ACC-1594实例 pub fn new(asset_gnacs: FullDividendGNACS) -> Self { Self { base: Acc1400::new(), base1410: Acc1410::new(), asset_gnacs, is_issuable: true, issuance_limit: None, issuance_records: Vec::new(), redemption_records: Vec::new(), dividend_records: HashMap::new(), claimable_dividends: HashMap::new(), holding_start_time: HashMap::new(), authorized_roles: HashMap::new(), } } /// 设置发行上限 pub fn set_issuance_limit(&mut self, limit: u64) { self.issuance_limit = Some(limit); } /// 设置是否可发行 pub fn set_issuable(&mut self, issuable: bool) { self.is_issuable = issuable; } /// 授权角色 pub fn authorize_role(&mut self, role: &str, address: &str) { self.authorized_roles .entry(role.to_string()) .or_insert_with(Vec::new) .push(address.to_string()); } /// 检查角色权限 pub fn has_role(&self, role: &str, address: &str) -> bool { self.authorized_roles .get(role) .map(|addresses| addresses.contains(&address.to_string())) .unwrap_or(false) } // ==================== 资产生命周期操作 ==================== /// 发行新资产(增加总供应量) pub fn issue( &mut self, operator: &str, to: &str, amount: u64, data: Vec, partition_id: &[u8; 32], receipt_hash: [u8; 32], ) -> Result<()> { // 检查权限 if !self.has_role("ISSUER", operator) { return Err(Acc1594Error::Unauthorized { operator: operator.to_string(), required_role: "ISSUER".to_string(), }); } // 检查是否可发行 if !self.is_issuable { return Err(Acc1594Error::NotIssuable("Asset is not issuable".to_string())); } // 检查发行上限 if let Some(limit) = self.issuance_limit { let current_supply = self.total_supply(partition_id)?; if current_supply + amount > limit { return Err(Acc1594Error::ExceedsIssuanceLimit { current: current_supply + amount, limit, }); } } // 发行到分区 self.base1410.issue_to_partition(partition_id, to, amount)?; // 记录持有开始时间 if !self.holding_start_time.contains_key(to) { self.holding_start_time.insert(to.to_string(), Self::current_timestamp()); } // 记录发行 self.issuance_records.push(IssuanceRecord { operator: operator.to_string(), to: to.to_string(), amount, data, timestamp: Self::current_timestamp(), receipt_hash, }); Ok(()) } /// 赎回资产(销毁) pub fn redeem( &mut self, account: &str, amount: u64, data: Vec, partition_id: &[u8; 32], receipt_hash: [u8; 32], ) -> Result<()> { // 检查赎回策略 let policy = RedemptionPolicy::from(self.asset_gnacs.dividend_extension.redemption_policy); if policy == RedemptionPolicy::NonRedeemable { return Err(Acc1594Error::RedemptionNotAllowed( "Asset is non-redeemable".to_string(), )); } // 检查最低持有期 self.check_min_holding_period(account)?; // 从分区销毁 self.base1410.burn_from_partition(partition_id, account, amount)?; // 记录赎回 self.redemption_records.push(RedemptionRecord { operator: account.to_string(), from: account.to_string(), amount, data, timestamp: Self::current_timestamp(), receipt_hash, }); Ok(()) } /// 操作员代表持有者赎回 pub fn operator_redeem( &mut self, operator: &str, token_holder: &str, amount: u64, data: Vec, partition_id: &[u8; 32], receipt_hash: [u8; 32], ) -> Result<()> { // 检查操作员权限 if !self.base1410.is_operator_for(token_holder, operator) { return Err(Acc1594Error::Unauthorized { operator: operator.to_string(), required_role: "OPERATOR".to_string(), }); } // 检查赎回策略 let policy = RedemptionPolicy::from(self.asset_gnacs.dividend_extension.redemption_policy); if policy == RedemptionPolicy::NonRedeemable { return Err(Acc1594Error::RedemptionNotAllowed( "Asset is non-redeemable".to_string(), )); } // 检查最低持有期 self.check_min_holding_period(token_holder)?; // 从分区销毁 self.base1410.burn_from_partition(partition_id, token_holder, amount)?; // 记录赎回 self.redemption_records.push(RedemptionRecord { operator: operator.to_string(), from: token_holder.to_string(), amount, data, timestamp: Self::current_timestamp(), receipt_hash, }); Ok(()) } /// 检查资产是否可发行 pub fn is_issuable(&self) -> bool { self.is_issuable } // ==================== 收益分配 ==================== /// 分配收益(由宪法执行引擎自动触发,或授权角色手动触发) pub fn distribute_dividend( &mut self, operator: &str, partition_id: &[u8; 32], total_amount: u64, period: u64, receipt_hash: [u8; 32], ) -> Result<()> { // 检查权限 if !self.has_role("DISTRIBUTOR", operator) { return Err(Acc1594Error::Unauthorized { operator: operator.to_string(), required_role: "DISTRIBUTOR".to_string(), }); } // 获取分区总供应量 let total_supply = self.total_supply(partition_id)?; if total_supply == 0 { return Ok(()); } // 获取所有持有者并分配 let partition_id_hex = hex::encode(partition_id); let holders = self.get_all_holders(partition_id)?; for account in holders { let balance = self.base1410.balance_of_by_partition(partition_id, &account)?; // 修复:先乘后除避免整数除法精度损失 let dividend = (balance * total_amount) / total_supply; self.claimable_dividends .entry(account.clone()) .or_insert_with(HashMap::new) .entry(partition_id_hex.clone()) .and_modify(|e| *e += dividend) .or_insert(dividend); } // 记录分红 let per_share_amount = if total_supply > 0 { total_amount / total_supply } else { 0 }; let record = DividendRecord { period, total_amount, per_share_amount, timestamp: Self::current_timestamp(), receipt_hash, }; self.dividend_records .entry(partition_id_hex) .or_insert_with(Vec::new) .push(record); Ok(()) } /// 查询账户可领取的收益(分区级) pub fn claimable_dividend(&self, account: &str, partition_id: &[u8; 32]) -> u64 { let partition_id_hex = hex::encode(partition_id); self.claimable_dividends .get(account) .and_then(|partitions| partitions.get(&partition_id_hex)) .copied() .unwrap_or(0) } /// 领取收益(自动转入账户XTZH余额) pub fn claim_dividend( &mut self, account: &str, partition_id: &[u8; 32], _receipt_hash: [u8; 32], ) -> Result { let partition_id_hex = hex::encode(partition_id); let amount = self.claimable_dividend(account, partition_id); if amount == 0 { return Err(Acc1594Error::NoClaimableDividend { account: account.to_string(), partition: partition_id_hex, }); } // 清除可领取分红 if let Some(partitions) = self.claimable_dividends.get_mut(account) { partitions.remove(&partition_id_hex); } Ok(amount) } /// 批量领取收益(多个分区) pub fn claim_multiple_dividends( &mut self, account: &str, partition_ids: &[[u8; 32]], receipt_hash: [u8; 32], ) -> Result { let mut total = 0; for partition_id in partition_ids { if let Ok(amount) = self.claim_dividend(account, partition_id, receipt_hash) { total += amount; } } Ok(total) } /// 获取历史分红记录 pub fn get_dividend_history( &self, partition_id: &[u8; 32], from: u64, to: u64, ) -> Vec { let partition_id_hex = hex::encode(partition_id); self.dividend_records .get(&partition_id_hex) .map(|records| { records .iter() .filter(|r| r.period >= from && r.period <= to) .cloned() .collect() }) .unwrap_or_default() } // ==================== 资产状态查询 ==================== /// 获取资产GNACS(含收益扩展) pub fn asset_gnacs(&self) -> &FullDividendGNACS { &self.asset_gnacs } /// 获取资产总供应量 pub fn total_supply(&self, partition_id: &[u8; 32]) -> Result { // 简化实现:返回分区信息中的总供应量 let info = self.base1410.get_partition_info(partition_id)?; Ok(info.total_supply) } /// 获取账户余额(指定分区) pub fn balance_of(&self, account: &str, partition_id: &[u8; 32]) -> Result { Ok(self.base1410.balance_of_by_partition(partition_id, account)?) } /// 获取资产净值(由AI估值引擎提供) pub fn net_asset_value(&self) -> (u64, u64) { // 简化实现:返回模拟的净值和时间戳 (1000000, Self::current_timestamp()) } // ==================== 辅助方法 ==================== /// 检查最低持有期 fn check_min_holding_period(&self, account: &str) -> Result<()> { let min_period = self.asset_gnacs.dividend_extension.min_holding_period; if min_period == 0 { return Ok(()); } if let Some(&start_time) = self.holding_start_time.get(account) { let current_time = Self::current_timestamp(); let held_seconds = current_time - start_time; let held_months = (held_seconds / (30 * 24 * 3600)) as u8; if held_months < min_period { return Err(Acc1594Error::MinHoldingPeriodNotMet { required_months: min_period, held_months, }); } } Ok(()) } /// 获取分区的所有持有者 fn get_all_holders(&self, partition_id: &[u8; 32]) -> Result> { // 从持有开始时间记录中获取所有账户,筛选出在该分区有余额的账户 let mut holders = Vec::new(); for account in self.holding_start_time.keys() { if let Ok(balance) = self.base1410.balance_of_by_partition(partition_id, account) { if balance > 0 { holders.push(account.clone()); } } } Ok(holders) } /// 获取当前时间戳 fn current_timestamp() -> u64 { std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs() } } #[cfg(test)] mod tests { use super::*; use nac_acc_1410::{ExtendedGNACS, GNACSExtension, PartitionType}; fn create_test_acc1594() -> (Acc1594, [u8; 32]) { let dividend_gnacs = FullDividendGNACS { base_gnacs: vec![0x94, 0x01, 0x00, 0x04, 0x02, 0x01], dividend_extension: DividendGNACSExtension { dividend_policy: 1, // 固定比例 dividend_period: 4, // 年度 dividend_rate: 5, // 5% redemption_policy: 1, // 按面值赎回 min_holding_period: 0, // 无最低持有期 }, }; let mut acc1594 = Acc1594::new(dividend_gnacs); // 授权角色 acc1594.authorize_role("ISSUER", "issuer1"); acc1594.authorize_role("DISTRIBUTOR", "distributor1"); // 创建分区 let extended_gnacs = ExtendedGNACS { base_gnacs: vec![0x94, 0x01, 0x00, 0x04, 0x02, 0x01], extension: GNACSExtension { partition_type: 0x01, vesting_years: 0, voting_multiplier: 1, dividend_priority: 1, }, }; let partition_id = acc1594 .base1410 .create_partition( "Test Partition".to_string(), extended_gnacs, PartitionType::CommonStock, ) .unwrap(); (acc1594, partition_id) } #[test] fn test_issue() { let (mut acc1594, partition_id) = create_test_acc1594(); let result = acc1594.issue( "issuer1", "investor1", 1000, vec![], &partition_id, [0u8; 32], ); assert!(result.is_ok()); assert_eq!(acc1594.balance_of("investor1", &partition_id).unwrap(), 1000); } #[test] fn test_redeem() { let (mut acc1594, partition_id) = create_test_acc1594(); acc1594 .issue("issuer1", "investor1", 1000, vec![], &partition_id, [0u8; 32]) .unwrap(); let result = acc1594.redeem("investor1", 300, vec![], &partition_id, [0u8; 32]); assert!(result.is_ok()); assert_eq!(acc1594.balance_of("investor1", &partition_id).unwrap(), 700); } #[test] fn test_distribute_dividend() { let (mut acc1594, partition_id) = create_test_acc1594(); // 发行给两个投资者 acc1594 .issue("issuer1", "investor1", 600, vec![], &partition_id, [0u8; 32]) .unwrap(); acc1594 .issue("issuer1", "investor2", 400, vec![], &partition_id, [0u8; 32]) .unwrap(); // 分配分红 let result = acc1594.distribute_dividend( "distributor1", &partition_id, 1000, 202601, [0u8; 32], ); assert!(result.is_ok()); // 检查可领取分红 assert_eq!(acc1594.claimable_dividend("investor1", &partition_id), 600); assert_eq!(acc1594.claimable_dividend("investor2", &partition_id), 400); } #[test] fn test_claim_dividend() { let (mut acc1594, partition_id) = create_test_acc1594(); acc1594 .issue("issuer1", "investor1", 1000, vec![], &partition_id, [0u8; 32]) .unwrap(); acc1594 .distribute_dividend("distributor1", &partition_id, 500, 202601, [0u8; 32]) .unwrap(); let claimed = acc1594 .claim_dividend("investor1", &partition_id, [0u8; 32]) .unwrap(); assert_eq!(claimed, 500); assert_eq!(acc1594.claimable_dividend("investor1", &partition_id), 0); } #[test] fn test_issuance_limit() { let (mut acc1594, partition_id) = create_test_acc1594(); acc1594.set_issuance_limit(1000); // 第一次发行应该成功 assert!(acc1594 .issue("issuer1", "investor1", 500, vec![], &partition_id, [0u8; 32]) .is_ok()); // 第二次发行超过限额应该失败 let result = acc1594.issue("issuer1", "investor2", 600, vec![], &partition_id, [0u8; 32]); assert!(result.is_err()); } }