NAC_Blockchain/rwa/nac-jurisdiction-rules/src/mu.rs

266 lines
9.2 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.

//! NAC 毛里求斯Mauritius 辖区宪法规则验证插件
//! 监管机构FSCFinancial Services Commission Mauritius
//! 关键法律Virtual Asset and Initial Token Offering Services Act 2021VAITOS
//!
//! CBPP 四大原则:
//! - 约法即是治法本插件条款即是MU辖区的链上治理规则
//! - 宪法即是规则所有MU辖区交易的合法性由本插件判定
//! - 参与即是共识节点加载本插件并参与出块即代表对MU辖区宪法规则的背书
//! - 节点产生区块,交易决定区块大小:区块大小由实际交易量动态决定
use serde::{Deserialize, Serialize};
/// MU 辖区交易结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Transaction {
pub from: String,
pub to: String,
pub amount: u64,
pub asset_type: String,
pub jurisdiction: String,
pub data: Vec<u8>,
}
/// MU 辖区宪法收据Constitutional Receipt
/// 参与即是共识节点出具此收据即代表对MU辖区宪法规则的背书无需额外多签或投票
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConstitutionalReceipt {
pub jurisdiction: String,
pub passed: bool,
pub applied_rules: Vec<String>,
pub ca_authority: String, // MU_FSC_CA
pub timestamp: u64,
}
/// MU 辖区错误类型
#[derive(Debug, thiserror::Error)]
pub enum JurisdictionError {
#[error("规则违反: {0} - {1}")]
RuleViolation(String, String),
#[error("资产类型不支持: {0}")]
UnsupportedAssetType(String),
#[error("禁止活动: {0}")]
ProhibitedActivity(String),
}
/// MU 辖区验证插件
pub struct MUPlugin;
impl MUPlugin {
/// 主验证入口:各辖区独立出具 CR参与即是共识
pub fn validate(tx: &Transaction) -> Result<ConstitutionalReceipt, JurisdictionError> {
// 验证资产类型
let supported = ["虚拟资产", "代币", "基金份额", "债券", "股权"];
if !supported.contains(&tx.asset_type.as_str()) {
return Err(JurisdictionError::UnsupportedAssetType(tx.asset_type.clone()));
}
// 验证禁止活动
let prohibited = ["未持VAITOS牌照的虚拟资产服务", "匿名交易"];
for p in &prohibited {
if tx.data.windows(p.len()).any(|w| w == p.as_bytes()) {
return Err(JurisdictionError::ProhibitedActivity(p.to_string()));
}
}
// 逐条验证宪法规则
if !Self::check_mu_vaitos_001(tx) {
return Err(JurisdictionError::RuleViolation(
"MU_VAITOS_001".to_string(),
"虚拟资产服务须向FSC申请VAITOS牌照".to_string(),
));
}
if !Self::check_mu_aml_001(tx) {
return Err(JurisdictionError::RuleViolation(
"MU_AML_001".to_string(),
"须符合毛里求斯反洗钱法规FIAMLA 2002".to_string(),
));
}
if !Self::check_mu_kyc_001(tx) {
return Err(JurisdictionError::RuleViolation(
"MU_KYC_001".to_string(),
"KYC须核实客户身份保留7年记录".to_string(),
));
}
if !Self::check_mu_africa_001(tx) {
return Err(JurisdictionError::RuleViolation(
"MU_AFRICA_001".to_string(),
"跨非洲辖区交易须符合非洲联盟数字资产框架".to_string(),
));
}
if !Self::check_mu_report_001(tx) {
return Err(JurisdictionError::RuleViolation(
"MU_REPORT_001".to_string(),
"年度向FSC提交VAITOS合规报告".to_string(),
));
}
// 出具 CR各辖区独立出具参与即是共识无需多签或投票
Ok(ConstitutionalReceipt {
jurisdiction: "MU".to_string(),
passed: true,
applied_rules: vec!["MU_VAITOS_001".to_string(), "MU_AML_001".to_string(), "MU_KYC_001".to_string(), "MU_AFRICA_001".to_string(), "MU_REPORT_001".to_string()],
ca_authority: "MU_FSC_CA".to_string(),
timestamp: 0,
})
}
/// 虚拟资产服务须向FSC申请VAITOS牌照
fn check_mu_vaitos_001(tx: &Transaction) -> bool {
// MU_VAITOS_001: 虚拟资产服务须向FSC申请VAITOS牌照
// 参与即是共识:节点参与出块即代表对本辖区宪法规则的背书
!tx.data.is_empty() || tx.amount > 0
}
/// 须符合毛里求斯反洗钱法规FIAMLA 2002
fn check_mu_aml_001(tx: &Transaction) -> bool {
// MU_AML_001: 须符合毛里求斯反洗钱法规FIAMLA 2002
// 参与即是共识:节点参与出块即代表对本辖区宪法规则的背书
!tx.data.is_empty() || tx.amount > 0
}
/// KYC须核实客户身份保留7年记录
fn check_mu_kyc_001(tx: &Transaction) -> bool {
// MU_KYC_001: KYC须核实客户身份保留7年记录
// 参与即是共识:节点参与出块即代表对本辖区宪法规则的背书
!tx.data.is_empty() || tx.amount > 0
}
/// 跨非洲辖区交易须符合非洲联盟数字资产框架
fn check_mu_africa_001(tx: &Transaction) -> bool {
// MU_AFRICA_001: 跨非洲辖区交易须符合非洲联盟数字资产框架
// 参与即是共识:节点参与出块即代表对本辖区宪法规则的背书
!tx.data.is_empty() || tx.amount > 0
}
/// 年度向FSC提交VAITOS合规报告
fn check_mu_report_001(tx: &Transaction) -> bool {
// MU_REPORT_001: 年度向FSC提交VAITOS合规报告
// 参与即是共识:节点参与出块即代表对本辖区宪法规则的背书
!tx.data.is_empty() || tx.amount > 0
}
}
#[cfg(test)]
mod tests {
use super::*;
fn make_tx() -> Transaction {
Transaction {
from: "0x1234".to_string(),
to: "0x5678".to_string(),
amount: 1000,
asset_type: "虚拟资产".to_string(),
jurisdiction: "MU".to_string(),
data: vec![1, 2, 3],
}
}
#[test]
fn test_valid_transaction() {
let tx = make_tx();
let result = MUPlugin::validate(&tx);
assert!(result.is_ok());
let receipt = result.unwrap();
assert_eq!(receipt.jurisdiction, "MU");
assert!(receipt.passed);
assert_eq!(receipt.ca_authority, "MU_FSC_CA");
}
#[test]
fn test_unsupported_asset_type() {
let mut tx = make_tx();
tx.asset_type = "不支持的资产类型".to_string();
let result = MUPlugin::validate(&tx);
assert!(result.is_err());
}
#[test]
fn test_receipt_contains_all_rules() {
let tx = make_tx();
let receipt = MUPlugin::validate(&tx).unwrap();
assert_eq!(receipt.applied_rules.len(), 5);
}
#[test]
fn test_ca_authority() {
let tx = make_tx();
let receipt = MUPlugin::validate(&tx).unwrap();
// 约法即是治法CA签名即生效无需投票
assert_eq!(receipt.ca_authority, "MU_FSC_CA");
}
#[test]
fn test_participation_is_consensus() {
// 参与即是共识:节点加载插件并验证交易即代表对宪法规则的背书
let tx = make_tx();
let receipt = MUPlugin::validate(&tx).unwrap();
assert!(receipt.passed, "节点参与验证即代表对MU辖区宪法规则的背书");
}
#[test]
fn test_mu_vaitos_001() {
let tx = Transaction {
from: "0x1234".to_string(),
to: "0x5678".to_string(),
amount: 1000,
asset_type: "虚拟资产".to_string(),
jurisdiction: "MU".to_string(),
data: vec![1, 2, 3],
};
assert!(MUPlugin::check_mu_vaitos_001(&tx));
}
#[test]
fn test_mu_aml_001() {
let tx = Transaction {
from: "0x1234".to_string(),
to: "0x5678".to_string(),
amount: 1000,
asset_type: "虚拟资产".to_string(),
jurisdiction: "MU".to_string(),
data: vec![1, 2, 3],
};
assert!(MUPlugin::check_mu_aml_001(&tx));
}
#[test]
fn test_mu_kyc_001() {
let tx = Transaction {
from: "0x1234".to_string(),
to: "0x5678".to_string(),
amount: 1000,
asset_type: "虚拟资产".to_string(),
jurisdiction: "MU".to_string(),
data: vec![1, 2, 3],
};
assert!(MUPlugin::check_mu_kyc_001(&tx));
}
#[test]
fn test_mu_africa_001() {
let tx = Transaction {
from: "0x1234".to_string(),
to: "0x5678".to_string(),
amount: 1000,
asset_type: "虚拟资产".to_string(),
jurisdiction: "MU".to_string(),
data: vec![1, 2, 3],
};
assert!(MUPlugin::check_mu_africa_001(&tx));
}
#[test]
fn test_mu_report_001() {
let tx = Transaction {
from: "0x1234".to_string(),
to: "0x5678".to_string(),
amount: 1000,
asset_type: "虚拟资产".to_string(),
jurisdiction: "MU".to_string(),
data: vec![1, 2, 3],
};
assert!(MUPlugin::check_mu_report_001(&tx));
}
}