128 lines
4.5 KiB
Rust
128 lines
4.5 KiB
Rust
//! 区块链集成适配器
|
||
//!
|
||
//! 通过 NAC_Lens 4.0 协议与 NVM(端口 9547)和 CBPP(端口 9545)交互,
|
||
//! 实现资产上链、交易提交和区块查询功能。
|
||
//!
|
||
//! **注意**:本模块使用 NAC 原生技术栈:
|
||
//! - NVM(NAC 虚拟机)而非 EVM
|
||
//! - NAC_Lens 4.0 而非 JSON-RPC
|
||
//! - CBPP(宪政区块生产协议)而非 PoS/PoW
|
||
|
||
use crate::error::{OnboardingError, Result};
|
||
use crate::types::{BlockchainResult, NVMClient, CBPPConsensus};
|
||
use chrono::Utc;
|
||
use tracing::info;
|
||
|
||
/// 区块链集成适配器
|
||
///
|
||
/// 封装与 NVM 和 CBPP 的交互逻辑,提供资产上链的统一接口。
|
||
pub struct BlockchainAdapter {
|
||
/// NVM 客户端(通过 NAC_Lens 4.0 通信)
|
||
nvm_client: NVMClient,
|
||
/// CBPP 共识接口(宪政区块生产协议,非投票制)
|
||
cbpp: CBPPConsensus,
|
||
}
|
||
|
||
impl BlockchainAdapter {
|
||
/// 创建新的区块链适配器
|
||
///
|
||
/// # 参数
|
||
/// - `rpc_url`: NVM 服务端点(默认 `http://localhost:9547`)
|
||
pub fn new(rpc_url: String) -> Result<Self> {
|
||
let nvm_client = NVMClient::new(&rpc_url);
|
||
let cbpp = CBPPConsensus::new();
|
||
Ok(Self { nvm_client, cbpp })
|
||
}
|
||
|
||
/// 提交资产 DNA 和代币地址到区块链
|
||
///
|
||
/// 通过 NVM 执行 Charter 合约,将资产信息永久记录到 NAC 主网。
|
||
pub async fn submit_to_chain(
|
||
&self,
|
||
dna_hash: &str,
|
||
token_address: &str,
|
||
) -> Result<BlockchainResult> {
|
||
info!("开始提交到 NAC 主网: dna={}", dna_hash);
|
||
|
||
// 构建交易数据(NAC 原生格式)
|
||
let tx_data = self.build_transaction_data(dna_hash, token_address)?;
|
||
|
||
// 通过 NVM 部署/调用 Charter 合约
|
||
let tx_hash = self.nvm_client.deploy_contract(&tx_data)
|
||
.await
|
||
.map_err(|e| OnboardingError::BlockchainIntegrationError(
|
||
format!("NVM 合约调用失败: {}", e)
|
||
))?;
|
||
|
||
// 验证宪法收据(CBPP 共识确认)
|
||
let receipt_valid = self.cbpp.submit_receipt(tx_hash.as_bytes())
|
||
.await
|
||
.map_err(|e| OnboardingError::BlockchainIntegrationError(
|
||
format!("CBPP 宪法收据验证失败: {}", e)
|
||
))?;
|
||
|
||
if !receipt_valid {
|
||
return Err(OnboardingError::BlockchainIntegrationError(
|
||
"宪法收据验证未通过".to_string()
|
||
));
|
||
}
|
||
|
||
// 生成区块信息(TODO: 从 CBPP 节点获取实际区块号)
|
||
let block_number = 1_u64;
|
||
let block_hash = format!("BLOCK-HASH-{}", &tx_hash[..8.min(tx_hash.len())]);
|
||
|
||
info!("NAC 主网提交完成: block={}, tx={}", block_number, tx_hash);
|
||
|
||
Ok(BlockchainResult {
|
||
block_number,
|
||
block_hash,
|
||
transaction_hash: tx_hash,
|
||
timestamp: Utc::now(),
|
||
})
|
||
}
|
||
|
||
/// 构建 NAC 原生交易数据
|
||
fn build_transaction_data(&self, dna_hash: &str, token_address: &str) -> Result<Vec<u8>> {
|
||
let mut data = Vec::new();
|
||
// NAC 原生编码:[dna_hash_len(4)] + [dna_hash] + [token_addr_len(4)] + [token_addr]
|
||
let dna_bytes = dna_hash.as_bytes();
|
||
let addr_bytes = token_address.as_bytes();
|
||
data.extend_from_slice(&(dna_bytes.len() as u32).to_be_bytes());
|
||
data.extend_from_slice(dna_bytes);
|
||
data.extend_from_slice(&(addr_bytes.len() as u32).to_be_bytes());
|
||
data.extend_from_slice(addr_bytes);
|
||
Ok(data)
|
||
}
|
||
|
||
/// 查询区块信息
|
||
pub async fn get_block(&self, block_number: u64) -> Result<String> {
|
||
// TODO: 通过 NAC_Lens 4.0 查询 CBPP 节点获取区块信息
|
||
Ok(format!("{{\"block_number\": {}, \"producer\": \"CBP-DID\", \"receipts\": []}}", block_number))
|
||
}
|
||
|
||
/// 查询交易信息
|
||
pub async fn get_transaction(&self, tx_hash: &str) -> Result<String> {
|
||
// TODO: 通过 NAC_Lens 4.0 查询 NVM 获取交易详情
|
||
Ok(format!("{{\"tx_hash\": \"{}\", \"status\": \"confirmed\"}}", tx_hash))
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn test_adapter_creation() {
|
||
let adapter = BlockchainAdapter::new("http://localhost:9547".to_string());
|
||
assert!(adapter.is_ok());
|
||
}
|
||
|
||
#[test]
|
||
fn test_build_transaction_data() {
|
||
let adapter = BlockchainAdapter::new("http://localhost:9547".to_string()).unwrap();
|
||
let data = adapter.build_transaction_data("DNA-HASH-001", "TOKEN-ADDR-001");
|
||
assert!(data.is_ok());
|
||
assert!(!data.unwrap().is_empty());
|
||
}
|
||
}
|