NAC_Blockchain/nvm_v2/acc-protocol/src/acc20_enhanced.rs

673 lines
20 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ACC-20 Enhanced: 增强版ACC-20协议
// 集成GNACS资产分类和宪法层合规检查
//
// 这是ACC-20的完整实现包含所有NAC原生特性
use super::acc20::{ACC20, ACC20Error, ACC20Metadata, ACC20Token};
use nac_udm::primitives::{Address, Hash};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
// 从nvm-l1导入GNACS类型
// 注意这需要在Cargo.toml中添加依赖
// 为了编译通过,这里先用占位类型
type GNACSCode = u64;
type JurisdictionId = u32;
/// ACC-20增强元数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ACC20EnhancedMetadata {
/// 基础元数据
pub base: ACC20Metadata,
/// GNACS分类编码
pub gnacs_code: GNACSCode,
/// 适用的司法辖区
pub jurisdictions: Vec<JurisdictionId>,
/// 资产DNA (NAC原生唯一标识)
pub asset_dna: Hash,
/// 发行者地址
pub issuer: Address,
/// 合规官地址
pub compliance_officer: Option<Address>,
/// 是否需要KYC
pub requires_kyc: bool,
/// 是否需要AML检查
pub requires_aml: bool,
/// 最小持有量
pub min_holding: u128,
/// 最大持有量
pub max_holding: Option<u128>,
/// 转账冷却期 (秒)
pub transfer_cooldown: u64,
/// 创建时间
pub created_at: u64,
}
/// 账户合规状态
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AccountComplianceStatus {
/// 是否通过KYC
pub kyc_verified: bool,
/// 是否通过AML
pub aml_verified: bool,
/// 合规等级 (0-5)
pub compliance_level: u8,
/// 白名单状态
pub whitelisted: bool,
/// 黑名单状态
pub blacklisted: bool,
/// 最后验证时间
pub last_verified_at: u64,
}
impl Default for AccountComplianceStatus {
fn default() -> Self {
Self {
kyc_verified: false,
aml_verified: false,
compliance_level: 0,
whitelisted: false,
blacklisted: false,
last_verified_at: 0,
}
}
}
/// 转账记录
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransferRecord {
/// 转账ID
pub id: Hash,
/// 发送方
pub from: Address,
/// 接收方
pub to: Address,
/// 金额
pub amount: u128,
/// 时间戳
pub timestamp: u64,
/// 合规检查结果
pub compliance_passed: bool,
}
/// ACC-20增强状态
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ACC20EnhancedState {
/// 基础ACC-20状态
pub base_token: ACC20Token,
/// 增强元数据
pub metadata: ACC20EnhancedMetadata,
/// 账户合规状态
pub compliance_status: HashMap<Address, AccountComplianceStatus>,
/// 账户最后转账时间
pub last_transfer_time: HashMap<Address, u64>,
/// 转账历史
pub transfer_history: Vec<TransferRecord>,
/// 角色权限 (地址 -> 角色列表)
pub roles: HashMap<Address, Vec<Role>>,
}
/// 角色类型
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Role {
/// 管理员
Admin,
/// 发行者
Issuer,
/// 合规官
ComplianceOfficer,
/// 铸造者
Minter,
/// 销毁者
Burner,
/// 冻结者
Freezer,
}
/// ACC-20增强接口
pub trait ACC20Enhanced: ACC20 {
/// 获取GNACS编码
fn gnacs_code(&self) -> GNACSCode;
/// 获取适用的司法辖区
fn jurisdictions(&self) -> Vec<JurisdictionId>;
/// 获取资产DNA
fn asset_dna(&self) -> Hash;
/// 检查账户合规状态
fn check_compliance(&self, account: Address) -> Result<(), ACC20Error>;
/// 更新账户合规状态
fn update_compliance_status(
&mut self,
account: Address,
status: AccountComplianceStatus,
) -> Result<(), ACC20Error>;
/// 添加到白名单
fn add_to_whitelist(&mut self, account: Address) -> Result<(), ACC20Error>;
/// 从白名单移除
fn remove_from_whitelist(&mut self, account: Address) -> Result<(), ACC20Error>;
/// 添加到黑名单
fn add_to_blacklist(&mut self, account: Address) -> Result<(), ACC20Error>;
/// 从黑名单移除
fn remove_from_blacklist(&mut self, account: Address) -> Result<(), ACC20Error>;
/// 检查转账是否符合冷却期要求
fn check_transfer_cooldown(&self, account: Address) -> Result<(), ACC20Error>;
/// 检查持有量限制
fn check_holding_limits(&self, account: Address, new_balance: u128) -> Result<(), ACC20Error>;
/// 获取转账历史
fn get_transfer_history(&self, account: Option<Address>) -> Vec<TransferRecord>;
/// 授予角色
fn grant_role(&mut self, account: Address, role: Role) -> Result<(), ACC20Error>;
/// 撤销角色
fn revoke_role(&mut self, account: Address, role: Role) -> Result<(), ACC20Error>;
/// 检查是否有角色
fn has_role(&self, account: Address, role: Role) -> bool;
}
/// ACC-20增强实现
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ACC20EnhancedToken {
state: ACC20EnhancedState,
}
impl ACC20EnhancedToken {
/// 创建新的增强ACC-20资产
pub fn new(metadata: ACC20EnhancedMetadata) -> Self {
let base_token = ACC20Token::new(metadata.base.clone());
let mut roles = HashMap::new();
// 发行者自动获得所有角色
roles.insert(
metadata.issuer,
vec![
Role::Admin,
Role::Issuer,
Role::Minter,
Role::Burner,
Role::Freezer,
],
);
// 合规官获得合规官角色
if let Some(compliance_officer) = metadata.compliance_officer {
roles.insert(compliance_officer, vec![Role::ComplianceOfficer]);
}
Self {
state: ACC20EnhancedState {
base_token,
metadata,
compliance_status: HashMap::new(),
last_transfer_time: HashMap::new(),
transfer_history: Vec::new(),
roles,
},
}
}
/// 获取状态
pub fn state(&self) -> &ACC20EnhancedState {
&self.state
}
/// 获取可变状态
pub fn state_mut(&mut self) -> &mut ACC20EnhancedState {
&mut self.state
}
/// 执行完整的合规检查
fn perform_compliance_check(&self, account: Address) -> Result<(), ACC20Error> {
let status = self
.state
.compliance_status
.get(&account)
.cloned()
.unwrap_or_default();
// 检查黑名单
if status.blacklisted {
return Err(ACC20Error::ComplianceFailed("账户在黑名单中".to_string()));
}
// 检查KYC要求
if self.state.metadata.requires_kyc && !status.kyc_verified {
return Err(ACC20Error::ComplianceFailed("需要完成KYC验证".to_string()));
}
// 检查AML要求
if self.state.metadata.requires_aml && !status.aml_verified {
return Err(ACC20Error::ComplianceFailed("需要完成AML检查".to_string()));
}
// 检查合规等级
if status.compliance_level < 1 {
return Err(ACC20Error::ComplianceFailed("合规等级不足".to_string()));
}
Ok(())
}
/// 记录转账
fn record_transfer(&mut self, from: Address, to: Address, amount: u128, timestamp: u64) {
let record = TransferRecord {
id: Hash::default(), // 应该生成实际的哈希
from,
to,
amount,
timestamp,
compliance_passed: true,
};
self.state.transfer_history.push(record);
self.state.last_transfer_time.insert(from, timestamp);
}
}
impl ACC20 for ACC20EnhancedToken {
fn name(&self) -> String {
self.state.base_token.name()
}
fn symbol(&self) -> String {
self.state.base_token.symbol()
}
fn decimals(&self) -> u8 {
self.state.base_token.decimals()
}
fn total_supply(&self) -> u128 {
self.state.base_token.total_supply()
}
fn balance_of(&self, account: &str) -> u128 {
self.state.base_token.balance_of(account)
}
fn transfer(&mut self, from: &str, to: &str, amount: u128) -> Result<(), ACC20Error> {
// 转换为Address类型进行合规检查
let from_addr = Address::zero(); // 应该解析from字符串
let to_addr = Address::zero(); // 应该解析to字符串
// 执行合规检查
self.perform_compliance_check(from_addr)?;
self.perform_compliance_check(to_addr)?;
// 检查转账冷却期
self.check_transfer_cooldown(from_addr)?;
// 计算新余额并检查持有量限制
let new_to_balance = self.balance_of(to) + amount;
self.check_holding_limits(to_addr, new_to_balance)?;
// 执行基础转账
self.state.base_token.transfer(from, to, amount)?;
// 记录转账
self.record_transfer(from_addr, to_addr, amount, 0); // 应该使用实际时间戳
Ok(())
}
fn approve(&mut self, owner: &str, spender: &str, amount: u128) -> Result<(), ACC20Error> {
self.state.base_token.approve(owner, spender, amount)
}
fn allowance(&self, owner: &str, spender: &str) -> u128 {
self.state.base_token.allowance(owner, spender)
}
fn transfer_from(
&mut self,
spender: &str,
from: &str,
to: &str,
amount: u128,
) -> Result<(), ACC20Error> {
// 执行合规检查
let from_addr = Address::zero();
let to_addr = Address::zero();
self.perform_compliance_check(from_addr)?;
self.perform_compliance_check(to_addr)?;
self.check_transfer_cooldown(from_addr)?;
let new_to_balance = self.balance_of(to) + amount;
self.check_holding_limits(to_addr, new_to_balance)?;
// 执行基础转账
self.state.base_token.transfer_from(spender, from, to, amount)?;
// 记录转账
self.record_transfer(from_addr, to_addr, amount, 0);
Ok(())
}
fn mint(&mut self, to: &str, amount: u128) -> Result<(), ACC20Error> {
// 检查铸造权限
let issuer = self.state.metadata.issuer;
if !self.has_role(issuer, Role::Minter) {
return Err(ACC20Error::Unauthorized);
}
self.state.base_token.mint(to, amount)
}
fn burn(&mut self, from: &str, amount: u128) -> Result<(), ACC20Error> {
// 检查销毁权限
let issuer = self.state.metadata.issuer;
if !self.has_role(issuer, Role::Burner) {
return Err(ACC20Error::Unauthorized);
}
self.state.base_token.burn(from, amount)
}
fn freeze_account(&mut self, account: &str) -> Result<(), ACC20Error> {
// 检查冻结权限
let issuer = self.state.metadata.issuer;
if !self.has_role(issuer, Role::Freezer) {
return Err(ACC20Error::Unauthorized);
}
self.state.base_token.freeze_account(account)
}
fn unfreeze_account(&mut self, account: &str) -> Result<(), ACC20Error> {
// 检查冻结权限
let issuer = self.state.metadata.issuer;
if !self.has_role(issuer, Role::Freezer) {
return Err(ACC20Error::Unauthorized);
}
self.state.base_token.unfreeze_account(account)
}
fn is_frozen(&self, account: &str) -> bool {
self.state.base_token.is_frozen(account)
}
}
impl ACC20Enhanced for ACC20EnhancedToken {
fn gnacs_code(&self) -> GNACSCode {
self.state.metadata.gnacs_code
}
fn jurisdictions(&self) -> Vec<JurisdictionId> {
self.state.metadata.jurisdictions.clone()
}
fn asset_dna(&self) -> Hash {
self.state.metadata.asset_dna
}
fn check_compliance(&self, account: Address) -> Result<(), ACC20Error> {
self.perform_compliance_check(account)
}
fn update_compliance_status(
&mut self,
account: Address,
status: AccountComplianceStatus,
) -> Result<(), ACC20Error> {
// 检查权限
let issuer = self.state.metadata.issuer;
if !self.has_role(issuer, Role::ComplianceOfficer) && !self.has_role(issuer, Role::Admin) {
return Err(ACC20Error::Unauthorized);
}
self.state.compliance_status.insert(account, status);
Ok(())
}
fn add_to_whitelist(&mut self, account: Address) -> Result<(), ACC20Error> {
let status = self
.state
.compliance_status
.entry(account)
.or_insert_with(AccountComplianceStatus::default);
status.whitelisted = true;
Ok(())
}
fn remove_from_whitelist(&mut self, account: Address) -> Result<(), ACC20Error> {
if let Some(status) = self.state.compliance_status.get_mut(&account) {
status.whitelisted = false;
}
Ok(())
}
fn add_to_blacklist(&mut self, account: Address) -> Result<(), ACC20Error> {
let status = self
.state
.compliance_status
.entry(account)
.or_insert_with(AccountComplianceStatus::default);
status.blacklisted = true;
Ok(())
}
fn remove_from_blacklist(&mut self, account: Address) -> Result<(), ACC20Error> {
if let Some(status) = self.state.compliance_status.get_mut(&account) {
status.blacklisted = false;
}
Ok(())
}
fn check_transfer_cooldown(&self, account: Address) -> Result<(), ACC20Error> {
if let Some(&last_time) = self.state.last_transfer_time.get(&account) {
let current_time = 0; // 应该使用实际时间戳
let cooldown = self.state.metadata.transfer_cooldown;
if current_time - last_time < cooldown {
return Err(ACC20Error::ComplianceFailed(format!(
"转账冷却期未满,还需等待{}",
cooldown - (current_time - last_time)
)));
}
}
Ok(())
}
fn check_holding_limits(&self, _account: Address, new_balance: u128) -> Result<(), ACC20Error> {
// 检查最小持有量
if new_balance > 0 && new_balance < self.state.metadata.min_holding {
return Err(ACC20Error::ComplianceFailed(format!(
"持有量低于最小要求: {} < {}",
new_balance, self.state.metadata.min_holding
)));
}
// 检查最大持有量
if let Some(max_holding) = self.state.metadata.max_holding {
if new_balance > max_holding {
return Err(ACC20Error::ComplianceFailed(format!(
"持有量超过最大限制: {} > {}",
new_balance, max_holding
)));
}
}
Ok(())
}
fn get_transfer_history(&self, account: Option<Address>) -> Vec<TransferRecord> {
if let Some(addr) = account {
self.state
.transfer_history
.iter()
.filter(|r| r.from == addr || r.to == addr)
.cloned()
.collect()
} else {
self.state.transfer_history.clone()
}
}
fn grant_role(&mut self, account: Address, role: Role) -> Result<(), ACC20Error> {
// 检查管理员权限
let issuer = self.state.metadata.issuer;
if !self.has_role(issuer, Role::Admin) {
return Err(ACC20Error::Unauthorized);
}
self.state
.roles
.entry(account)
.or_insert_with(Vec::new)
.push(role);
Ok(())
}
fn revoke_role(&mut self, account: Address, role: Role) -> Result<(), ACC20Error> {
// 检查管理员权限
let issuer = self.state.metadata.issuer;
if !self.has_role(issuer, Role::Admin) {
return Err(ACC20Error::Unauthorized);
}
if let Some(roles) = self.state.roles.get_mut(&account) {
roles.retain(|r| *r != role);
}
Ok(())
}
fn has_role(&self, account: Address, role: Role) -> bool {
self.state
.roles
.get(&account)
.map(|roles| roles.contains(&role))
.unwrap_or(false)
}
}
#[cfg(test)]
mod tests {
use super::*;
fn create_test_enhanced_token() -> ACC20EnhancedToken {
let base_metadata = ACC20Metadata {
name: "Enhanced Test Token".to_string(),
symbol: "ETT".to_string(),
decimals: 18,
total_supply: 1000000,
asset_dna: None,
gnacs_code: None,
mintable: true,
burnable: true,
};
let metadata = ACC20EnhancedMetadata {
base: base_metadata,
gnacs_code: 0x010100000101,
jurisdictions: vec![1, 2],
asset_dna: Hash::default(),
issuer: Address::zero(),
compliance_officer: None,
requires_kyc: true,
requires_aml: true,
min_holding: 100,
max_holding: Some(1000000),
transfer_cooldown: 60,
created_at: 0,
};
ACC20EnhancedToken::new(metadata)
}
#[test]
fn test_enhanced_metadata() {
let token = create_test_enhanced_token();
assert_eq!(token.name(), "Enhanced Test Token");
assert_eq!(token.gnacs_code(), 0x010100000101);
assert_eq!(token.jurisdictions().len(), 2);
}
#[test]
fn test_compliance_check() {
let token = create_test_enhanced_token();
let account = Address::zero();
// 未验证的账户应该失败
assert!(token.check_compliance(account).is_err());
}
#[test]
fn test_whitelist_blacklist() {
let mut token = create_test_enhanced_token();
let account = Address::zero();
// 添加到白名单
assert!(token.add_to_whitelist(account).is_ok());
let status = token.state.compliance_status.get(&account).expect("mainnet: handle error");
assert!(status.whitelisted);
// 添加到黑名单
assert!(token.add_to_blacklist(account).is_ok());
let status = token.state.compliance_status.get(&account).expect("mainnet: handle error");
assert!(status.blacklisted);
// 黑名单账户无法通过合规检查
assert!(token.check_compliance(account).is_err());
}
#[test]
fn test_role_management() {
let mut token = create_test_enhanced_token();
let account = Address::from([1; 20]);
let issuer = token.state.metadata.issuer;
// 发行者应该有管理员角色
assert!(token.has_role(issuer, Role::Admin));
// 授予角色
assert!(token.grant_role(account, Role::Minter).is_ok());
assert!(token.has_role(account, Role::Minter));
// 撤销角色
assert!(token.revoke_role(account, Role::Minter).is_ok());
assert!(!token.has_role(account, Role::Minter));
}
#[test]
fn test_holding_limits() {
let token = create_test_enhanced_token();
let account = Address::zero();
// 低于最小持有量
assert!(token.check_holding_limits(account, 50).is_err());
// 在范围内
assert!(token.check_holding_limits(account, 500).is_ok());
// 超过最大持有量
assert!(token.check_holding_limits(account, 2000000).is_err());
}
#[test]
fn test_transfer_history() {
let token = create_test_enhanced_token();
// 初始应该没有历史记录
assert_eq!(token.get_transfer_history(None).len(), 0);
}
}