NAC_Blockchain/docs/modules/nac-api-server分析报告.md

19 KiB
Raw Permalink Blame History

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服务器提供两大核心功能

  1. 钱包API: 余额查询、转账、交易历史
  2. 交易所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% 🚧 进行中

待完善功能

  1. 高优先级:

    • 集成NAC SDK连接实际区块链
    • 实现错误处理
    • 添加身份验证
    • 添加输入验证
  2. 中优先级:

    • 添加速率限制
    • 修复CORS配置
    • 添加配置管理
    • 添加集成测试
  3. 低优先级:

    • 添加日志记录
    • 修复lib.rs
    • 添加API文档
    • 添加性能监控

🌟 设计亮点

  1. 模块化路由

    • 钱包和交易所API分离
    • 易于扩展
  2. 异步高性能

    • 基于Tokio和Axum
    • 支持高并发
  3. RESTful设计

    • 符合REST规范
    • 易于理解和使用
  4. CORS支持

    • 支持跨域请求
    • 方便前端集成

🔗 模块依赖关系

nac-api-server
├── 依赖
│   ├── axum (Web框架)
│   ├── tokio (异步运行时)
│   ├── serde (序列化)
│   └── tower-http (中间件)
├── 应该依赖(未实现)
│   ├── nac-sdk (区块链SDK)
│   ├── nac-wallet-core (钱包核心)
│   └── nac-rwa-exchange (RWA交易所)
└── 被依赖
    ├── nac-vision-wallet (前端钱包)
    └── 第三方应用

📝 开发建议

短期目标 (1周)

  1. 集成NAC SDK (优先级P1)

    • 连接NAC节点
    • 实现真实的余额查询
    • 实现真实的转账
  2. 实现错误处理 (优先级P1)

    • 定义错误类型
    • 添加错误处理逻辑
    • 返回友好的错误信息
  3. 添加身份验证 (优先级P1)

    • JWT认证
    • 签名验证
    • 权限检查

中期目标 (2周)

  1. 添加输入验证 (优先级P2)

    • 参数验证
    • 地址格式验证
    • 金额范围验证
  2. 添加速率限制 (优先级P2)

    • 全局速率限制
    • 按IP限制
    • 按用户限制
  3. 添加配置管理 (优先级P2)

    • 配置文件
    • 环境变量
    • 配置热更新

长期目标 (1个月)

  1. 添加集成测试 (优先级P3)

    • API测试
    • 性能测试
    • 压力测试
  2. 添加API文档 (优先级P3)

    • OpenAPI规范
    • Swagger UI
    • 示例代码
  3. 添加监控 (优先级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并实现真实的区块链交互