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

218 lines
7.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 TR 辖区宪法规则验证插件
// 监管机构SPK/BDDK (Capital Markets Board / Banking Regulation and Supervision Agency)
// 法律框架Capital Markets Law No. 6362 / Crypto Asset Service Providers Regulation 2021
// CBPP原则约法即是治法 | 宪法即是规则 | 参与即是共识 | 节点产生区块交易决定区块大小
// 参与即是共识TR辖区节点加载此插件参与出块即代表对本辖区宪法规则的背书
// NAC_Lens 4.0 路由层自动处理跨辖区消息传递
use serde::{Deserialize, Serialize};
const JURISDICTION_CODE: &str = "TR";
const AML_THRESHOLD_USD: f64 = 15000.0;
/// TR 辖区交易上下文(土耳其)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TRTxContext {
pub tx_hash: String,
pub from: [u8; 32],
pub to: [u8; 32],
pub amount_usd: f64,
pub asset_type: String,
pub kyc_level: KycLevel,
pub aml_reported: bool,
pub is_anonymous: bool,
pub is_cross_border: bool,
pub sanctions_cleared: bool,
}
/// KYC 等级
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum KycLevel {
None,
Basic,
Enhanced,
Institutional,
}
/// 验证结果
#[derive(Debug, Clone)]
pub enum ValidationResult {
Approved {
jurisdiction: String,
/// 宪法收据CR参与即是共识节点独立出具无需多签
constitutional_receipt: String,
},
Rejected {
reason: String,
jurisdiction: String,
},
}
/// TR 辖区宪法规则验证引擎
pub struct TRJurisdictionPlugin;
impl TRJurisdictionPlugin {
pub fn new() -> Self {
Self
}
/// KYC 等级验证最低要求Enhanced
fn check_kyc_level(tx: &TRTxContext) -> bool {
matches!(tx.kyc_level, KycLevel::Enhanced | KycLevel::Institutional)
|| (tx.kyc_level == KycLevel::Enhanced && "Enhanced" == "Enhanced")
}
/// AML 阈值检查15000 USD
fn check_aml_threshold(tx: &TRTxContext) -> bool {
if tx.amount_usd > AML_THRESHOLD_USD {
// 超过阈值需要向 SPK/BDDK (Capital Markets Board / Banking Regulation and Supervision Agency) 报告
// 约法即是治法:此要求直接来自 Capital Markets Law No. 6362 / Crypto Asset Service Providers Regulation 2021
return tx.aml_reported;
}
true
}
/// 制裁名单检查
fn check_sanctions(tx: &TRTxContext) -> bool {
tx.sanctions_cleared
}
/// 辖区特定规则验证
fn check_jurisdiction_rules(tx: &TRTxContext) -> bool {
// Rule: CASP license required from SPK
// Rule: Turkish TC Kimlik No KYC mandatory
// Rule: TRY reporting above TRY 75,000
// Rule: Prohibition on using crypto as payment instruments (CBRT 2021)
// 禁止匿名交易(宪法即是规则)
!tx.is_anonymous
}
/// 出具宪法收据CR
/// 参与即是共识节点独立出具CR无需多签无需链上投票
fn issue_constitutional_receipt(tx: &TRTxContext) -> String {
format!("CR-{}:{}", JURISDICTION_CODE, tx.tx_hash)
}
}
impl TRJurisdictionPlugin {
/// 主验证入口
pub fn validate(&self, tx: &TRTxContext) -> ValidationResult {
// 1. KYC 验证
if !Self::check_kyc_level(tx) {
return ValidationResult::Rejected {
reason: format!("TR_KYC: Minimum level Enhanced required per {}",
"SPK/BDDK (Capital Markets Board / Banking Regulation and Supervision Agency)"),
jurisdiction: JURISDICTION_CODE.to_string(),
};
}
// 2. AML 阈值检查
if !Self::check_aml_threshold(tx) {
return ValidationResult::Rejected {
reason: format!("TR_AML: Transactions above {} USD require reporting to {}",
AML_THRESHOLD_USD, "SPK/BDDK (Capital Markets Board / Banking Regulation and Supervision Agency)"),
jurisdiction: JURISDICTION_CODE.to_string(),
};
}
// 3. 制裁名单检查
if !Self::check_sanctions(tx) {
return ValidationResult::Rejected {
reason: "TR_SANCTIONS: Transaction parties are on sanctions list".to_string(),
jurisdiction: JURISDICTION_CODE.to_string(),
};
}
// 4. 辖区特定规则
if !Self::check_jurisdiction_rules(tx) {
return ValidationResult::Rejected {
reason: "TR_RULES: Jurisdiction-specific rule violation".to_string(),
jurisdiction: JURISDICTION_CODE.to_string(),
};
}
// 验证通过,出具 CR参与即是共识
ValidationResult::Approved {
jurisdiction: JURISDICTION_CODE.to_string(),
constitutional_receipt: Self::issue_constitutional_receipt(tx),
}
}
pub fn jurisdiction_code(&self) -> &str {
JURISDICTION_CODE
}
pub fn regulatory_authority(&self) -> &str {
"SPK/BDDK (Capital Markets Board / Banking Regulation and Supervision Agency)"
}
}
#[cfg(test)]
mod tests {
use super::*;
fn make_tx(kyc: KycLevel, amount: f64, anonymous: bool, aml: bool) -> TRTxContext {
TRTxContext {
tx_hash: "test_hash_001".to_string(),
from: [0u8; 32],
to: [1u8; 32],
amount_usd: amount,
asset_type: "RWA_REAL_ESTATE".to_string(),
kyc_level: kyc,
aml_reported: aml,
is_anonymous: anonymous,
is_cross_border: false,
sanctions_cleared: true,
}
}
#[test]
fn test_tr_valid_transaction() {
let plugin = TRJurisdictionPlugin::new();
let tx = make_tx(KycLevel::Enhanced, 1000.0, false, false);
assert!(matches!(plugin.validate(&tx), ValidationResult::Approved { .. }));
}
#[test]
fn test_tr_kyc_insufficient() {
let plugin = TRJurisdictionPlugin::new();
let tx = make_tx(KycLevel::None, 1000.0, false, false);
assert!(matches!(plugin.validate(&tx), ValidationResult::Rejected { .. }));
}
#[test]
fn test_tr_aml_threshold_exceeded_unreported() {
let plugin = TRJurisdictionPlugin::new();
let tx = make_tx(KycLevel::Enhanced, 16000.0, false, false);
assert!(matches!(plugin.validate(&tx), ValidationResult::Rejected { .. }));
}
#[test]
fn test_tr_aml_threshold_reported() {
let plugin = TRJurisdictionPlugin::new();
let tx = make_tx(KycLevel::Enhanced, 16000.0, false, true);
assert!(matches!(plugin.validate(&tx), ValidationResult::Approved { .. }));
}
#[test]
fn test_tr_anonymous_rejected() {
let plugin = TRJurisdictionPlugin::new();
let tx = make_tx(KycLevel::Enhanced, 100.0, true, false);
assert!(matches!(plugin.validate(&tx), ValidationResult::Rejected { .. }));
}
#[test]
fn test_tr_jurisdiction_code() {
let plugin = TRJurisdictionPlugin::new();
assert_eq!(plugin.jurisdiction_code(), "TR");
}
#[test]
fn test_tr_regulatory_authority() {
let plugin = TRJurisdictionPlugin::new();
assert!(!plugin.regulatory_authority().is_empty());
}
}