// NAC宪法层服务 (nac-constitution-service) v1.0.0 // Constitutional Layer HTTP Service // // 严格遵循 NAC 原生类型系统: // - Address:32字节(256位) // - Hash:48字节(SHA3-384,384位) // - 支持8组二进制字符串转换 // // 宪法层是 NAC 公链的核心基础层,所有交易和合约必须通过宪法验证 // Chain ID: 5132611 use actix_web::{web, App, HttpServer, HttpResponse}; use actix_web::dev::{ServiceRequest, ServiceResponse, Service, Transform}; use actix_web::Error; use futures_util::future::{ok, Ready, LocalBoxFuture}; use serde::{Deserialize, Serialize}; use chrono::Utc; use std::env; use std::sync::Arc; use parking_lot::RwLock; use uuid::Uuid; // 使用 NAC 原生类型 use nac_udm::primitives::{Address, Hash}; // ============================================================ // NAC 原生类型包装(用于 HTTP API 序列化) // ============================================================ /// NAC Address 的 JSON 表示(32字节,hex 编码) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NacAddress { /// 十六进制表示(64个字符,不含0x前缀) pub hex: String, /// 二进制字符串表示(256位,8组×32字节) pub binary: String, /// 字节长度(固定32) pub byte_length: u8, } impl NacAddress { /// 从 Address 创建 pub fn from_address(addr: &Address) -> Self { Self { hex: addr.to_hex().trim_start_matches("0x").to_string(), binary: addr.to_binary_string(), byte_length: 32, } } /// 从 hex 字符串解析 pub fn from_hex(hex_str: &str) -> Result { let addr = Address::from_hex(hex_str)?; Ok(Self::from_address(&addr)) } /// 从二进制字符串解析(8组×32字节×8位 = 256位) pub fn from_binary(binary_str: &str) -> Result { let addr = Address::from_binary_string(binary_str)?; Ok(Self::from_address(&addr)) } } /// NAC Hash 的 JSON 表示(48字节,SHA3-384) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NacHash { /// 十六进制表示(96个字符,不含0x前缀) pub hex: String, /// 二进制字符串表示(384位,8组×48字节) pub binary: String, /// 字节长度(固定48) pub byte_length: u8, /// 哈希算法 pub algorithm: String, } impl NacHash { /// 从 Hash 创建 pub fn from_hash(hash: &Hash) -> Self { Self { hex: hash.to_hex().trim_start_matches("0x").to_string(), binary: hash.to_binary_string(), byte_length: 48, algorithm: "SHA3-384".to_string(), } } /// 计算数据的 SHA3-384 哈希 pub fn sha3_384(data: &[u8]) -> Self { let hash = Hash::sha3_384(data); Self::from_hash(&hash) } } // ============================================================ // 宪法层核心数据结构 // ============================================================ /// 宪法状态 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConstitutionState { /// 当前宪法版本 pub current_version: u64, /// 宪法哈希(NAC Hash 48字节 SHA3-384) pub constitution_hash: NacHash, /// 当前纪元 pub current_epoch: u64, /// 当前区块高度 pub current_height: u64, /// 共识参数 pub gas_limit: u64, /// 最小出块间隔(毫秒) pub delta_t_min: u64, /// 最大出块间隔(毫秒) pub delta_t_max: u64, /// 目标区块利用率 pub target_utilization: f64, /// 宪法层状态 pub layer_status: String, /// 验证器数量 pub validator_count: u64, /// Chain ID pub chain_id: u64, /// 最后更新时间 pub last_updated: String, } /// 宪法验证请求 #[derive(Debug, Deserialize)] pub struct ConstitutionValidationRequest { /// 交易哈希(hex,48字节 SHA3-384) pub tx_hash: Option, /// 发送方地址(hex,32字节) pub sender: Option, /// 接收方地址(hex,32字节) pub receiver: Option, /// 交易金额 pub amount: Option, /// 合约字节码(hex) pub contract_bytecode: Option, /// 验证类型:transaction / contract / governance / rwa_asset pub validation_type: String, /// 额外数据 pub extra_data: Option, } /// 宪法原则检查结果 #[derive(Debug, Serialize)] pub struct PrincipleCheckResult { /// 原则编号(1-7) pub principle_id: u8, /// 原则名称 pub principle_name: String, /// 是否通过 pub passed: bool, /// 详情 pub detail: String, } /// 宪法验证结果 #[derive(Debug, Serialize)] pub struct ConstitutionValidationResult { /// 是否通过宪法验证 pub valid: bool, /// 验证 ID(UUID) pub validation_id: String, /// 宪法原则检查结果(7条) pub principles: Vec, /// 违规详情 pub violations: Vec, /// 建议 pub recommendations: Vec, /// 验证耗时(毫秒) pub elapsed_ms: u64, /// 时间戳 pub timestamp: String, } /// 宪法收据(ConstitutionalReceipt) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConstitutionalReceipt { /// 收据 ID(格式:CR-{UUID}) pub receipt_id: String, /// 关联交易哈希(NAC Hash,48字节) pub tx_hash: String, /// 宪法版本 pub constitution_version: u64, /// 宪法哈希(NAC Hash,48字节 SHA3-384) pub constitution_hash: NacHash, /// 验证结果 pub validation_passed: bool, /// 通过的宪法原则编号 pub passed_principles: Vec, /// 区块高度 pub block_height: u64, /// 纪元 pub epoch: u64, /// 生成时间戳(Unix 毫秒) pub timestamp: u64, /// 收据签名(NAC Hash,48字节 SHA3-384) pub signature: NacHash, /// 有效期(区块高度) pub expiry_height: u64, /// Chain ID pub chain_id: u64, } /// 宪法收据生成请求 #[derive(Debug, Deserialize)] pub struct ReceiptGenerationRequest { /// 交易哈希(hex,48字节) pub tx_hash: String, /// 验证 ID(可选) pub validation_id: Option, } /// 二进制字符串转换请求 #[derive(Debug, Deserialize)] pub struct BinaryConversionRequest { /// 输入值(hex 或 binary) pub value: String, /// 输入格式:hex / binary pub input_format: String, /// 类型:address(32字节)/ hash(48字节) pub data_type: String, } // ============================================================ // 宪法层全局状态 // ============================================================ #[derive(Debug)] pub struct ConstitutionLayerState { pub version: u64, pub constitution_hash: Hash, pub epoch: u64, pub height: u64, pub gas_limit: u64, pub delta_t_min: u64, pub delta_t_max: u64, pub target_utilization: f64, pub validator_count: u64, pub receipts: Vec, } impl Default for ConstitutionLayerState { fn default() -> Self { // 使用 NAC 原生 Hash::sha3_384 计算创世宪法哈希 let genesis_data = b"NAC Constitutional Layer v1.0 - NewAssetChain MainNet Genesis - Chain-ID-5132611 - CBPP-Constitutional-Block-Production-Protocol"; let constitution_hash = Hash::sha3_384(genesis_data); Self { version: 1, constitution_hash, epoch: 1, height: 0, gas_limit: 30_000_000, delta_t_min: 100, delta_t_max: 2000, target_utilization: 0.75, validator_count: 21, receipts: Vec::new(), } } } type SharedState = Arc>; // ============================================================ // NAC 宪法七大原则验证 // ============================================================ fn check_constitutional_principles(req: &ConstitutionValidationRequest) -> Vec { let mut results = Vec::new(); // 原则1:主权完整性原则 — 发送方地址必须是合法的 NAC Address(32字节) let p1_passed = if let Some(sender) = &req.sender { let hex = sender.trim_start_matches("0x"); // Address 32字节 = 64个十六进制字符 hex.len() == 64 && hex.chars().all(|c| c.is_ascii_hexdigit()) } else { false }; results.push(PrincipleCheckResult { principle_id: 1, principle_name: "主权完整性原则".to_string(), passed: p1_passed, detail: if p1_passed { "发送方地址合法(NAC Address,32字节,256位)".to_string() } else { "发送方地址缺失或不合法(需要32字节/64位十六进制)".to_string() }, }); // 原则2:资产真实性原则 — 金额必须为正数 let p2_passed = match req.validation_type.as_str() { "transaction" => req.amount.map(|a| a > 0).unwrap_or(false), _ => true, }; results.push(PrincipleCheckResult { principle_id: 2, principle_name: "资产真实性原则".to_string(), passed: p2_passed, detail: if p2_passed { "交易金额合法(大于零)".to_string() } else { "交易金额必须大于零".to_string() }, }); // 原则3:合规验证原则 — 合约字节码不能为空 let p3_passed = match req.validation_type.as_str() { "contract" => req.contract_bytecode.as_ref() .map(|b| !b.is_empty() && b.len() >= 2) .unwrap_or(false), _ => true, }; results.push(PrincipleCheckResult { principle_id: 3, principle_name: "合规验证原则".to_string(), passed: p3_passed, detail: if p3_passed { "合约字节码格式合法".to_string() } else { "合约字节码不能为空".to_string() }, }); // 原则4:区块序列原则 — 由 CBPP 节点保证 results.push(PrincipleCheckResult { principle_id: 4, principle_name: "区块序列原则(CBPP原则4)".to_string(), passed: true, detail: "由 CBPP 节点保证,节点序列 ≤ 最新区块高度".to_string(), }); // 原则5:宪法不可绕过原则 — 本次验证即为强制检查 results.push(PrincipleCheckResult { principle_id: 5, principle_name: "宪法不可绕过原则".to_string(), passed: true, detail: "宪法层强制验证,不可绕过".to_string(), }); // 原则6:去中心化治理原则 — 治理提案必须有合法类型 let p6_passed = match req.validation_type.as_str() { "governance" => req.extra_data.as_ref() .map(|d| d.get("proposal_type").is_some()) .unwrap_or(false), _ => true, }; results.push(PrincipleCheckResult { principle_id: 6, principle_name: "去中心化治理原则".to_string(), passed: p6_passed, detail: if p6_passed { "治理提案格式合法".to_string() } else { "治理提案必须包含 proposal_type 字段".to_string() }, }); // 原则7:RWA 资产合规原则 — RWA 资产必须有 GNACS 分类码 let p7_passed = match req.validation_type.as_str() { "rwa_asset" => req.extra_data.as_ref() .map(|d| d.get("gnacs_code").is_some()) .unwrap_or(false), _ => true, }; results.push(PrincipleCheckResult { principle_id: 7, principle_name: "RWA资产合规原则(GNACS分类)".to_string(), passed: p7_passed, detail: if p7_passed { "RWA资产包含合法的 GNACS 分类码".to_string() } else { "RWA资产必须包含 gnacs_code 字段".to_string() }, }); results } // ============================================================ // Token 认证中间件 (FIX-007) // ============================================================ /// Token 认证中间件工厂 /// 所有 API 端点(除 /health 外)均需要 Bearer Token 认证 pub struct BearerAuth { pub token: Arc, } impl BearerAuth { pub fn new(token: String) -> Self { Self { token: Arc::new(token) } } } impl Transform for BearerAuth where S: Service, Error = Error> + 'static, B: 'static, { type Response = ServiceResponse; type Error = Error; type InitError = (); type Transform = BearerAuthMiddleware; type Future = Ready>; fn new_transform(&self, service: S) -> Self::Future { ok(BearerAuthMiddleware { service: Arc::new(service), token: self.token.clone(), }) } } /// Token 认证中间件实例 pub struct BearerAuthMiddleware { service: Arc, token: Arc, } impl Service for BearerAuthMiddleware where S: Service, Error = Error> + 'static, B: 'static, { type Response = ServiceResponse; type Error = Error; type Future = LocalBoxFuture<'static, Result>; fn poll_ready( &self, cx: &mut std::task::Context<'_>, ) -> std::task::Poll> { self.service.poll_ready(cx) } fn call(&self, req: ServiceRequest) -> Self::Future { // /health 端点无需认证(供监控系统使用) if req.path() == "/health" { let svc = self.service.clone(); return Box::pin(async move { svc.call(req).await }); } let token = self.token.clone(); let svc = self.service.clone(); Box::pin(async move { // 提取 Authorization 头 let auth_header = req .headers() .get("Authorization") .and_then(|v| v.to_str().ok()) .unwrap_or(""); // 验证 Bearer Token let provided = auth_header.strip_prefix("Bearer ").unwrap_or(""); if provided != token.as_str() { log::warn!( "宪法层 API 认证失败: path={} remote={:?}", req.path(), req.peer_addr() ); return Err(actix_web::error::ErrorUnauthorized( serde_json::json!({ "success": false, "error": "Unauthorized: valid Bearer token required", "code": 401 }).to_string() )); } svc.call(req).await }) } } // ============================================================ // HTTP 处理器 // ============================================================ /// 健康检查 async fn health(state: web::Data) -> HttpResponse { let s = state.read(); HttpResponse::Ok().json(serde_json::json!({ "status": "running", "service": "nac-constitution-service", "version": "1.0.0", "layer": "Constitutional Layer", "protocol": "CBPP", "chain_id": 5132611u64, "type_system": { "address": "32 bytes (256-bit)", "hash": "48 bytes (SHA3-384, 384-bit)", "binary_groups": 8 }, "constitution_version": s.version, "constitution_hash_hex": s.constitution_hash.to_hex(), "constitution_hash_binary_length": s.constitution_hash.to_binary_string().replace(" ", "").len(), "current_epoch": s.epoch, "timestamp": Utc::now().to_rfc3339() })) } /// 获取宪法状态 async fn get_constitution_state(state: web::Data) -> HttpResponse { let s = state.read(); HttpResponse::Ok().json(ConstitutionState { current_version: s.version, constitution_hash: NacHash::from_hash(&s.constitution_hash), current_epoch: s.epoch, current_height: s.height, gas_limit: s.gas_limit, delta_t_min: s.delta_t_min, delta_t_max: s.delta_t_max, target_utilization: s.target_utilization, layer_status: "active".to_string(), validator_count: s.validator_count, chain_id: 5132611, last_updated: Utc::now().to_rfc3339(), }) } /// 宪法合规验证 async fn validate( req: web::Json, ) -> HttpResponse { let start = std::time::Instant::now(); let validation_id = Uuid::new_v4().to_string(); log::info!("宪法验证请求 | 类型: {} | ID: {}", req.validation_type, validation_id); let principles = check_constitutional_principles(&req); let violations: Vec = principles.iter() .filter(|p| !p.passed) .map(|p| format!("原则{}: {} — {}", p.principle_id, p.principle_name, p.detail)) .collect(); let valid = violations.is_empty(); let elapsed = start.elapsed().as_millis() as u64; let recommendations = if !valid { violations.iter().map(|v| format!("请修正: {}", v)).collect() } else { vec!["全部7条宪法原则验证通过,可生成宪法收据".to_string()] }; if valid { log::info!("宪法验证通过 | ID: {} | 耗时: {}ms", validation_id, elapsed); } else { log::warn!("宪法验证失败 | ID: {} | 违规数: {}", validation_id, violations.len()); } HttpResponse::Ok().json(ConstitutionValidationResult { valid, validation_id, principles, violations, recommendations, elapsed_ms: elapsed, timestamp: Utc::now().to_rfc3339(), }) } /// 生成宪法收据 async fn generate_receipt( req: web::Json, state: web::Data, ) -> HttpResponse { let s = state.read(); let receipt_id = format!("CR-{}", Uuid::new_v4().to_string().replace("-", "").to_uppercase()); // 使用 NAC 原生 Hash::sha3_384 生成收据签名 let mut sig_data = Vec::new(); sig_data.extend_from_slice(receipt_id.as_bytes()); sig_data.extend_from_slice(req.tx_hash.as_bytes()); sig_data.extend_from_slice(s.constitution_hash.as_bytes()); sig_data.extend_from_slice(&s.epoch.to_le_bytes()); sig_data.extend_from_slice(&s.height.to_le_bytes()); let signature_hash = Hash::sha3_384(&sig_data); let now_ts = Utc::now().timestamp_millis() as u64; let expiry_height = s.height + 1000; let receipt = ConstitutionalReceipt { receipt_id: receipt_id.clone(), tx_hash: req.tx_hash.clone(), constitution_version: s.version, constitution_hash: NacHash::from_hash(&s.constitution_hash), validation_passed: true, passed_principles: vec![1, 2, 3, 4, 5, 6, 7], block_height: s.height, epoch: s.epoch, timestamp: now_ts, signature: NacHash::from_hash(&signature_hash), expiry_height, chain_id: 5132611, }; drop(s); state.write().receipts.push(receipt.clone()); log::info!("宪法收据已生成 | ID: {} | 交易: {} | 有效期至区块: {}", receipt_id, req.tx_hash, expiry_height); HttpResponse::Ok().json(serde_json::json!({ "success": true, "receipt": receipt, "message": format!("宪法收据已生成,有效期至区块高度 {}", expiry_height) })) } /// 查询宪法收据 async fn get_receipt( path: web::Path, state: web::Data, ) -> HttpResponse { let receipt_id = path.into_inner(); let s = state.read(); match s.receipts.iter().find(|r| r.receipt_id == receipt_id) { Some(receipt) => { let expired = receipt.expiry_height < s.height; HttpResponse::Ok().json(serde_json::json!({ "found": true, "receipt": receipt, "expired": expired, "current_height": s.height })) } None => HttpResponse::NotFound().json(serde_json::json!({ "found": false, "receipt_id": receipt_id, "message": "宪法收据不存在" })) } } /// 获取宪法参数 async fn get_params(state: web::Data) -> HttpResponse { let s = state.read(); let hash = NacHash::from_hash(&s.constitution_hash); HttpResponse::Ok().json(serde_json::json!({ "constitution_version": s.version, "constitution_hash": hash, "epoch": s.epoch, "gas_limit": s.gas_limit, "gas_limit_min": 1_000_000u64, "gas_limit_max": 100_000_000u64, "delta_t_min_ms": s.delta_t_min, "delta_t_max_ms": s.delta_t_max, "target_utilization": s.target_utilization, "adjust_factor": 0.125, "validator_count": s.validator_count, "type_system": { "address_bytes": 32, "hash_bytes": 48, "hash_algorithm": "SHA3-384", "binary_groups": 8, "address_bits": 256, "hash_bits": 384 }, "cbpp_principles": [ {"id": 1, "name": "主权完整性原则"}, {"id": 2, "name": "资产真实性原则"}, {"id": 3, "name": "合规验证原则"}, {"id": 4, "name": "区块序列原则"}, {"id": 5, "name": "宪法不可绕过原则"}, {"id": 6, "name": "去中心化治理原则"}, {"id": 7, "name": "RWA资产合规原则"} ], "timestamp": Utc::now().to_rfc3339() })) } /// NAC 类型系统二进制字符串转换工具 async fn convert_binary(req: web::Json) -> HttpResponse { match req.data_type.as_str() { "address" => { match req.input_format.as_str() { "hex" => { match NacAddress::from_hex(&req.value) { Ok(addr) => HttpResponse::Ok().json(serde_json::json!({ "success": true, "data_type": "address", "byte_length": 32, "bit_length": 256, "hex": addr.hex, "binary": addr.binary, "binary_length": addr.binary.replace(" ", "").len() })), Err(e) => HttpResponse::BadRequest().json(serde_json::json!({ "success": false, "error": e })) } } "binary" => { match NacAddress::from_binary(&req.value) { Ok(addr) => HttpResponse::Ok().json(serde_json::json!({ "success": true, "data_type": "address", "byte_length": 32, "bit_length": 256, "hex": addr.hex, "binary": addr.binary })), Err(e) => HttpResponse::BadRequest().json(serde_json::json!({ "success": false, "error": e })) } } _ => HttpResponse::BadRequest().json(serde_json::json!({ "success": false, "error": "input_format 必须为 hex 或 binary" })) } } "hash" => { match req.input_format.as_str() { "hex" => { match Hash::from_hex(&req.value) { Ok(hash) => { let nac_hash = NacHash::from_hash(&hash); HttpResponse::Ok().json(serde_json::json!({ "success": true, "data_type": "hash", "algorithm": "SHA3-384", "byte_length": 48, "bit_length": 384, "hex": nac_hash.hex, "binary": nac_hash.binary, "binary_length": nac_hash.binary.replace(" ", "").len() })) } Err(e) => HttpResponse::BadRequest().json(serde_json::json!({ "success": false, "error": e })) } } "binary" => { match Hash::from_binary_string(&req.value) { Ok(hash) => { let nac_hash = NacHash::from_hash(&hash); HttpResponse::Ok().json(serde_json::json!({ "success": true, "data_type": "hash", "algorithm": "SHA3-384", "byte_length": 48, "bit_length": 384, "hex": nac_hash.hex, "binary": nac_hash.binary })) } Err(e) => HttpResponse::BadRequest().json(serde_json::json!({ "success": false, "error": e })) } } "data" => { // 直接计算任意数据的 SHA3-384 哈希 let nac_hash = NacHash::sha3_384(req.value.as_bytes()); HttpResponse::Ok().json(serde_json::json!({ "success": true, "data_type": "hash", "algorithm": "SHA3-384", "byte_length": 48, "bit_length": 384, "input": req.value, "hex": nac_hash.hex, "binary": nac_hash.binary, "binary_length": nac_hash.binary.replace(" ", "").len() })) } _ => HttpResponse::BadRequest().json(serde_json::json!({ "success": false, "error": "input_format 必须为 hex、binary 或 data" })) } } _ => HttpResponse::BadRequest().json(serde_json::json!({ "success": false, "error": "data_type 必须为 address 或 hash" })) } } /// 宪法层统计信息 async fn get_stats(state: web::Data) -> HttpResponse { let s = state.read(); HttpResponse::Ok().json(serde_json::json!({ "service": "nac-constitution-service", "layer": "Constitutional Layer", "chain_id": 5132611u64, "constitution_version": s.version, "current_epoch": s.epoch, "current_height": s.height, "total_receipts_generated": s.receipts.len(), "active_receipts": s.receipts.iter().filter(|r| r.expiry_height >= s.height).count(), "expired_receipts": s.receipts.iter().filter(|r| r.expiry_height < s.height).count(), "validator_count": s.validator_count, "type_system": { "address_bytes": 32, "hash_bytes": 48, "hash_algorithm": "SHA3-384", "binary_groups": 8 }, "timestamp": Utc::now().to_rfc3339() })) } // ============================================================ // 主入口 // ============================================================ #[actix_web::main] async fn main() -> std::io::Result<()> { env_logger::init_from_env(env_logger::Env::default().default_filter_or("info")); let host = env::var("CONSTITUTION_HOST").unwrap_or_else(|_| "0.0.0.0".to_string()); let port: u16 = env::var("CONSTITUTION_PORT") .unwrap_or_else(|_| "9548".to_string()) .parse() .unwrap_or(9548); log::info!("╔══════════════════════════════════════════════════════╗"); log::info!("║ NAC 宪法层服务 (Constitutional Layer) ║"); log::info!("║ nac-constitution-service v1.0.0 ║"); log::info!("║ NAC 公链 Chain ID: 5132611 ║"); log::info!("║ 类型系统: Address 32B / Hash 48B (SHA3-384) ║"); log::info!("╚══════════════════════════════════════════════════════╝"); log::info!("监听地址: {}:{}", host, port); let state: SharedState = Arc::new(RwLock::new(ConstitutionLayerState::default())); { let s = state.read(); log::info!("宪法层初始化完成"); log::info!("创世宪法哈希 (SHA3-384, 48B): {}", s.constitution_hash.to_hex()); log::info!("二进制长度: {} 位", s.constitution_hash.to_binary_string().replace(" ", "").len()); } let state_data = web::Data::new(state); // FIX-007: 读取 API Token(从环境变量 CONSTITUTION_API_TOKEN) let api_token = env::var("CONSTITUTION_API_TOKEN").unwrap_or_else(|_| { // 若未设置,生成随机 token 并打印到日志(主网运维必须配置此变量) let random_token = format!("nac-const-{}", Uuid::new_v4().to_string().replace("-", "")); log::warn!("CONSTITUTION_API_TOKEN 未设置,已生成临时 Token: {}", random_token); log::warn!("主网运维:请在 systemd 服务中设置 CONSTITUTION_API_TOKEN 环境变量!"); random_token }); log::info!("宪法层 API Token 认证已启用 (FIX-007)"); let api_token = Arc::new(api_token); HttpServer::new(move || { let token = api_token.as_ref().clone(); App::new() .app_data(state_data.clone()) .wrap(BearerAuth::new(token)) // 健康检查 .route("/health", web::get().to(health)) // 宪法状态 .route("/state", web::get().to(get_constitution_state)) // 宪法验证(七大原则) .route("/validate", web::post().to(validate)) // 宪法收据 .route("/receipt/generate", web::post().to(generate_receipt)) .route("/receipt/{receipt_id}", web::get().to(get_receipt)) // 宪法参数 .route("/params", web::get().to(get_params)) // NAC 类型系统工具(Address 32B / Hash 48B 二进制转换) .route("/types/convert", web::post().to(convert_binary)) // 统计信息 .route("/stats", web::get().to(get_stats)) }) .bind(format!("{}:{}", host, port))? .run() .await }