453 lines
13 KiB
Rust
453 lines
13 KiB
Rust
//! NAC ACC-1410 Protocol Implementation
|
||
//! NAC ACC-1410协议实现 - 部分同质化资产协议
|
||
//!
|
||
//! ACC-1410扩展了ACC-20基础协议,增加了分区(Partition)功能,
|
||
//! 允许同一资产类别内的代币被分为不同的分区,每个分区可以有不同的属性和限制。
|
||
//!
|
||
//! # 核心功能
|
||
//!
|
||
//! - **分区管理**: 创建、关闭、查询分区
|
||
//! - **分区余额**: 查询账户在特定分区的余额
|
||
//! - **分区转账**: 在分区间转移代币
|
||
//! - **操作员授权**: 授权第三方操作员代理转账
|
||
//! - **GNACS扩展**: 64位扩展编码,包含分区类型、锁定期、投票权等信息
|
||
//!
|
||
//! # 示例
|
||
//!
|
||
//! ```rust
|
||
//! use nac_acc_1410::*;
|
||
//!
|
||
//! // 创建ACC-1410实例
|
||
//! let mut acc1410 = Acc1410::new();
|
||
//!
|
||
//! // 创建分区
|
||
//! 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 = acc1410.create_partition(
|
||
//! "Common Stock".to_string(),
|
||
//! extended_gnacs,
|
||
//! PartitionType::CommonStock,
|
||
//! ).unwrap();
|
||
//!
|
||
//! // 发行代币到分区
|
||
//! acc1410.issue_to_partition(&partition_id, "user1", 1000).unwrap();
|
||
//!
|
||
//! // 分区间转账
|
||
//! acc1410.transfer_by_partition("user1", "user2", 300, &partition_id).unwrap();
|
||
//! ```
|
||
|
||
pub mod error;
|
||
pub mod partition;
|
||
pub mod transfer;
|
||
pub mod types;
|
||
pub mod cross_partition_transfer;
|
||
pub mod batch_operations;
|
||
pub mod events;
|
||
pub mod optimization;
|
||
|
||
pub use error::{Acc1410Error, Result};
|
||
pub use partition::PartitionManager;
|
||
pub use transfer::{OperatorManager, TransferManager};
|
||
pub use types::{
|
||
ExtendedGNACS, GNACSExtension, Partition, PartitionInfo, PartitionType, TransferResult,
|
||
TransferStatus,
|
||
};
|
||
|
||
/// ACC-1410协议主结构
|
||
#[derive(Debug)]
|
||
pub struct Acc1410 {
|
||
transfer_manager: TransferManager,
|
||
}
|
||
|
||
impl Acc1410 {
|
||
/// 创建新的ACC-1410实例
|
||
pub fn new() -> Self {
|
||
let partition_manager = PartitionManager::new();
|
||
let transfer_manager = TransferManager::new(partition_manager);
|
||
Self { transfer_manager }
|
||
}
|
||
|
||
// ==================== 分区管理 ====================
|
||
|
||
/// 创建新分区
|
||
pub fn create_partition(
|
||
&mut self,
|
||
name: String,
|
||
extended_gnacs: ExtendedGNACS,
|
||
partition_type: PartitionType,
|
||
) -> Result<[u8; 32]> {
|
||
self.transfer_manager
|
||
.partition_manager_mut()
|
||
.create_partition(name, extended_gnacs, partition_type)
|
||
}
|
||
|
||
/// 关闭分区
|
||
pub fn close_partition(&mut self, partition_id: &[u8; 32]) -> Result<()> {
|
||
self.transfer_manager
|
||
.partition_manager_mut()
|
||
.close_partition(partition_id)
|
||
}
|
||
|
||
/// 获取分区信息
|
||
pub fn get_partition_info(&self, partition_id: &[u8; 32]) -> Result<PartitionInfo> {
|
||
self.transfer_manager
|
||
.partition_manager()
|
||
.get_partition_info(partition_id)
|
||
}
|
||
|
||
/// 获取所有分区ID
|
||
pub fn get_all_partition_ids(&self) -> Vec<[u8; 32]> {
|
||
self.transfer_manager
|
||
.partition_manager()
|
||
.get_all_partition_ids()
|
||
}
|
||
|
||
// ==================== 余额查询 ====================
|
||
|
||
/// 获取账户在指定分区的余额
|
||
pub fn balance_of_by_partition(
|
||
&self,
|
||
partition_id: &[u8; 32],
|
||
account: &str,
|
||
) -> Result<u64> {
|
||
self.transfer_manager
|
||
.partition_manager()
|
||
.balance_of_by_partition(partition_id, account)
|
||
}
|
||
|
||
/// 获取账户拥有的所有分区
|
||
pub fn partitions_of(&self, account: &str) -> Vec<[u8; 32]> {
|
||
self.transfer_manager
|
||
.partition_manager()
|
||
.partitions_of(account)
|
||
}
|
||
|
||
// ==================== 代币发行 ====================
|
||
|
||
/// 向指定分区发行代币
|
||
pub fn issue_to_partition(
|
||
&mut self,
|
||
partition_id: &[u8; 32],
|
||
to: &str,
|
||
amount: u64,
|
||
) -> Result<()> {
|
||
self.transfer_manager
|
||
.partition_manager_mut()
|
||
.add_balance(partition_id, to, amount)
|
||
}
|
||
|
||
/// 从指定分区销毁代币
|
||
pub fn burn_from_partition(
|
||
&mut self,
|
||
partition_id: &[u8; 32],
|
||
from: &str,
|
||
amount: u64,
|
||
) -> Result<()> {
|
||
self.transfer_manager
|
||
.partition_manager_mut()
|
||
.sub_balance(partition_id, from, amount)
|
||
}
|
||
|
||
// ==================== 转账功能 ====================
|
||
|
||
/// 分区间转账
|
||
pub fn transfer_by_partition(
|
||
&mut self,
|
||
from: &str,
|
||
to: &str,
|
||
amount: u64,
|
||
partition_id: &[u8; 32],
|
||
) -> Result<TransferResult> {
|
||
self.transfer_manager
|
||
.transfer_by_partition(from, to, amount, partition_id)
|
||
}
|
||
|
||
/// 操作员代理转账
|
||
pub fn operator_transfer_by_partition(
|
||
&mut self,
|
||
operator: &str,
|
||
from: &str,
|
||
to: &str,
|
||
amount: u64,
|
||
partition_id: &[u8; 32],
|
||
) -> Result<TransferResult> {
|
||
self.transfer_manager
|
||
.operator_transfer_by_partition(operator, from, to, amount, partition_id)
|
||
}
|
||
|
||
// ==================== 操作员管理 ====================
|
||
|
||
/// 授权全局操作员
|
||
pub fn authorize_operator(&mut self, account: &str, operator: &str) {
|
||
self.transfer_manager
|
||
.operator_manager_mut()
|
||
.authorize_operator(account, operator);
|
||
}
|
||
|
||
/// 撤销全局操作员
|
||
pub fn revoke_operator(&mut self, account: &str, operator: &str) {
|
||
self.transfer_manager
|
||
.operator_manager_mut()
|
||
.revoke_operator(account, operator);
|
||
}
|
||
|
||
/// 授权分区级操作员
|
||
pub fn authorize_operator_by_partition(
|
||
&mut self,
|
||
account: &str,
|
||
partition_id: &[u8; 32],
|
||
operator: &str,
|
||
) {
|
||
self.transfer_manager
|
||
.operator_manager_mut()
|
||
.authorize_operator_by_partition(account, partition_id, operator);
|
||
}
|
||
|
||
/// 撤销分区级操作员
|
||
pub fn revoke_operator_by_partition(
|
||
&mut self,
|
||
account: &str,
|
||
partition_id: &[u8; 32],
|
||
operator: &str,
|
||
) {
|
||
self.transfer_manager
|
||
.operator_manager_mut()
|
||
.revoke_operator_by_partition(account, partition_id, operator);
|
||
}
|
||
|
||
/// 检查是否为操作员
|
||
pub fn is_operator_for(&self, account: &str, operator: &str) -> bool {
|
||
self.transfer_manager
|
||
.operator_manager()
|
||
.is_operator_for(account, operator)
|
||
}
|
||
|
||
/// 检查是否为分区级操作员
|
||
pub fn is_operator_for_partition(
|
||
&self,
|
||
account: &str,
|
||
partition_id: &[u8; 32],
|
||
operator: &str,
|
||
) -> bool {
|
||
self.transfer_manager
|
||
.operator_manager()
|
||
.is_operator_for_partition(account, partition_id, operator)
|
||
}
|
||
|
||
// ==================== 转账控制 ====================
|
||
|
||
/// 暂停所有转账
|
||
pub fn halt_transfers(&mut self) {
|
||
self.transfer_manager.halt_transfers();
|
||
}
|
||
|
||
/// 恢复转账
|
||
pub fn resume_transfers(&mut self) {
|
||
self.transfer_manager.resume_transfers();
|
||
}
|
||
|
||
/// 锁定账户
|
||
pub fn lock_account(&mut self, account: &str, unlock_time: u64) {
|
||
self.transfer_manager.lock_account(account, unlock_time);
|
||
}
|
||
|
||
/// 解锁账户
|
||
pub fn unlock_account(&mut self, account: &str) {
|
||
self.transfer_manager.unlock_account(account);
|
||
}
|
||
}
|
||
|
||
impl Default for Acc1410 {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn test_acc1410_full_workflow() {
|
||
let mut acc1410 = Acc1410::new();
|
||
|
||
// 创建普通股分区
|
||
let common_stock_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 common_partition = acc1410
|
||
.create_partition(
|
||
"Common Stock".to_string(),
|
||
common_stock_gnacs,
|
||
PartitionType::CommonStock,
|
||
)
|
||
.unwrap();
|
||
|
||
// 创建优先股分区
|
||
let preferred_stock_gnacs = ExtendedGNACS {
|
||
base_gnacs: vec![0x94, 0x01, 0x00, 0x04, 0x02, 0x02],
|
||
extension: GNACSExtension {
|
||
partition_type: 0x02,
|
||
vesting_years: 0,
|
||
voting_multiplier: 0,
|
||
dividend_priority: 1,
|
||
},
|
||
};
|
||
|
||
let preferred_partition = acc1410
|
||
.create_partition(
|
||
"Preferred Stock".to_string(),
|
||
preferred_stock_gnacs,
|
||
PartitionType::PreferredStock,
|
||
)
|
||
.unwrap();
|
||
|
||
// 发行代币
|
||
acc1410
|
||
.issue_to_partition(&common_partition, "user1", 1000)
|
||
.unwrap();
|
||
acc1410
|
||
.issue_to_partition(&preferred_partition, "user1", 500)
|
||
.unwrap();
|
||
|
||
// 检查余额
|
||
assert_eq!(
|
||
acc1410
|
||
.balance_of_by_partition(&common_partition, "user1")
|
||
.unwrap(),
|
||
1000
|
||
);
|
||
assert_eq!(
|
||
acc1410
|
||
.balance_of_by_partition(&preferred_partition, "user1")
|
||
.unwrap(),
|
||
500
|
||
);
|
||
|
||
// 转账
|
||
acc1410
|
||
.transfer_by_partition("user1", "user2", 300, &common_partition)
|
||
.unwrap();
|
||
|
||
assert_eq!(
|
||
acc1410
|
||
.balance_of_by_partition(&common_partition, "user1")
|
||
.unwrap(),
|
||
700
|
||
);
|
||
assert_eq!(
|
||
acc1410
|
||
.balance_of_by_partition(&common_partition, "user2")
|
||
.unwrap(),
|
||
300
|
||
);
|
||
|
||
// 授权操作员
|
||
acc1410.authorize_operator("user1", "operator1");
|
||
|
||
// 操作员代理转账
|
||
acc1410
|
||
.operator_transfer_by_partition("operator1", "user1", "user3", 200, &common_partition)
|
||
.unwrap();
|
||
|
||
assert_eq!(
|
||
acc1410
|
||
.balance_of_by_partition(&common_partition, "user1")
|
||
.unwrap(),
|
||
500
|
||
);
|
||
assert_eq!(
|
||
acc1410
|
||
.balance_of_by_partition(&common_partition, "user3")
|
||
.unwrap(),
|
||
200
|
||
);
|
||
|
||
// 检查账户拥有的分区
|
||
let partitions = acc1410.partitions_of("user1");
|
||
assert_eq!(partitions.len(), 2);
|
||
}
|
||
|
||
#[test]
|
||
fn test_partition_types() {
|
||
let mut acc1410 = Acc1410::new();
|
||
|
||
// 测试所有分区类型
|
||
let partition_types = vec![
|
||
(PartitionType::CommonStock, "Common Stock"),
|
||
(PartitionType::PreferredStock, "Preferred Stock"),
|
||
(PartitionType::RestrictedStock, "Restricted Stock"),
|
||
(PartitionType::EmployeeOption, "Employee Option"),
|
||
(PartitionType::IncomeRight, "Income Right"),
|
||
(PartitionType::VotingRight, "Voting Right"),
|
||
];
|
||
|
||
for (partition_type, name) in partition_types {
|
||
let gnacs = ExtendedGNACS {
|
||
base_gnacs: vec![0; 6],
|
||
extension: GNACSExtension {
|
||
partition_type: partition_type as u8,
|
||
vesting_years: 0,
|
||
voting_multiplier: 1,
|
||
dividend_priority: 1,
|
||
},
|
||
};
|
||
|
||
let partition_id = acc1410
|
||
.create_partition(name.to_string(), gnacs, partition_type)
|
||
.unwrap();
|
||
|
||
let info = acc1410.get_partition_info(&partition_id).unwrap();
|
||
assert_eq!(info.partition_type, partition_type);
|
||
assert_eq!(info.name, name);
|
||
}
|
||
}
|
||
|
||
#[test]
|
||
fn test_gnacs_extension() {
|
||
// 测试GNACS扩展编码/解码
|
||
let extension = GNACSExtension {
|
||
partition_type: 0x01,
|
||
vesting_years: 3,
|
||
voting_multiplier: 2,
|
||
dividend_priority: 1,
|
||
};
|
||
|
||
let encoded = extension.encode();
|
||
let decoded = GNACSExtension::decode(encoded);
|
||
|
||
assert_eq!(decoded.partition_type, 0x01);
|
||
assert_eq!(decoded.vesting_years, 3);
|
||
assert_eq!(decoded.voting_multiplier, 2);
|
||
assert_eq!(decoded.dividend_priority, 1);
|
||
|
||
// 测试完整64位GNACS
|
||
let extended_gnacs = ExtendedGNACS {
|
||
base_gnacs: vec![0x94, 0x01, 0x00, 0x04, 0x02, 0x01],
|
||
extension,
|
||
};
|
||
|
||
let full_encoded = extended_gnacs.encode();
|
||
assert_eq!(full_encoded.len(), 8);
|
||
|
||
let full_decoded = ExtendedGNACS::decode(&full_encoded).unwrap();
|
||
assert_eq!(full_decoded.base_gnacs, vec![0x94, 0x01, 0x00, 0x04, 0x02, 0x01]);
|
||
assert_eq!(full_decoded.extension.partition_type, 0x01);
|
||
}
|
||
}
|