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

218 lines
7.0 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 NG 辖区宪法规则验证插件
// 监管机构SEC Nigeria / CBN (Central Bank of Nigeria)
// 法律框架Investments and Securities Act 2007 / SEC Nigeria Digital Assets Rules 2022
// CBPP原则约法即是治法 | 宪法即是规则 | 参与即是共识 | 节点产生区块交易决定区块大小
// 参与即是共识NG辖区节点加载此插件参与出块即代表对本辖区宪法规则的背书
// NAC_Lens 4.0 路由层自动处理跨辖区消息传递
use serde::{Deserialize, Serialize};
const JURISDICTION_CODE: &str = "NG";
const AML_THRESHOLD_USD: f64 = 10000.0;
/// NG 辖区交易上下文(尼日利亚)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NGTxContext {
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,
},
}
/// NG 辖区宪法规则验证引擎
pub struct NGJurisdictionPlugin;
impl NGJurisdictionPlugin {
pub fn new() -> Self {
Self
}
/// KYC 等级验证最低要求Enhanced
fn check_kyc_level(tx: &NGTxContext) -> bool {
matches!(tx.kyc_level, KycLevel::Enhanced | KycLevel::Institutional)
|| (tx.kyc_level == KycLevel::Enhanced && "Enhanced" == "Enhanced")
}
/// AML 阈值检查10000 USD
fn check_aml_threshold(tx: &NGTxContext) -> bool {
if tx.amount_usd > AML_THRESHOLD_USD {
// 超过阈值需要向 SEC Nigeria / CBN (Central Bank of Nigeria) 报告
// 约法即是治法:此要求直接来自 Investments and Securities Act 2007 / SEC Nigeria Digital Assets Rules 2022
return tx.aml_reported;
}
true
}
/// 制裁名单检查
fn check_sanctions(tx: &NGTxContext) -> bool {
tx.sanctions_cleared
}
/// 辖区特定规则验证
fn check_jurisdiction_rules(tx: &NGTxContext) -> bool {
// Rule: SEC Nigeria registration required for digital asset platforms
// Rule: BVN (Bank Verification Number) KYC mandatory
// Rule: NGN transactions above NGN 5,000,000 require NFIU reporting
// Rule: EFCC cooperation mandatory
// 禁止匿名交易(宪法即是规则)
!tx.is_anonymous
}
/// 出具宪法收据CR
/// 参与即是共识节点独立出具CR无需多签无需链上投票
fn issue_constitutional_receipt(tx: &NGTxContext) -> String {
format!("CR-{}:{}", JURISDICTION_CODE, tx.tx_hash)
}
}
impl NGJurisdictionPlugin {
/// 主验证入口
pub fn validate(&self, tx: &NGTxContext) -> ValidationResult {
// 1. KYC 验证
if !Self::check_kyc_level(tx) {
return ValidationResult::Rejected {
reason: format!("NG_KYC: Minimum level Enhanced required per {}",
"SEC Nigeria / CBN (Central Bank of Nigeria)"),
jurisdiction: JURISDICTION_CODE.to_string(),
};
}
// 2. AML 阈值检查
if !Self::check_aml_threshold(tx) {
return ValidationResult::Rejected {
reason: format!("NG_AML: Transactions above {} USD require reporting to {}",
AML_THRESHOLD_USD, "SEC Nigeria / CBN (Central Bank of Nigeria)"),
jurisdiction: JURISDICTION_CODE.to_string(),
};
}
// 3. 制裁名单检查
if !Self::check_sanctions(tx) {
return ValidationResult::Rejected {
reason: "NG_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: "NG_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 {
"SEC Nigeria / CBN (Central Bank of Nigeria)"
}
}
#[cfg(test)]
mod tests {
use super::*;
fn make_tx(kyc: KycLevel, amount: f64, anonymous: bool, aml: bool) -> NGTxContext {
NGTxContext {
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_ng_valid_transaction() {
let plugin = NGJurisdictionPlugin::new();
let tx = make_tx(KycLevel::Enhanced, 1000.0, false, false);
assert!(matches!(plugin.validate(&tx), ValidationResult::Approved { .. }));
}
#[test]
fn test_ng_kyc_insufficient() {
let plugin = NGJurisdictionPlugin::new();
let tx = make_tx(KycLevel::None, 1000.0, false, false);
assert!(matches!(plugin.validate(&tx), ValidationResult::Rejected { .. }));
}
#[test]
fn test_ng_aml_threshold_exceeded_unreported() {
let plugin = NGJurisdictionPlugin::new();
let tx = make_tx(KycLevel::Enhanced, 11000.0, false, false);
assert!(matches!(plugin.validate(&tx), ValidationResult::Rejected { .. }));
}
#[test]
fn test_ng_aml_threshold_reported() {
let plugin = NGJurisdictionPlugin::new();
let tx = make_tx(KycLevel::Enhanced, 11000.0, false, true);
assert!(matches!(plugin.validate(&tx), ValidationResult::Approved { .. }));
}
#[test]
fn test_ng_anonymous_rejected() {
let plugin = NGJurisdictionPlugin::new();
let tx = make_tx(KycLevel::Enhanced, 100.0, true, false);
assert!(matches!(plugin.validate(&tx), ValidationResult::Rejected { .. }));
}
#[test]
fn test_ng_jurisdiction_code() {
let plugin = NGJurisdictionPlugin::new();
assert_eq!(plugin.jurisdiction_code(), "NG");
}
#[test]
fn test_ng_regulatory_authority() {
let plugin = NGJurisdictionPlugin::new();
assert!(!plugin.regulatory_authority().is_empty());
}
}