NAC_Blockchain/nac-acc-service/src/main.rs

243 lines
9.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// nac-acc-service — NAC ACC 协议族服务L1层端口9551
use actix_web::{web, App, HttpServer, HttpResponse};
use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use chrono::Utc;
use uuid::Uuid;
use sha3::{Sha3_384, Digest};
use tracing::info;
const CHAIN_ID: u64 = 5132611;
const SERVICE_VERSION: &str = "1.0.0";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TokenRecord {
pub token_id: String,
pub protocol: String,
pub gnacs_code: String,
pub holder: String,
pub amount: u128,
pub metadata: serde_json::Value,
pub minted_at: i64,
pub status: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransferRecord {
pub transfer_id: String,
pub protocol: String,
pub from: String,
pub to: String,
pub amount: u128,
pub tx_hash: String,
pub timestamp: i64,
pub constitution_verified: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AccState {
pub tokens: HashMap<String, TokenRecord>,
pub transfers: Vec<TransferRecord>,
pub total_minted: u64,
pub total_transfers: u64,
pub started_at: i64,
}
type SharedState = Arc<Mutex<AccState>>;
#[derive(Debug, Deserialize)]
pub struct MintReq {
pub protocol: String,
pub gnacs_code: String,
pub holder: String,
pub amount: u128,
pub metadata: Option<serde_json::Value>,
}
#[derive(Debug, Deserialize)]
pub struct TransferReq {
pub protocol: String,
pub from: String,
pub to: String,
pub token_id: String,
pub amount: u128,
}
#[derive(Debug, Deserialize)]
pub struct BurnReq {
pub token_id: String,
pub holder: String,
pub amount: u128,
}
fn sha3_384_hex(data: &[u8]) -> String {
let mut h = Sha3_384::new(); h.update(data); hex::encode(h.finalize())
}
fn validate_address(addr: &str) -> bool {
addr.len() == 64 && addr.chars().all(|c| c.is_ascii_hexdigit())
}
async fn health(state: web::Data<SharedState>) -> HttpResponse {
let s = state.lock().unwrap();
HttpResponse::Ok().json(serde_json::json!({
"status": "healthy", "service": "nac-acc-service",
"version": SERVICE_VERSION, "chain_id": CHAIN_ID,
"tokens": s.tokens.len(), "total_transfers": s.total_transfers,
"type_system": {"address_bytes": 32, "hash_bytes": 48, "hash_algorithm": "SHA3-384"},
"supported_protocols": 19,
"timestamp": Utc::now().to_rfc3339()
}))
}
async fn get_state(state: web::Data<SharedState>) -> HttpResponse {
let s = state.lock().unwrap();
HttpResponse::Ok().json(serde_json::json!({
"chain_id": CHAIN_ID, "service_version": SERVICE_VERSION,
"tokens": s.tokens.len(), "total_minted": s.total_minted,
"total_transfers": s.total_transfers,
"uptime_ms": Utc::now().timestamp_millis() - s.started_at,
"timestamp": Utc::now().to_rfc3339()
}))
}
async fn mint_token(state: web::Data<SharedState>, req: web::Json<MintReq>) -> HttpResponse {
if !validate_address(&req.holder) {
return HttpResponse::BadRequest().json(serde_json::json!({
"success": false, "error": "holder 必须为 NAC Address32字节64个十六进制字符"
}));
}
if req.amount == 0 {
return HttpResponse::BadRequest().json(serde_json::json!({
"success": false, "error": "amount 必须大于 0宪法原则2资产真实性原则"
}));
}
let mut s = state.lock().unwrap();
let token_id = format!("TOKEN-{}", &Uuid::new_v4().to_string()[..12].to_uppercase());
let hash_input = format!("{}:{}:{}:{}", req.protocol, req.holder, req.amount, Utc::now().timestamp_millis());
let token_hash = sha3_384_hex(hash_input.as_bytes());
s.tokens.insert(token_id.clone(), TokenRecord {
token_id: token_id.clone(), protocol: req.protocol.clone(),
gnacs_code: req.gnacs_code.clone(), holder: req.holder.clone(),
amount: req.amount, metadata: req.metadata.clone().unwrap_or(serde_json::json!({})),
minted_at: Utc::now().timestamp_millis(), status: "active".to_string(),
});
s.total_minted += 1;
HttpResponse::Ok().json(serde_json::json!({
"success": true, "token_id": token_id,
"token_hash": {"hex": token_hash, "algorithm": "SHA3-384", "byte_length": 48},
"protocol": req.protocol, "gnacs_code": req.gnacs_code,
"holder": req.holder, "amount": req.amount.to_string(),
"constitution_verified": true,
"timestamp": Utc::now().to_rfc3339()
}))
}
async fn transfer_token(state: web::Data<SharedState>, req: web::Json<TransferReq>) -> HttpResponse {
if !validate_address(&req.from) || !validate_address(&req.to) {
return HttpResponse::BadRequest().json(serde_json::json!({
"success": false, "error": "from/to 必须为 NAC Address32字节64个十六进制字符"
}));
}
let mut s = state.lock().unwrap();
if !s.tokens.contains_key(&req.token_id) {
return HttpResponse::NotFound().json(serde_json::json!({
"success": false, "error": format!("Token {} 不存在", req.token_id)
}));
}
let tx_input = format!("{}:{}:{}:{}:{}", req.from, req.to, req.token_id, req.amount, Utc::now().timestamp_millis());
let tx_hash = sha3_384_hex(tx_input.as_bytes());
let transfer_id = format!("TX-{}", &Uuid::new_v4().to_string()[..12].to_uppercase());
s.transfers.push(TransferRecord {
transfer_id: transfer_id.clone(), protocol: req.protocol.clone(),
from: req.from.clone(), to: req.to.clone(), amount: req.amount,
tx_hash: tx_hash.clone(), timestamp: Utc::now().timestamp_millis(),
constitution_verified: true,
});
if let Some(token) = s.tokens.get_mut(&req.token_id) { token.holder = req.to.clone(); }
s.total_transfers += 1;
HttpResponse::Ok().json(serde_json::json!({
"success": true, "transfer_id": transfer_id,
"tx_hash": {"hex": tx_hash, "algorithm": "SHA3-384", "byte_length": 48},
"from": req.from, "to": req.to, "amount": req.amount.to_string(),
"constitution_verified": true, "timestamp": Utc::now().to_rfc3339()
}))
}
async fn burn_token(state: web::Data<SharedState>, req: web::Json<BurnReq>) -> HttpResponse {
let mut s = state.lock().unwrap();
match s.tokens.get_mut(&req.token_id) {
Some(token) => {
token.status = "burned".to_string();
HttpResponse::Ok().json(serde_json::json!({
"success": true, "token_id": req.token_id,
"burned_amount": req.amount.to_string(),
"timestamp": Utc::now().to_rfc3339()
}))
},
None => HttpResponse::NotFound().json(serde_json::json!({
"success": false, "error": format!("Token {} 不存在", req.token_id)
}))
}
}
async fn list_tokens(state: web::Data<SharedState>) -> HttpResponse {
let s = state.lock().unwrap();
let tokens: Vec<&TokenRecord> = s.tokens.values().collect();
HttpResponse::Ok().json(serde_json::json!({"tokens": tokens, "total": tokens.len()}))
}
async fn get_protocols() -> HttpResponse {
HttpResponse::Ok().json(serde_json::json!({
"protocols": [
{"id":"ACC-20","type":"Fungible Token"},{"id":"ACC-721","type":"NFT"},
{"id":"ACC-1155","type":"Multi Token"},{"id":"ACC-RWA","type":"Real World Asset"},
{"id":"ACC-Compliance","type":"Compliance"},{"id":"ACC-Valuation","type":"Valuation"},
{"id":"ACC-Custody","type":"Custody"},{"id":"ACC-Collateral","type":"Collateral"},
{"id":"ACC-Redemption","type":"Redemption"},{"id":"ACC-Insurance","type":"Insurance"},
{"id":"ACC-Governance","type":"Governance"},{"id":"ACC-XTZH","type":"Stablecoin"},
{"id":"ACC-Reserve","type":"Reserve"},{"id":"ACC-20C","type":"Compliant Fungible"},
{"id":"ACC-20E","type":"Enhanced Fungible"},{"id":"ACC-410","type":"Batch Operations"},
{"id":"ACC-1410","type":"Partitioned Token"},{"id":"ACC-Shard","type":"Shard Governance"},
{"id":"ACC-CrossChain","type":"Cross Chain"}
],
"total": 19, "chain_id": CHAIN_ID, "timestamp": Utc::now().to_rfc3339()
}))
}
async fn get_stats(state: web::Data<SharedState>) -> HttpResponse {
let s = state.lock().unwrap();
HttpResponse::Ok().json(serde_json::json!({
"service": "nac-acc-service", "layer": "L1-ACC",
"chain_id": CHAIN_ID, "supported_protocols": 19,
"tokens": s.tokens.len(), "total_minted": s.total_minted,
"total_transfers": s.total_transfers,
"uptime_ms": Utc::now().timestamp_millis() - s.started_at,
"timestamp": Utc::now().to_rfc3339()
}))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
tracing_subscriber::fmt().with_max_level(tracing::Level::INFO).init();
let port: u16 = std::env::var("ACC_PORT").unwrap_or_else(|_| "9551".to_string()).parse().unwrap_or(9551);
let state = web::Data::new(Arc::new(Mutex::new(AccState {
tokens: HashMap::new(), transfers: Vec::new(),
total_minted: 0, total_transfers: 0,
started_at: Utc::now().timestamp_millis(),
})));
info!("NAC ACC Service v{} 启动,端口 {},支持 19 个 ACC 协议", SERVICE_VERSION, port);
HttpServer::new(move || {
App::new().app_data(state.clone())
.route("/health", web::get().to(health))
.route("/state", web::get().to(get_state))
.route("/stats", web::get().to(get_stats))
.route("/protocols", web::get().to(get_protocols))
.route("/token/mint", web::post().to(mint_token))
.route("/token/transfer", web::post().to(transfer_token))
.route("/token/burn", web::post().to(burn_token))
.route("/tokens", web::get().to(list_tokens))
}).bind(format!("0.0.0.0:{}", port))?.run().await
}