342 lines
10 KiB
Rust
342 lines
10 KiB
Rust
// NAC资产一键上链系统 - DNA生成模块
|
||
// 调用nac-sdk的L1协议层适配器生成资产DNA和GNACS编码
|
||
|
||
use chrono::Utc;
|
||
use nac_sdk::adapters::NACAdapter;
|
||
|
||
use crate::error::{OnboardingError, Result};
|
||
use crate::models::{Asset, ComplianceResult, ValuationResult, DNAResult};
|
||
|
||
/// DNA生成服务
|
||
pub struct DNAService {
|
||
adapter: NACAdapter,
|
||
}
|
||
|
||
impl DNAService {
|
||
/// 创建DNA生成服务
|
||
pub fn new(adapter: NACAdapter) -> Self {
|
||
Self { adapter }
|
||
}
|
||
|
||
/// 生成资产DNA
|
||
///
|
||
/// # 参数
|
||
/// - asset: 资产信息
|
||
/// - compliance_result: 合规审批结果
|
||
/// - valuation_result: 估值结果
|
||
///
|
||
/// # 返回
|
||
/// - DNAResult: DNA生成结果
|
||
pub async fn generate_dna(
|
||
&self,
|
||
asset: &Asset,
|
||
compliance_result: &ComplianceResult,
|
||
valuation_result: &ValuationResult
|
||
) -> Result<DNAResult> {
|
||
log::info!("开始生成资产DNA,资产ID: {}", asset.id);
|
||
|
||
// 第1步:生成GNACS编码
|
||
let gnacs_code = self.generate_gnacs_code(
|
||
asset,
|
||
compliance_result,
|
||
valuation_result
|
||
).await?;
|
||
|
||
log::info!("GNACS编码生成成功: {}", gnacs_code);
|
||
|
||
// 第2步:构造资产DNA结构
|
||
let dna_structure = self.create_dna_structure(
|
||
asset,
|
||
&gnacs_code,
|
||
compliance_result,
|
||
valuation_result
|
||
);
|
||
|
||
log::info!("资产DNA结构创建成功");
|
||
|
||
// 第3步:计算DNA哈希
|
||
let dna_hash = self.calculate_dna_hash(&dna_structure).await?;
|
||
|
||
log::info!("DNA哈希计算成功: {}", dna_hash);
|
||
|
||
// 第4步:生成DNA CODE(加密的DNA)
|
||
let dna_code = self.generate_dna_code(&dna_structure, &dna_hash).await?;
|
||
|
||
log::info!("DNA CODE生成成功");
|
||
|
||
// 构造返回结果
|
||
let result = DNAResult {
|
||
gnacs_code,
|
||
dna_hash,
|
||
dna_code,
|
||
timestamp: Utc::now(),
|
||
};
|
||
|
||
Ok(result)
|
||
}
|
||
|
||
/// 生成GNACS编码
|
||
///
|
||
/// # 参数
|
||
/// - asset: 资产信息
|
||
/// - compliance_result: 合规审批结果
|
||
/// - valuation_result: 估值结果
|
||
///
|
||
/// # 返回
|
||
/// - String: 48位GNACS编码
|
||
async fn generate_gnacs_code(
|
||
&self,
|
||
asset: &Asset,
|
||
compliance_result: &ComplianceResult,
|
||
valuation_result: &ValuationResult
|
||
) -> Result<String> {
|
||
log::info!("生成GNACS编码...");
|
||
|
||
// 确定资产类型
|
||
let asset_type = &asset.asset_type;
|
||
|
||
// 根据合规性评分确定风险权重
|
||
let risk_weight = if compliance_result.score >= 0.9 {
|
||
1 // 低风险
|
||
} else if compliance_result.score >= 0.7 {
|
||
2 // 中风险
|
||
} else {
|
||
3 // 高风险
|
||
};
|
||
|
||
// 根据KYC等级确定合规等级
|
||
let compliance_level = asset.kyc_level;
|
||
|
||
log::info!("资产类型: {}, 风险权重: {}, 合规等级: {}", asset_type, risk_weight, compliance_level);
|
||
|
||
// 调用nac-sdk的L1协议层适配器生成GNACS编码
|
||
let gnacs_code = self.adapter.l1()
|
||
.gnacs_encode(
|
||
asset_type.clone(),
|
||
risk_weight,
|
||
compliance_level
|
||
)
|
||
.await
|
||
.map_err(|e| {
|
||
log::error!("GNACS编码生成失败: {}", e);
|
||
OnboardingError::DNAError(format!("GNACS编码生成失败: {}", e))
|
||
})?;
|
||
|
||
// 验证GNACS编码格式(48位)
|
||
if gnacs_code.len() != 48 {
|
||
return Err(OnboardingError::DNAError(
|
||
format!("GNACS编码格式错误: 长度为{},期望48位", gnacs_code.len())
|
||
));
|
||
}
|
||
|
||
Ok(gnacs_code)
|
||
}
|
||
|
||
/// 创建资产DNA结构
|
||
///
|
||
/// # 参数
|
||
/// - asset: 资产信息
|
||
/// - gnacs_code: GNACS编码
|
||
/// - compliance_result: 合规审批结果
|
||
/// - valuation_result: 估值结果
|
||
///
|
||
/// # 返回
|
||
/// - String: DNA结构(JSON字符串)
|
||
fn create_dna_structure(
|
||
&self,
|
||
asset: &Asset,
|
||
gnacs_code: &str,
|
||
compliance_result: &ComplianceResult,
|
||
valuation_result: &ValuationResult
|
||
) -> String {
|
||
log::info!("创建资产DNA结构...");
|
||
|
||
let dna = serde_json::json!({
|
||
"version": "1.0",
|
||
"gnacs_code": gnacs_code,
|
||
"asset": {
|
||
"id": asset.id,
|
||
"type": asset.asset_type,
|
||
"info": asset.asset_info,
|
||
"jurisdiction": asset.jurisdiction
|
||
},
|
||
"compliance": {
|
||
"score": compliance_result.score,
|
||
"result_hash": compliance_result.result_hash,
|
||
"timestamp": compliance_result.timestamp
|
||
},
|
||
"valuation": {
|
||
"value_sdr": valuation_result.value_sdr,
|
||
"result_hash": valuation_result.result_hash,
|
||
"timestamp": valuation_result.timestamp
|
||
},
|
||
"created_at": Utc::now().to_rfc3339()
|
||
});
|
||
|
||
dna.to_string()
|
||
}
|
||
|
||
/// 计算DNA哈希
|
||
///
|
||
/// # 参数
|
||
/// - dna_structure: DNA结构
|
||
///
|
||
/// # 返回
|
||
/// - String: 48字节SHA3-384哈希(十六进制字符串)
|
||
async fn calculate_dna_hash(&self, dna_structure: &str) -> Result<String> {
|
||
log::info!("计算DNA哈希...");
|
||
|
||
// 调用nac-sdk的L0原生层适配器计算SHA3-384哈希
|
||
let dna_hash = self.adapter.l0()
|
||
.hash_sha3_384(dna_structure.as_bytes())
|
||
.map_err(|e| {
|
||
log::error!("DNA哈希计算失败: {}", e);
|
||
OnboardingError::DNAError(format!("DNA哈希计算失败: {}", e))
|
||
})?;
|
||
|
||
// 转换为十六进制字符串
|
||
let dna_hash_hex = hex::encode(dna_hash);
|
||
|
||
Ok(dna_hash_hex)
|
||
}
|
||
|
||
/// 生成DNA CODE(加密的DNA)
|
||
///
|
||
/// # 参数
|
||
/// - dna_structure: DNA结构
|
||
/// - dna_hash: DNA哈希
|
||
///
|
||
/// # 返回
|
||
/// - String: 加密的DNA CODE
|
||
async fn generate_dna_code(&self, dna_structure: &str, dna_hash: &str) -> Result<String> {
|
||
log::info!("生成DNA CODE...");
|
||
|
||
// 使用DNA哈希作为密钥,对DNA结构进行加密
|
||
// 这里使用简单的Base64编码,实际应该使用更安全的加密算法
|
||
let dna_code = base64::encode(dna_structure);
|
||
|
||
Ok(dna_code)
|
||
}
|
||
|
||
/// 解码DNA CODE
|
||
///
|
||
/// # 参数
|
||
/// - dna_code: DNA CODE
|
||
///
|
||
/// # 返回
|
||
/// - String: 解码后的DNA结构
|
||
pub fn decode_dna_code(&self, dna_code: &str) -> Result<String> {
|
||
log::info!("解码DNA CODE...");
|
||
|
||
let dna_structure = base64::decode(dna_code)
|
||
.map_err(|e| OnboardingError::DNAError(format!("DNA CODE解码失败: {}", e)))?;
|
||
|
||
let dna_str = String::from_utf8(dna_structure)
|
||
.map_err(|e| OnboardingError::DNAError(format!("DNA结构转换失败: {}", e)))?;
|
||
|
||
Ok(dna_str)
|
||
}
|
||
|
||
/// 验证GNACS编码
|
||
///
|
||
/// # 参数
|
||
/// - gnacs_code: GNACS编码
|
||
///
|
||
/// # 返回
|
||
/// - bool: 是否验证通过
|
||
pub async fn verify_gnacs_code(&self, gnacs_code: &str) -> Result<bool> {
|
||
log::info!("验证GNACS编码: {}", gnacs_code);
|
||
|
||
// 调用nac-sdk的L1协议层适配器验证GNACS编码
|
||
let verified = self.adapter.l1()
|
||
.gnacs_verify(gnacs_code.to_string())
|
||
.await
|
||
.map_err(|e| {
|
||
log::error!("GNACS编码验证失败: {}", e);
|
||
OnboardingError::DNAError(format!("GNACS编码验证失败: {}", e))
|
||
})?;
|
||
|
||
if verified {
|
||
log::info!("GNACS编码验证通过");
|
||
} else {
|
||
log::warn!("GNACS编码验证失败");
|
||
}
|
||
|
||
Ok(verified)
|
||
}
|
||
|
||
/// 解析GNACS编码
|
||
///
|
||
/// # 参数
|
||
/// - gnacs_code: GNACS编码
|
||
///
|
||
/// # 返回
|
||
/// - (String, i32, i32): (资产类型, 风险权重, 合规等级)
|
||
pub async fn parse_gnacs_code(&self, gnacs_code: &str) -> Result<(String, i32, i32)> {
|
||
log::info!("解析GNACS编码: {}", gnacs_code);
|
||
|
||
// 调用nac-sdk的L1协议层适配器解析GNACS编码
|
||
let decoded = self.adapter.l1()
|
||
.gnacs_decode(gnacs_code.to_string())
|
||
.await
|
||
.map_err(|e| {
|
||
log::error!("GNACS编码解析失败: {}", e);
|
||
OnboardingError::DNAError(format!("GNACS编码解析失败: {}", e))
|
||
})?;
|
||
|
||
Ok((decoded.asset_type, decoded.risk_weight, decoded.compliance_level))
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
use nac_sdk::adapters::config::NACConfig;
|
||
|
||
#[tokio::test]
|
||
async fn test_generate_dna() {
|
||
// 创建测试配置
|
||
let config = NACConfig::default();
|
||
let adapter = NACAdapter::new(&config).await.expect("mainnet: handle error");
|
||
let service = DNAService::new(adapter);
|
||
|
||
// 创建测试数据
|
||
let asset = Asset {
|
||
id: "test-asset-id".to_string(),
|
||
user_id: "test-user-id".to_string(),
|
||
asset_type: "real-estate".to_string(),
|
||
asset_info: serde_json::json!({"name": "测试资产"}),
|
||
legal_docs: serde_json::json!([]),
|
||
kyc_level: 2,
|
||
jurisdiction: "CN".to_string(),
|
||
state: crate::models::OnboardingState::Pending,
|
||
created_at: Utc::now(),
|
||
updated_at: Utc::now(),
|
||
};
|
||
|
||
let compliance_result = ComplianceResult {
|
||
score: 0.85,
|
||
result_hash: "test-compliance-hash".to_string(),
|
||
proof_data: "test-proof".to_string(),
|
||
timestamp: Utc::now(),
|
||
};
|
||
|
||
let valuation_result = ValuationResult {
|
||
value_sdr: 1000000.0,
|
||
result_hash: "test-valuation-hash".to_string(),
|
||
model_params: serde_json::json!({}),
|
||
timestamp: Utc::now(),
|
||
};
|
||
|
||
// 执行DNA生成
|
||
let result = service.generate_dna(&asset, &compliance_result, &valuation_result).await;
|
||
|
||
// 验证结果
|
||
assert!(result.is_ok());
|
||
let dna_result = result.expect("mainnet: handle error");
|
||
assert_eq!(dna_result.gnacs_code.len(), 48);
|
||
assert!(!dna_result.dna_hash.is_empty());
|
||
assert!(!dna_result.dna_code.is_empty());
|
||
}
|
||
}
|