first
This commit is contained in:
177
src/main.rs
Normal file
177
src/main.rs
Normal file
@ -0,0 +1,177 @@
|
||||
mod blockchain;
|
||||
mod cli;
|
||||
mod wallet;
|
||||
mod network;
|
||||
mod api;
|
||||
|
||||
use blockchain::{Blockchain, Transaction};
|
||||
use clap::Parser;
|
||||
use cli::{Cli, Commands};
|
||||
use std::fs;
|
||||
use wallet::Wallet;
|
||||
|
||||
const BLOCKCHAIN_FILE: &str = "blockchain.json";
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let cli = Cli::parse();
|
||||
|
||||
let mut blockchain = load_blockchain();
|
||||
|
||||
match cli.command {
|
||||
Commands::Wallet { atproto_did, export } => {
|
||||
let wallet = Wallet::new(atproto_did);
|
||||
println!("New wallet created!");
|
||||
println!("Address: {}", wallet.address);
|
||||
if let Some(private_key) = wallet.get_private_key_hex() {
|
||||
println!("Private key: {}", private_key);
|
||||
println!("IMPORTANT: Save this private key securely!");
|
||||
}
|
||||
if let Some(ref did) = wallet.atproto_did {
|
||||
println!("ATProto DID: {}", did);
|
||||
}
|
||||
|
||||
if let Some(path) = export {
|
||||
match wallet.export_to_file(&path) {
|
||||
Ok(()) => println!("Wallet exported to: {}", path),
|
||||
Err(e) => println!("Failed to export wallet: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Commands::Import { path } => {
|
||||
match Wallet::import_from_file(&path) {
|
||||
Ok(wallet) => {
|
||||
println!("Wallet imported successfully!");
|
||||
println!("Address: {}", wallet.address);
|
||||
if let Some(ref did) = wallet.atproto_did {
|
||||
println!("ATProto DID: {}", did);
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Failed to import wallet: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
Commands::Balance { address } => {
|
||||
let balance = blockchain.get_balance(&address);
|
||||
println!("Balance for {}: {} AIC", address, balance);
|
||||
}
|
||||
|
||||
Commands::Send { to, amount, private_key, atproto_did } => {
|
||||
match Wallet::from_private_key(&private_key, atproto_did) {
|
||||
Ok(wallet) => {
|
||||
let mut transaction = Transaction::new(
|
||||
wallet.address.clone(),
|
||||
to.clone(),
|
||||
amount,
|
||||
wallet.atproto_did.clone(),
|
||||
);
|
||||
|
||||
if let Some(ref signing_key) = wallet.private_key {
|
||||
transaction.sign(signing_key);
|
||||
|
||||
match blockchain.add_transaction(transaction) {
|
||||
Ok(()) => {
|
||||
save_blockchain(&blockchain);
|
||||
println!("Transaction added to pending transactions");
|
||||
println!("From: {}", wallet.address);
|
||||
println!("To: {}", to);
|
||||
println!("Amount: {} AIC", amount);
|
||||
}
|
||||
Err(e) => println!("Error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error loading wallet: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
Commands::Mine { address } => {
|
||||
if blockchain.pending_transactions.is_empty() {
|
||||
println!("No pending transactions to mine");
|
||||
} else {
|
||||
println!("Mining block...");
|
||||
let pending_count = blockchain.pending_transactions.len();
|
||||
blockchain.mine_pending_transactions(address.clone());
|
||||
save_blockchain(&blockchain);
|
||||
println!("Block mined successfully!");
|
||||
println!("Transactions included: {}", pending_count);
|
||||
println!("Mining reward sent to: {}", address);
|
||||
}
|
||||
}
|
||||
|
||||
Commands::Info => {
|
||||
println!("Blockchain Info:");
|
||||
println!("Total blocks: {}", blockchain.chain.len());
|
||||
println!("Difficulty: {}", blockchain.difficulty);
|
||||
println!("Mining reward: {} AIC", blockchain.mining_reward);
|
||||
println!("Pending transactions: {}", blockchain.pending_transactions.len());
|
||||
|
||||
if let Some(latest) = blockchain.chain.last() {
|
||||
println!("\nLatest block:");
|
||||
println!(" Index: {}", latest.index);
|
||||
println!(" Hash: {}", latest.hash);
|
||||
println!(" Timestamp: {}", latest.timestamp);
|
||||
println!(" Transactions: {}", latest.transactions.len());
|
||||
}
|
||||
}
|
||||
|
||||
Commands::Validate => {
|
||||
if blockchain.is_valid() {
|
||||
println!("Blockchain is valid ✓");
|
||||
} else {
|
||||
println!("Blockchain is invalid ✗");
|
||||
}
|
||||
}
|
||||
|
||||
Commands::Server { port } => {
|
||||
println!("Starting API server on port {}", port);
|
||||
api::run_api_server(blockchain, port).await;
|
||||
}
|
||||
|
||||
Commands::Node { port } => {
|
||||
println!("Starting P2P node on port {}", port);
|
||||
let (tx, mut rx) = tokio::sync::mpsc::channel(100);
|
||||
|
||||
let p2p_network = network::P2PNetwork::new(tx, port).await
|
||||
.expect("Failed to create P2P network");
|
||||
|
||||
tokio::spawn(async move {
|
||||
p2p_network.run().await;
|
||||
});
|
||||
|
||||
// Handle incoming messages
|
||||
while let Some(msg) = rx.recv().await {
|
||||
match msg {
|
||||
network::MessageType::NewTransaction(tx) => {
|
||||
println!("Received new transaction");
|
||||
if let Err(e) = blockchain.add_transaction(tx) {
|
||||
eprintln!("Failed to add transaction: {}", e);
|
||||
}
|
||||
save_blockchain(&blockchain);
|
||||
}
|
||||
network::MessageType::NewBlock(block) => {
|
||||
println!("Received new block");
|
||||
// TODO: Validate and add block
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_blockchain() -> Blockchain {
|
||||
if let Ok(data) = fs::read_to_string(BLOCKCHAIN_FILE) {
|
||||
if let Ok(blockchain) = serde_json::from_str(&data) {
|
||||
return blockchain;
|
||||
}
|
||||
}
|
||||
Blockchain::new()
|
||||
}
|
||||
|
||||
fn save_blockchain(blockchain: &Blockchain) {
|
||||
if let Ok(data) = serde_json::to_string_pretty(blockchain) {
|
||||
let _ = fs::write(BLOCKCHAIN_FILE, data);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user