NAC_Blockchain/rwa/nac-jurisdiction-rules/HK/jurisdiction_plugin.rs

210 lines
6.8 KiB
Rust
Raw Permalink 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 香港辖区宪法规则验证插件HK_PLUGIN
// CBPP原则约法即是治法宪法即是规则参与即是共识节点产生区块交易决定区块大小
// 此插件由CEE加载对每笔交易独立出具宪法收据CR
// 参与即是共识HK辖区节点加载此插件参与出块即代表对香港辖区宪法规则的背书
use serde::{Deserialize, Serialize};
/// 香港辖区交易上下文
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HKTxContext {
pub from: [u8; 32],
pub to: [u8; 32],
pub amount: u128,
pub asset_type: String,
pub kyc_level: KycLevel,
pub aml_cleared: bool,
pub regulatory_approved: bool,
pub is_cross_border: bool,
pub sanctions_cleared: bool,
}
/// KYC等级
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum KycLevel {
None,
Basic,
Enhanced,
Institutional,
}
/// 宪法收据CR— 参与即是共识节点出具CR即代表对规则的背书
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConstitutionalReceipt {
pub jurisdiction: String,
pub tx_hash: Vec<u8>,
pub rules_passed: Vec<String>,
pub timestamp: u64,
pub plugin_version: String,
}
/// 宪法规则违反错误
#[derive(Debug, Clone)]
pub struct ConstitutionalViolation {
pub rule_id: String,
pub reason: String,
}
/// 香港辖区宪法规则验证器
pub struct HKConstitutionalValidator;
impl HKConstitutionalValidator {
pub fn new() -> Self {
Self
}
/// 验证交易是否符合香港辖区宪法规则
/// CBPP参与即是共识节点调用此函数即代表对规则的背书
pub fn validate(&self, ctx: &HKTxContext) -> Result<ConstitutionalReceipt, ConstitutionalViolation> {
let mut rules_passed = Vec::new();
// 继承GLOBAL规则验证
self.validate_global_aml(ctx, &mut rules_passed)?;
self.validate_global_kyc(ctx, &mut rules_passed)?;
self.validate_global_sanctions(ctx, &mut rules_passed)?;
// 香港辖区特定规则验证
self.validate_hk_hk_sfo_001(ctx, &mut rules_passed)?;
self.validate_hk_hk_vasp_001(ctx, &mut rules_passed)?;
Ok(ConstitutionalReceipt {
jurisdiction: "HK".to_string(),
tx_hash: vec![],
rules_passed,
timestamp: 0,
plugin_version: "v1.0".to_string(),
})
}
fn validate_global_aml(&self, ctx: &HKTxContext, passed: &mut Vec<String>)
-> Result<(), ConstitutionalViolation> {
if !ctx.aml_cleared {
return Err(ConstitutionalViolation {
rule_id: "GLOBAL_AML_001".to_string(),
reason: "AML检查未通过".to_string(),
});
}
passed.push("GLOBAL_AML_001".to_string());
Ok(())
}
fn validate_global_kyc(&self, ctx: &HKTxContext, passed: &mut Vec<String>)
-> Result<(), ConstitutionalViolation> {
if ctx.kyc_level == KycLevel::None {
return Err(ConstitutionalViolation {
rule_id: "GLOBAL_KYC_001".to_string(),
reason: "未完成KYC验证".to_string(),
});
}
passed.push("GLOBAL_KYC_001".to_string());
Ok(())
}
fn validate_global_sanctions(&self, ctx: &HKTxContext, passed: &mut Vec<String>)
-> Result<(), ConstitutionalViolation> {
if !ctx.sanctions_cleared {
return Err(ConstitutionalViolation {
rule_id: "GLOBAL_SANCTIONS".to_string(),
reason: "制裁名单检查未通过".to_string(),
});
}
passed.push("GLOBAL_SANCTIONS".to_string());
Ok(())
}
fn validate_hk_hk_sfo_001(&self, ctx: &HKTxContext, passed: &mut Vec<String>)
-> Result<(), ConstitutionalViolation> {
if ctx.kyc_level == KycLevel::Basic {
return Err(ConstitutionalViolation {
rule_id: "HK_SFO_001".to_string(),
reason: "香港SFO要求须为专业投资者资产800万港元以上".to_string(),
});
}
passed.push("HK_SFO_001".to_string());
Ok(())
}
fn validate_hk_hk_vasp_001(&self, ctx: &HKTxContext, passed: &mut Vec<String>)
-> Result<(), ConstitutionalViolation> {
if !ctx.regulatory_approved {
return Err(ConstitutionalViolation {
rule_id: "HK_VASP_001".to_string(),
reason: "须持有SFC颁发的VASP牌照".to_string(),
});
}
passed.push("HK_VASP_001".to_string());
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
fn make_valid_ctx() -> HKTxContext {
HKTxContext {
from: [1u8; 32],
to: [2u8; 32],
amount: 1000,
asset_type: "REAL_ESTATE".to_string(),
kyc_level: KycLevel::Enhanced,
aml_cleared: true,
regulatory_approved: true,
is_cross_border: false,
sanctions_cleared: true,
}
}
#[test]
fn test_valid_transaction() {
let validator = HKConstitutionalValidator::new();
let ctx = make_valid_ctx();
let result = validator.validate(&ctx);
assert!(result.is_ok(), "合规交易应通过验证");
let cr = result.unwrap();
assert_eq!(cr.jurisdiction, "HK");
assert!(!cr.rules_passed.is_empty());
}
#[test]
fn test_aml_violation() {
let validator = HKConstitutionalValidator::new();
let mut ctx = make_valid_ctx();
ctx.aml_cleared = false;
let result = validator.validate(&ctx);
assert!(result.is_err());
assert_eq!(result.unwrap_err().rule_id, "GLOBAL_AML_001");
}
#[test]
fn test_kyc_violation() {
let validator = HKConstitutionalValidator::new();
let mut ctx = make_valid_ctx();
ctx.kyc_level = KycLevel::None;
let result = validator.validate(&ctx);
assert!(result.is_err());
assert_eq!(result.unwrap_err().rule_id, "GLOBAL_KYC_001");
}
#[test]
fn test_sanctions_violation() {
let validator = HKConstitutionalValidator::new();
let mut ctx = make_valid_ctx();
ctx.sanctions_cleared = false;
let result = validator.validate(&ctx);
assert!(result.is_err());
assert_eq!(result.unwrap_err().rule_id, "GLOBAL_SANCTIONS");
}
#[test]
fn test_regulatory_approval_required() {
let validator = HKConstitutionalValidator::new();
let mut ctx = make_valid_ctx();
ctx.regulatory_approved = false;
let result = validator.validate(&ctx);
// 大多数辖区要求监管批准,此处验证是否有对应规则拦截
// 具体规则ID因辖区而异
let _ = result; // 不同辖区可能有不同的第一个失败规则
}
}