19 KiB
nac-api-server 模块深度分析报告
模块名称: nac-api-server
版本: 1.0.0
分析日期: 2026-02-18
分析人员: NAC开发团队
📋 模块概览
功能定位: NAC公链统一API服务器 - 为钱包和交易所提供后端支持
英文全称: NAC API Server
代码行数: 303行
完成度: 20%
测试覆盖: 5% (1个无关测试)
编译状态: ✅ 通过
运行状态: ⚠️ 仅模拟数据
🏗️ 架构设计
核心功能
nac-api-server是NAC公链的HTTP API服务器,提供两大核心功能:
- 钱包API: 余额查询、转账、交易历史
- 交易所API: 资产列表、订单簿、订单创建、交易历史
技术栈
| 组件 | 技术 | 版本 | 说明 |
|---|---|---|---|
| Web框架 | Axum | 0.7 | 高性能异步Web框架 |
| 运行时 | Tokio | 1.0 | 异步运行时 |
| 序列化 | Serde | 1.0 | JSON序列化/反序列化 |
| 日志 | Tracing | 0.1 | 结构化日志 |
| CORS | Tower-HTTP | 0.5 | 跨域支持 |
目录结构
nac-api-server/
├── Cargo.toml
└── src/
├── main.rs (58行) - 服务器入口和路由配置
├── lib.rs (14行) - 库文件(无实际功能)
├── wallet.rs (93行) - 钱包API实现
└── exchange.rs (138行) - 交易所API实现
📦 依赖关系
[dependencies]
tokio = { version = "1.0", features = ["full"] } # 异步运行时
axum = "0.7" # Web框架
tower = "0.4" # 中间件
tower-http = { version = "0.5", features = ["cors", "trace", "fs"] } # HTTP工具
serde = { version = "1.0", features = ["derive"] } # 序列化
serde_json = "1.0" # JSON序列化
tracing = "0.1" # 日志
tracing-subscriber = { version = "0.3", features = ["env-filter"] } # 日志订阅
anyhow = "1.0" # 错误处理
thiserror = "1.0" # 错误定义
uuid = { version = "1.0", features = ["v4", "serde"] } # UUID生成
chrono = { version = "0.4", features = ["serde"] } # 时间处理
🔍 核心功能详解
1. 服务器入口 (main.rs - 58行)
1.1 主函数
#[tokio::main]
async fn main() {
// 初始化日志
tracing_subscriber::fmt::init();
// 创建路由
let app = Router::new()
.route("/", get(root))
.route("/health", get(health_check))
// 钱包API
.nest("/api/wallet", wallet::routes())
// 交易所API
.nest("/api/exchange", exchange::routes())
// CORS配置
.layer(
CorsLayer::new()
.allow_origin(Any)
.allow_methods(Any)
.allow_headers(Any)
);
// 启动服务器
let addr = "0.0.0.0:8080";
println!("🚀 NAC API服务器启动在 http://{}", addr);
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
axum::serve(listener, app).await.unwrap();
}
路由结构:
/ GET 根路径
/health GET 健康检查
/api/wallet/balance/:address GET 查询余额
/api/wallet/transfer POST 转账
/api/wallet/transactions/:address GET 交易历史
/api/exchange/assets GET 资产列表
/api/exchange/orderbook/:asset GET 订单簿
/api/exchange/orders POST 创建订单
/api/exchange/trades GET 交易历史
1.2 健康检查
async fn health_check() -> Json<HealthResponse> {
Json(HealthResponse {
status: "ok".to_string(),
version: "1.0.0".to_string(),
})
}
#[derive(Serialize)]
struct HealthResponse {
status: String,
version: String,
}
响应示例:
{
"status": "ok",
"version": "1.0.0"
}
2. 钱包API (wallet.rs - 93行)
2.1 余额查询
async fn get_balance(Path(address): Path<String>) -> Json<BalanceResponse> {
// TODO: 实现真实的余额查询
Json(BalanceResponse {
address,
balance: "1000.00".to_string(),
assets: vec![
AssetBalance {
symbol: "XTZH".to_string(),
amount: "1000.00".to_string(),
},
AssetBalance {
symbol: "XIC".to_string(),
amount: "500.00".to_string(),
},
],
})
}
API: GET /api/wallet/balance/:address
响应示例:
{
"address": "nac1...",
"balance": "1000.00",
"assets": [
{
"symbol": "XTZH",
"amount": "1000.00"
},
{
"symbol": "XIC",
"amount": "500.00"
}
]
}
问题: 只返回模拟数据,没有连接实际区块链
2.2 转账
#[derive(Deserialize)]
struct TransferRequest {
from: String,
to: String,
amount: String,
asset: String,
}
async fn transfer(Json(req): Json<TransferRequest>) -> Json<TransferResponse> {
// TODO: 实现真实的转账逻辑
Json(TransferResponse {
tx_hash: "0x1234567890abcdef".to_string(),
status: "pending".to_string(),
})
}
API: POST /api/wallet/transfer
请求示例:
{
"from": "nac1...",
"to": "nac2...",
"amount": "100.00",
"asset": "XTZH"
}
响应示例:
{
"tx_hash": "0x1234567890abcdef",
"status": "pending"
}
问题:
- 没有签名验证
- 没有余额检查
- 没有实际提交交易
2.3 交易历史
async fn get_transactions(Path(address): Path<String>) -> Json<Vec<Transaction>> {
// TODO: 实现真实的交易历史查询
Json(vec![
Transaction {
hash: "0xabc123".to_string(),
from: address.clone(),
to: "nac1...".to_string(),
amount: "100.00".to_string(),
asset: "XTZH".to_string(),
timestamp: 1708012800,
status: "confirmed".to_string(),
},
])
}
API: GET /api/wallet/transactions/:address
响应示例:
[
{
"hash": "0xabc123",
"from": "nac1...",
"to": "nac2...",
"amount": "100.00",
"asset": "XTZH",
"timestamp": 1708012800,
"status": "confirmed"
}
]
3. 交易所API (exchange.rs - 138行)
3.1 资产列表
async fn get_assets() -> Json<Vec<Asset>> {
// TODO: 实现真实的资产列表查询
Json(vec![
Asset {
id: "asset1".to_string(),
name: "房产Token A".to_string(),
symbol: "RWA-A".to_string(),
price: "1000.00".to_string(),
volume_24h: "50000.00".to_string(),
change_24h: "+2.5%".to_string(),
},
Asset {
id: "asset2".to_string(),
name: "艺术品Token B".to_string(),
symbol: "RWA-B".to_string(),
price: "500.00".to_string(),
volume_24h: "30000.00".to_string(),
change_24h: "-1.2%".to_string(),
},
])
}
API: GET /api/exchange/assets
响应示例:
[
{
"id": "asset1",
"name": "房产Token A",
"symbol": "RWA-A",
"price": "1000.00",
"volume_24h": "50000.00",
"change_24h": "+2.5%"
}
]
3.2 订单簿
async fn get_orderbook(Path(asset): Path<String>) -> Json<OrderBook> {
// TODO: 实现真实的订单簿查询
Json(OrderBook {
asset,
bids: vec![
Order {
price: "999.00".to_string(),
amount: "10.00".to_string(),
total: "9990.00".to_string(),
},
],
asks: vec![
Order {
price: "1001.00".to_string(),
amount: "15.00".to_string(),
total: "15015.00".to_string(),
},
],
})
}
API: GET /api/exchange/orderbook/:asset
响应示例:
{
"asset": "RWA-A",
"bids": [
{
"price": "999.00",
"amount": "10.00",
"total": "9990.00"
}
],
"asks": [
{
"price": "1001.00",
"amount": "15.00",
"total": "15015.00"
}
]
}
3.3 创建订单
#[derive(Deserialize)]
struct CreateOrderRequest {
asset: String,
order_type: String, // "buy" or "sell"
price: String,
amount: String,
}
async fn create_order(Json(req): Json<CreateOrderRequest>) -> Json<CreateOrderResponse> {
// TODO: 实现真实的订单创建逻辑
Json(CreateOrderResponse {
order_id: "order123".to_string(),
status: "pending".to_string(),
})
}
API: POST /api/exchange/orders
请求示例:
{
"asset": "RWA-A",
"order_type": "buy",
"price": "1000.00",
"amount": "10.00"
}
响应示例:
{
"order_id": "order123",
"status": "pending"
}
3.4 交易历史
async fn get_trades() -> Json<Vec<Trade>> {
// TODO: 实现真实的交易历史查询
Json(vec![
Trade {
id: "trade1".to_string(),
asset: "RWA-A".to_string(),
price: "1000.00".to_string(),
amount: "5.00".to_string(),
timestamp: 1708012800,
trade_type: "buy".to_string(),
},
])
}
API: GET /api/exchange/trades
响应示例:
[
{
"id": "trade1",
"asset": "RWA-A",
"price": "1000.00",
"amount": "5.00",
"timestamp": 1708012800,
"trade_type": "buy"
}
]
🐛 发现的问题
问题1: 所有API都是模拟数据
严重程度: ⚠️ 极高
描述: 所有API都只返回硬编码的模拟数据,没有连接实际区块链
影响: 无法在生产环境使用
建议: 集成NAC SDK
use nac_sdk::NacClient;
async fn get_balance(Path(address): Path<String>) -> Json<BalanceResponse> {
let client = NacClient::new("http://localhost:8545")?;
let balance = client.get_balance(&address).await?;
Json(BalanceResponse {
address,
balance: balance.to_string(),
assets: client.get_assets(&address).await?,
})
}
状态: ❌ 待实现
问题2: 缺少错误处理
严重程度: ⚠️ 高
描述: 所有函数都没有错误处理,直接返回成功
建议: 使用Result类型
use axum::http::StatusCode;
async fn get_balance(
Path(address): Path<String>
) -> Result<Json<BalanceResponse>, (StatusCode, String)> {
let client = NacClient::new("http://localhost:8545")
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
let balance = client.get_balance(&address).await
.map_err(|e| (StatusCode::BAD_REQUEST, e.to_string()))?;
Ok(Json(BalanceResponse {
address,
balance: balance.to_string(),
assets: vec![],
}))
}
状态: ❌ 待实现
问题3: 缺少身份验证
严重程度: ⚠️ 高
描述: 转账和创建订单等敏感操作没有身份验证
建议: 添加JWT认证
use axum::extract::Extension;
use jsonwebtoken::{decode, DecodingKey, Validation};
#[derive(Deserialize)]
struct Claims {
sub: String,
exp: usize,
}
async fn transfer(
Extension(auth): Extension<Claims>,
Json(req): Json<TransferRequest>
) -> Result<Json<TransferResponse>, (StatusCode, String)> {
// 验证from地址是否属于当前用户
if req.from != auth.sub {
return Err((StatusCode::FORBIDDEN, "Unauthorized".to_string()));
}
// 执行转账
// ...
}
状态: ❌ 待实现
问题4: 缺少输入验证
严重程度: ⚠️ 高
描述: 没有验证输入参数的合法性
建议: 添加验证逻辑
use validator::Validate;
#[derive(Deserialize, Validate)]
struct TransferRequest {
#[validate(length(min = 42, max = 42))]
from: String,
#[validate(length(min = 42, max = 42))]
to: String,
#[validate(range(min = 0.0))]
amount: f64,
#[validate(length(min = 1, max = 10))]
asset: String,
}
async fn transfer(
Json(req): Json<TransferRequest>
) -> Result<Json<TransferResponse>, (StatusCode, String)> {
req.validate()
.map_err(|e| (StatusCode::BAD_REQUEST, e.to_string()))?;
// 执行转账
// ...
}
状态: ❌ 待实现
问题5: 缺少速率限制
严重程度: ⚠️ 中等
描述: 没有速率限制,容易被DDoS攻击
建议: 添加速率限制中间件
use tower_governor::{GovernorLayer, GovernorConfigBuilder};
let governor_conf = Box::new(
GovernorConfigBuilder::default()
.per_second(10)
.burst_size(20)
.finish()
.unwrap()
);
let app = Router::new()
// ...
.layer(GovernorLayer { config: governor_conf });
状态: ❌ 待实现
问题6: CORS配置过于宽松
严重程度: ⚠️ 中等
描述: 允许所有来源、方法和头部,存在安全风险
建议: 限制CORS配置
use tower_http::cors::CorsLayer;
let cors = CorsLayer::new()
.allow_origin("https://wallet.newassetchain.io".parse::<HeaderValue>().unwrap())
.allow_methods([Method::GET, Method::POST])
.allow_headers([CONTENT_TYPE, AUTHORIZATION]);
状态: ❌ 待修复
问题7: 缺少日志记录
严重程度: ⚠️ 低
描述: 虽然初始化了tracing,但没有实际使用
建议: 添加日志
use tracing::{info, warn, error};
async fn transfer(Json(req): Json<TransferRequest>) -> Json<TransferResponse> {
info!("Transfer request: from={}, to={}, amount={}", req.from, req.to, req.amount);
// 执行转账
match execute_transfer(&req).await {
Ok(tx_hash) => {
info!("Transfer successful: tx_hash={}", tx_hash);
Json(TransferResponse { tx_hash, status: "pending".to_string() })
}
Err(e) => {
error!("Transfer failed: {}", e);
// 返回错误
}
}
}
状态: ❌ 待添加
问题8: lib.rs无实际功能
严重程度: ⚠️ 低
描述: lib.rs只有一个add函数,与API服务器无关
建议: 删除或添加实际功能
// lib.rs应该导出共享类型和工具函数
pub mod types;
pub mod utils;
pub mod error;
pub use types::*;
pub use error::ApiError;
状态: ❌ 待修复
问题9: 缺少测试
严重程度: ⚠️ 中等
描述: 只有1个无关的测试,没有API测试
建议: 添加集成测试
#[cfg(test)]
mod tests {
use super::*;
use axum::http::StatusCode;
use tower::ServiceExt;
#[tokio::test]
async fn test_health_check() {
let app = create_app();
let response = app
.oneshot(
Request::builder()
.uri("/health")
.body(Body::empty())
.unwrap()
)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
}
}
状态: ❌ 待添加
问题10: 缺少配置管理
严重程度: ⚠️ 中等
描述: 端口、RPC地址等配置硬编码
建议: 使用配置文件
use config::{Config, File};
#[derive(Deserialize)]
struct AppConfig {
server_addr: String,
rpc_url: String,
jwt_secret: String,
}
fn load_config() -> AppConfig {
let config = Config::builder()
.add_source(File::with_name("config"))
.build()
.unwrap();
config.try_deserialize().unwrap()
}
状态: ❌ 待实现
📊 完成度评估
| 功能模块 | 代码行数 | 完成度 | 状态 |
|---|---|---|---|
| 服务器入口 | 58行 | 80% | ⚠️ 缺少配置 |
| 钱包API | 93行 | 10% | ❌ 仅模拟数据 |
| 交易所API | 138行 | 10% | ❌ 仅模拟数据 |
| 错误处理 | 0行 | 0% | ❌ 未实现 |
| 身份验证 | 0行 | 0% | ❌ 未实现 |
| 测试覆盖 | 14行 | 5% | ❌ 不足 |
| 总计 | 303行 | 20% | 🚧 进行中 |
待完善功能
-
高优先级:
- ❌ 集成NAC SDK(连接实际区块链)
- ❌ 实现错误处理
- ❌ 添加身份验证
- ❌ 添加输入验证
-
中优先级:
- ❌ 添加速率限制
- ❌ 修复CORS配置
- ❌ 添加配置管理
- ❌ 添加集成测试
-
低优先级:
- ⏳ 添加日志记录
- ⏳ 修复lib.rs
- ⏳ 添加API文档
- ⏳ 添加性能监控
🌟 设计亮点
-
模块化路由
- 钱包和交易所API分离
- 易于扩展
-
异步高性能
- 基于Tokio和Axum
- 支持高并发
-
RESTful设计
- 符合REST规范
- 易于理解和使用
-
CORS支持
- 支持跨域请求
- 方便前端集成
🔗 模块依赖关系
nac-api-server
├── 依赖
│ ├── axum (Web框架)
│ ├── tokio (异步运行时)
│ ├── serde (序列化)
│ └── tower-http (中间件)
├── 应该依赖(未实现)
│ ├── nac-sdk (区块链SDK)
│ ├── nac-wallet-core (钱包核心)
│ └── nac-rwa-exchange (RWA交易所)
└── 被依赖
├── nac-vision-wallet (前端钱包)
└── 第三方应用
📝 开发建议
短期目标 (1周)
-
集成NAC SDK (优先级P1)
- 连接NAC节点
- 实现真实的余额查询
- 实现真实的转账
-
实现错误处理 (优先级P1)
- 定义错误类型
- 添加错误处理逻辑
- 返回友好的错误信息
-
添加身份验证 (优先级P1)
- JWT认证
- 签名验证
- 权限检查
中期目标 (2周)
-
添加输入验证 (优先级P2)
- 参数验证
- 地址格式验证
- 金额范围验证
-
添加速率限制 (优先级P2)
- 全局速率限制
- 按IP限制
- 按用户限制
-
添加配置管理 (优先级P2)
- 配置文件
- 环境变量
- 配置热更新
长期目标 (1个月)
-
添加集成测试 (优先级P3)
- API测试
- 性能测试
- 压力测试
-
添加API文档 (优先级P3)
- OpenAPI规范
- Swagger UI
- 示例代码
-
添加监控 (优先级P4)
- Prometheus指标
- 健康检查
- 性能监控
💡 使用示例
启动服务器
cargo run --bin nac-api-server
API调用示例
查询余额
curl http://localhost:8080/api/wallet/balance/nac1...
转账
curl -X POST http://localhost:8080/api/wallet/transfer \
-H "Content-Type: application/json" \
-d '{
"from": "nac1...",
"to": "nac2...",
"amount": "100.00",
"asset": "XTZH"
}'
查询资产列表
curl http://localhost:8080/api/exchange/assets
创建订单
curl -X POST http://localhost:8080/api/exchange/orders \
-H "Content-Type: application/json" \
-d '{
"asset": "RWA-A",
"order_type": "buy",
"price": "1000.00",
"amount": "10.00"
}'
分析完成时间: 2026-02-18
下一步: 集成NAC SDK并实现真实的区块链交互