From 9f5d864d533ce86459e654f5d78212933c0269ea Mon Sep 17 00:00:00 2001 From: gabrix73 Date: Mon, 1 Jun 2026 18:41:36 +0200 Subject: Initial commit: OnionCoin prototype with Proof-of-Relay consensus OnionCoin is a privacy cryptocurrency that rewards Tor relay operators through a unique Proof-of-Contribution consensus mechanism. Core Features: - Proof-of-Relay: 30% of block rewards go to Tor operators - Native .onion node identity (no IP exposure) - Temporal obfuscation protocols - Dandelion++ over Tor propagation - Native inheritance system with dead man's switch Technical Stack: - Rust workspace with 8 crates - Ed25519/X25519 cryptography - arti (Rust Tor client) integration planned - 10 minute block time, 5-10 TPS design Status: Prototype - Consensus logic complete with passing tests (30/33) - Network layer conceptual design complete - Tor integration pending - Testnet launch planned Q3 2026 License: MIT Author: Gabriele Salati (virebent) Contact: g48rix@gmail.com Website: https://www.gabrielesalati.eu Repository: https://git.virebent.art/virebent/onioncoin --- examples/consensus_demo.rs | 271 +++++++++++++++++++++++++++++ examples/inheritance_demo.rs | 397 +++++++++++++++++++++++++++++++++++++++++++ examples/timing_demo.rs | 191 +++++++++++++++++++++ 3 files changed, 859 insertions(+) create mode 100644 examples/consensus_demo.rs create mode 100644 examples/inheritance_demo.rs create mode 100644 examples/timing_demo.rs (limited to 'examples') diff --git a/examples/consensus_demo.rs b/examples/consensus_demo.rs new file mode 100644 index 0000000..7017f1e --- /dev/null +++ b/examples/consensus_demo.rs @@ -0,0 +1,271 @@ +/// Demonstration of OnionCoin's Proof-of-Contribution consensus +/// +/// Shows how validators earn rewards through: +/// - Stake (40%) +/// - Tor relay work (30%) ← UNIQUE! +/// - Bandwidth (15%) +/// - Uptime (10%) +/// - Storage (5%) + +use onioncoin_consensus::*; +use onioncoin_consensus::proof_of_contribution::ScoreWeights; + +fn main() { + println!("=== OnionCoin Proof-of-Contribution Demo ===\n"); + + demo_validator_tiers(); + println!(); + + demo_contribution_scoring(); + println!(); + + demo_relay_proof(); + println!(); + + demo_validator_selection(); + println!(); + + demo_genesis_mining(); +} + +fn demo_validator_tiers() { + println!("šŸŽÆ VALIDATOR TIERS"); + println!("=================="); + + let tiers = [ + ValidatorTier::Micro, + ValidatorTier::Light, + ValidatorTier::Standard, + ValidatorTier::Power, + ]; + + println!("ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”"); + println!("│ Tier │ Min Stake │ Hardware │ Monthly Return │"); + println!("ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤"); + + for tier in &tiers { + println!( + "│ {:11} │ {:10} ONC │ {:18} │ ~{:13} ONC │", + format!("{:?}", tier), + tier.min_stake(), + match tier { + ValidatorTier::Micro => "Raspberry Pi Zero", + ValidatorTier::Light => "Raspberry Pi 4", + ValidatorTier::Standard => "Desktop PC/VPS", + ValidatorTier::Power => "Server 24/7", + }, + format!("{:.1}", tier.expected_monthly_return()) + ); + } + + println!("ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜"); + println!("\nāœ… Even a Raspberry Pi Zero can validate!"); +} + +fn demo_contribution_scoring() { + println!("šŸ“Š CONTRIBUTION SCORING"); + println!("======================"); + + // Scenario 1: Whale with just stake (lazy validator) + let whale = Validator::new([1u8; 32], 10000, "whale.onion".to_string(), 0).unwrap(); + let whale_score = ProofOfContribution::calculate( + &whale, + None, // No relay work + &BandwidthMetrics::new(), + &UptimeMetrics::new(0), + &StorageMetrics::new(), + ); + + println!("Scenario 1: Whale Validator (10,000 ONC stake, no work)"); + println!("{}", whale_score.score.breakdown()); + + println!("\n─────────────────────────────────────────────────────\n"); + + // Scenario 2: Micro validator with relay work (active participant) + let micro = Validator::new([2u8; 32], 10, "micro.onion".to_string(), 0).unwrap(); + + // Excellent relay metrics + let mut relay_metrics = RelayMetrics::new(); + relay_metrics.bytes_relayed = 100 * 1024 * 1024 * 1024; // 100 GB! + relay_metrics.unique_circuits = 200; + relay_metrics.packets_relayed = 1_000_000; + relay_metrics.avg_latency_ms = 500; + + let relay_proof = RelayProof::new([2u8; 32], 0, 3600, relay_metrics); + + // Good bandwidth + let mut bandwidth = BandwidthMetrics::new(); + bandwidth.update(10_000_000, 10_000_000, 100); + + // Great uptime + let mut uptime = UptimeMetrics::new(0); + for i in 1..=1000 { + uptime.record_heartbeat(i * 60); + } + + // Some storage + let mut storage = StorageMetrics::new(); + storage.update(20 * 1024 * 1024 * 1024, 10 * 1024 * 1024 * 1024, 1000, 10000); + + let micro_score = ProofOfContribution::calculate( + µ, + Some(&relay_proof), + &bandwidth, + &uptime, + &storage, + ); + + println!("Scenario 2: Micro Validator (10 ONC stake, LOTS of work)"); + println!("{}", micro_score.score.breakdown()); + + println!("\nšŸŽÆ KEY INSIGHT:"); + println!(" Whale total score: {:.3}", whale_score.total_score()); + println!(" Micro total score: {:.3}", micro_score.total_score()); + println!("\n Micro validator is {}% as competitive as whale!", + (micro_score.total_score() / whale_score.total_score() * 100.0) as i32); + println!(" šŸ’” OnionCoin rewards WORK, not just wealth!"); +} + +fn demo_relay_proof() { + println!("🌐 PROOF-OF-RELAY (OnionCoin's UNIQUE Feature)"); + println!("=============================================="); + + println!("Relay Node Activity:"); + println!(" - Relayed: 50 GB of OnionCoin traffic"); + println!(" - Circuits: 150 unique Tor circuits"); + println!(" - Packets: 500,000"); + println!(" - Latency: 800ms average"); + + let mut metrics = RelayMetrics::new(); + metrics.bytes_relayed = 50 * 1024 * 1024 * 1024; + metrics.unique_circuits = 150; + metrics.packets_relayed = 500_000; + metrics.avg_latency_ms = 800; + + let proof = RelayProof::new([42u8; 32], 0, 3600, metrics); + + println!("\nRelay Proof:"); + println!(" - Valid: {}", proof.verify()); + println!(" - Quality Score: {:.2}", proof.metrics.quality_score()); + println!(" - Reward: {} ONC", proof.calculate_reward()); + + println!("\nāœ… NO OTHER CRYPTOCURRENCY REWARDS TOR RELAY WORK!"); +} + +fn demo_validator_selection() { + println!("šŸŽ² VALIDATOR SELECTION"); + println!("====================="); + + let mut registry = ValidatorRegistry::new(); + + // Create diverse validators + let validators_data = vec![ + ("whale.onion", 10000, 0.3), // High stake, low work + ("worker.onion", 100, 0.8), // Low stake, high work + ("balanced.onion", 1000, 0.6), // Balanced + ]; + + let mut validators = Vec::new(); + for (i, (addr, stake, score)) in validators_data.iter().enumerate() { + let pubkey = [(i + 1) as u8; 32]; + let validator = Validator::new(pubkey, *stake, addr.to_string(), 0).unwrap(); + registry.register(validator.clone()).unwrap(); + validators.push((validator, *score)); + } + + println!("Validators:"); + for (validator, score) in &validators { + println!(" - {}: {} ONC (score: {:.2})", + validator.onion_address, + validator.stake, + score); + } + + // Create contribution proofs + let candidates: Vec<_> = validators + .iter() + .map(|(v, score)| { + let poc = create_mock_poc(v.pubkey, *score); + (v, poc) + }) + .collect(); + + let selector = ValidatorSelector::default(); + + println!("\nSelection Simulation (1000 rounds):"); + let mut selection_counts = std::collections::HashMap::new(); + + for height in 0..1000 { + let prev_hash = [height as u8; 32]; + if let Some(selected) = selector.select_validator(&candidates, &prev_hash, height) { + *selection_counts.entry(selected).or_insert(0) += 1; + } + } + + for (validator, _) in &validators { + let count = selection_counts.get(&validator.pubkey).unwrap_or(&0); + let percentage = (*count as f64 / 1000.0) * 100.0; + println!(" - {}: selected {} times ({:.1}%)", + validator.onion_address, + count, + percentage); + } + + println!("\nāœ… High-work validators get selected more often!"); +} + +fn demo_genesis_mining() { + println!("🌱 GENESIS MINING (Fair Launch)"); + println!("================================"); + + let config = GenesisConfig::default(); + let mut genesis = GenesisMining::new(config.clone(), 0); + + println!("Genesis Phase:"); + println!(" - Duration: 6 months"); + println!(" - Total Supply: 1,000,000 ONC"); + println!(" - Distribution: 100% to Tor relay operators"); + println!(" - NO pre-mine, NO ICO, completely FAIR\n"); + + // Simulate 3 relay operators + let operators = vec![ + ("Early adopter (day 1)", [1u8; 32], "early.onion", 0, 100 * 1024 * 1024 * 1024u64), + ("Mid participant (month 2)", [2u8; 32], "mid.onion", 60 * 24 * 3600, 80 * 1024 * 1024 * 1024), + ("Late joiner (month 4)", [3u8; 32], "late.onion", 120 * 24 * 3600, 50 * 1024 * 1024 * 1024), + ]; + + for (name, pubkey, addr, reg_time, bytes) in &operators { + genesis.register_relay(*pubkey, addr.to_string(), *reg_time); + genesis.record_relay_activity(pubkey, *bytes, 86400 * 30); // 30 days uptime + + let rewards = genesis.calculate_rewards(pubkey, config.duration_seconds); + println!("{}", name); + println!(" - Relayed: {} GB", bytes / (1024 * 1024 * 1024)); + println!(" - Rewards: {} ONC", rewards); + } + + let stats = genesis.stats(); + println!("\nGenesis Stats:"); + println!(" - Total relay nodes: {}", stats.total_relay_nodes); + println!(" - Total relayed: {} GB", stats.total_bytes_relayed / (1024 * 1024 * 1024)); + + println!("\nāœ… Early participants get bonus, but everyone can join!"); +} + +// Helper function +fn create_mock_poc(pubkey: [u8; 32], total_score: f64) -> ProofOfContribution { + let score = ContributionScore { + stake_score: total_score * 0.4, + relay_score: total_score * 0.3, + bandwidth_score: total_score * 0.15, + uptime_score: total_score * 0.1, + storage_score: total_score * 0.05, + weights: ScoreWeights::default(), + }; + + ProofOfContribution { + validator_pubkey: pubkey, + score, + timestamp: 0, + } +} diff --git a/examples/inheritance_demo.rs b/examples/inheritance_demo.rs new file mode 100644 index 0000000..00c22ac --- /dev/null +++ b/examples/inheritance_demo.rs @@ -0,0 +1,397 @@ +/// Demonstration of OnionCoin's Revolutionary Inheritance System +/// +/// World's first cryptocurrency with NATIVE inheritance built into the blockchain! +/// +/// Features: +/// - Time-locked contracts with progressive unlock +/// - Heartbeat system (proof of life) +/// - Shamir secret sharing (3-of-5) +/// - Anti-scam protections +/// - Dispute resolution + +use onioncoin_inheritance::*; +use onioncoin_inheritance::contract::ContractStatus; +use onioncoin_inheritance::unlock::UnlockScheduleType; +use onioncoin_inheritance::recovery::{DisputeReason, Evidence, EvidenceType, ResolutionType, ResolutionAction}; + +fn main() { + println!("=== OnionCoin Inheritance System Demo ===\n"); + + demo_basic_inheritance(); + println!("\n{}\n", "=".repeat(60)); + + demo_progressive_unlock(); + println!("\n{}\n", "=".repeat(60)); + + demo_heartbeat_system(); + println!("\n{}\n", "=".repeat(60)); + + demo_shamir_secret_sharing(); + println!("\n{}\n", "=".repeat(60)); + + demo_dispute_resolution(); + println!("\n{}\n", "=".repeat(60)); + + demo_complete_scenario(); +} + +fn demo_basic_inheritance() { + println!("šŸ“œ BASIC INHERITANCE CONTRACT"); + println!("============================="); + + // Create beneficiaries + let beneficiaries = vec![ + Beneficiary::new([1u8; 32], 60).unwrap(), // Wife: 60% + Beneficiary::new([2u8; 32], 40).unwrap(), // Child: 40% + ]; + + // Create contract + let contract = InheritanceContract::new( + [0u8; 32], // Owner pubkey + beneficiaries, + InheritanceConfig::default(), // 90 days + 30 days grace + 100_000, // 100,000 ONC locked + 0, + ).unwrap(); + + println!("Contract Created:"); + println!(" Owner: {:?}...", &contract.owner[0..4]); + println!(" Locked Amount: {} ONC", contract.locked_amount); + println!(" Beneficiaries: {}", contract.beneficiaries.len()); + + for (i, b) in contract.beneficiaries.iter().enumerate() { + let amount = b.calculate_amount(contract.locked_amount); + println!(" {}. {}% = {} ONC", i + 1, b.percentage, amount); + } + + println!("\nHeartbeat Requirements:"); + println!(" Interval: {} days", contract.config.heartbeat_interval / (24 * 3600)); + println!(" Grace Period: {} days", contract.config.grace_period / (24 * 3600)); + println!(" Total Timeout: {} days", contract.config.total_timeout() / (24 * 3600)); + + println!("\nāœ… NO OTHER CRYPTO HAS THIS BUILT-IN!"); +} + +fn demo_progressive_unlock() { + println!("šŸ”“ PROGRESSIVE UNLOCK (INNOVATIVE!)"); + println!("==================================="); + + let beneficiaries = vec![Beneficiary::new([1u8; 32], 100).unwrap()]; + + let mut contract = InheritanceContract::new( + [0u8; 32], + beneficiaries, + InheritanceConfig::default(), + 100_000, + 0, + ).unwrap(); + + println!("Why Progressive Unlock?"); + println!(" āŒ Traditional dead man's switch: ALL funds unlock at once"); + println!(" āœ… OnionCoin: Gradual unlock gives owner time to recover!\n"); + + // Simulate timeout + contract.status = ContractStatus::Unlocking; + + // Initialize progressive unlock + ProgressiveUnlock::initialize(&mut contract, UnlockScheduleType::Standard).unwrap(); + + let schedule = contract.unlock_schedule.as_ref().unwrap(); + + println!("Standard 4-Tier Schedule:"); + for tier in &schedule.tiers { + println!(" Tier {}: Day +{} → Unlock {}%", + tier.tier, + tier.days_after_expiry, + tier.unlock_percentage); + } + + println!("\nExample Timeline:"); + println!(" Day 0: Grace period expires"); + println!(" Day 30: Tier 1 unlocks → 10,000 ONC available (10%)"); + println!(" Day 60: Tier 2 unlocks → 25,000 ONC more (35% total)"); + println!(" Day 90: Tier 3 unlocks → 35,000 ONC more (70% total)"); + println!(" Day 120: Tier 4 unlocks → 30,000 ONC more (100% total)"); + + println!("\nšŸ’” If owner wakes up from coma on day 50:"); + println!(" Only 35% unlocked, can dispute and recover 65%!"); +} + +fn demo_heartbeat_system() { + println!("šŸ’“ HEARTBEAT SYSTEM"); + println!("=================="); + + let beneficiaries = vec![Beneficiary::new([1u8; 32], 100).unwrap()]; + + let mut contract = InheritanceContract::new( + [0u8; 32], + beneficiaries, + InheritanceConfig::default(), + 10000, + 0, + ).unwrap(); + + let mut manager = HeartbeatManager::new(); + manager.register_contract(contract.contract_id, 0); + + println!("How It Works:"); + println!(" 1. Owner must 'check in' every 90 days"); + println!(" 2. Heartbeat = Send 0.00000001 ONC to yourself"); + println!(" 3. Privacy-preserving (no one knows why you sent it)"); + println!(" 4. Can do via Tor for extra privacy\n"); + + // Simulate heartbeats + println!("Simulating Owner Activity:"); + + // Day 30 + manager.process_heartbeat(&mut contract, 30 * 24 * 3600).unwrap(); + println!(" Day 30: āœ“ Heartbeat sent"); + + // Day 65 + manager.process_heartbeat(&mut contract, 65 * 24 * 3600).unwrap(); + println!(" Day 65: āœ“ Heartbeat sent"); + + let stats = manager.get_stats(&contract.contract_id).unwrap(); + println!("\nStatistics:"); + println!(" Total Heartbeats: {}", stats.heartbeat_count); + println!(" Average Interval: {:.1} days", stats.avg_interval_days); + println!(" Last Heartbeat: {} days ago", + (65 * 24 * 3600 - stats.last_heartbeat) / (24 * 3600)); + + println!("\n Recommendation: {}", manager.suggest_frequency(&contract.contract_id).unwrap()); + + // Simulate warning + println!("\nWarning System:"); + let notifications = manager.check_contracts(&[&contract], 65 * 24 * 3600 + 75 * 24 * 3600); + + if !notifications.is_empty() { + println!(" āš ļø {}", notifications[0].message); + } +} + +fn demo_shamir_secret_sharing() { + println!("šŸ” SHAMIR SECRET SHARING (3-of-5)"); + println!("================================="); + + println!("Scenario: Split seed phrase among 5 trusted people"); + println!(" Any 3 can recover, but 2 or fewer cannot\n"); + + let seed_phrase = b"abandon ability able about above absent absorb abstract absurd abuse access accident"; + + // Create 5 guardians + let guardians = vec![ + [1u8; 32], // Best friend + [2u8; 32], // Sister + [3u8; 32], // Lawyer + [4u8; 32], // Colleague + [5u8; 32], // Trusted advisor + ]; + + println!("Guardians:"); + let guardian_names = ["Best Friend", "Sister", "Lawyer", "Colleague", "Advisor"]; + for (i, name) in guardian_names.iter().enumerate() { + println!(" {}. {} ({:?}...)", i + 1, name, &guardians[i][0..4]); + } + + // Create Shamir scheme + let mut shamir = ShamirShares::new(3, 5).unwrap(); + let shares = shamir.split_secret(seed_phrase, &guardians).unwrap(); + + println!("\nāœ… Secret split into 5 shares"); + println!(" Each guardian receives their encrypted share\n"); + + // Simulate recovery scenario + println!("Recovery Scenario:"); + println!(" Owner passed away, beneficiaries contact guardians\n"); + + // Only 2 shares - fails + println!(" Attempt 1: Guardian 1 + Guardian 2 (2 shares)"); + let result = shamir.recover_secret(&shares[0..2]); + println!(" āŒ Failed: Need minimum 3 shares\n"); + + // 3 shares - success! + println!(" Attempt 2: Guardian 1 + Guardian 3 + Guardian 5 (3 shares)"); + let recovered = shamir.recover_secret(&[shares[0].clone(), shares[2].clone(), shares[4].clone()]).unwrap(); + println!(" āœ… Success: Seed phrase recovered!"); + + if recovered == seed_phrase { + println!(" āœ… Verified: Matches original seed\n"); + } + + println!("Security:"); + println!(" āœ… No single guardian can access funds"); + println!(" āœ… Collusion of 3+ required"); + println!(" āœ… Redundancy: Can lose 2 shares and still recover"); +} + +fn demo_dispute_resolution() { + println!("āš–ļø DISPUTE RESOLUTION (ANTI-SCAM)"); + println!("================================="); + + let beneficiaries = vec![Beneficiary::new([1u8; 32], 100).unwrap()]; + + let mut contract = InheritanceContract::new( + [0u8; 32], + beneficiaries, + InheritanceConfig::default(), + 50000, + 0, + ).unwrap(); + + let mut recovery_manager = RecoveryManager::default(); + + println!("Scenario: Owner in hospital, unable to send heartbeat"); + println!(" Grace period expires, unlock starts...\n"); + + // Simulate unlock starting + contract.status = ContractStatus::Unlocking; + + println!("Owner Recovers and Files Dispute:"); + recovery_manager.file_dispute( + &mut contract, + [0u8; 32], // Owner + DisputeReason::TemporaryIncapacitation, + 1000, + ).unwrap(); + + println!(" āœ… Dispute filed successfully"); + println!(" Status: {:?}", contract.status); + + // Add evidence + let evidence = Evidence { + evidence_type: EvidenceType::MedicalCertificate, + data: vec![1, 2, 3], // Encrypted medical cert + submitted_at: 1100, + }; + + recovery_manager.add_evidence(&contract.contract_id, evidence).unwrap(); + println!(" āœ… Medical certificate submitted\n"); + + // Resolve dispute + println!("Resolution:"); + let resolution = DisputeResolution { + resolution_type: ResolutionType::ResetHeartbeat, + actions: vec![ResolutionAction::HeartbeatReset], + resolved_at: 2000, + notes: Some("Owner verified alive, medical emergency confirmed".to_string()), + }; + + recovery_manager.resolve_dispute(&mut contract, resolution, 2000).unwrap(); + + println!(" āœ… Heartbeat reset"); + println!(" āœ… Contract resumed: {:?}", contract.status); + println!(" āœ… Funds secure, owner has full control\n"); + + println!("Anti-Scam Protection:"); + println!(" āœ… Maximum 3 disputes allowed (prevent abuse)"); + println!(" āœ… 7-day cooldown between disputes"); + println!(" āœ… Evidence required (proof of life)"); + println!(" āœ… Suspicious activity detection"); +} + +fn demo_complete_scenario() { + println!("šŸŽ¬ COMPLETE SCENARIO"); + println!("==================="); + + println!("Alice wants to ensure her crypto goes to her family if she dies\n"); + + // Step 1: Create contract + println!("Step 1: Create Inheritance Contract"); + let beneficiaries = vec![ + Beneficiary::new([1u8; 32], 70).unwrap(), // Husband + Beneficiary::new([2u8; 32], 30).unwrap(), // Daughter + ]; + + let mut contract = InheritanceContract::new( + [0u8; 32], // Alice + beneficiaries, + InheritanceConfig::default(), + 500_000, // 500,000 ONC + 0, + ).unwrap(); + + println!(" āœ… Contract created"); + println!(" āœ… 500,000 ONC locked"); + println!(" āœ… 70% to husband, 30% to daughter\n"); + + // Step 2: Optional Shamir shares + println!("Step 2: Setup Shamir Secret Sharing (Optional)"); + let guardians = vec![ + [10u8; 32], + [11u8; 32], + [12u8; 32], + [13u8; 32], + [14u8; 32], + ]; + + let distribution = ShareDistribution::standard_3_of_5(guardians).unwrap(); + println!(" āœ… Seed split among 5 trusted guardians"); + println!(" āœ… Any 3 can help family recover\n"); + + // Step 3: Regular heartbeats + println!("Step 3: Alice Sends Regular Heartbeats"); + let mut manager = HeartbeatManager::new(); + manager.register_contract(contract.contract_id, 0); + + for month in 1..=12 { + let days = month * 30; + manager.process_heartbeat(&mut contract, days * 24 * 3600).unwrap(); + if month % 3 == 0 { + println!(" āœ“ Month {}: Heartbeat sent", month); + } + } + println!(" āœ… 12 months of regular heartbeats\n"); + + // Step 4: Alice passes away (tragic scenario) + println!("Step 4: Alice Passes Away (Simulation)"); + println!(" Last heartbeat: Month 12"); + println!(" Current time: Month 16 (120 days later)\n"); + + let current_time = 16 * 30 * 24 * 3600; + + // Step 5: Grace period expires + println!("Step 5: System Detects Timeout"); + contract.update_status(current_time); + println!(" Status: {:?}", contract.status); + + let notifications = manager.check_contracts(&[&contract], current_time); + println!(" Notifications sent: {}", notifications.len()); + println!(" - Critical warning to Alice (no response)"); + println!(" - Info to beneficiaries (grace period)\n"); + + // Step 6: Progressive unlock + println!("Step 6: Progressive Unlock Begins"); + contract.status = ContractStatus::Unlocking; + ProgressiveUnlock::initialize(&mut contract, UnlockScheduleType::Standard).unwrap(); + + // Simulate tier 1 unlock (30 days after grace expiry) + let tier1_time = current_time + 30 * 24 * 3600; + let distributions = ProgressiveUnlock::process(&mut contract, tier1_time).unwrap(); + + println!(" Day 30: Tier 1 Unlocks (10%)"); + for dist in &distributions { + println!(" → {} ONC to beneficiary {:?}...", + dist.amount, + &dist.beneficiary[0..4]); + } + + println!("\n Husband receives: 35,000 ONC (70% of 50,000)"); + println!(" Daughter receives: 15,000 ONC (30% of 50,000)\n"); + + // Step 7: Full unlock + let final_time = current_time + 120 * 24 * 3600; + ProgressiveUnlock::process(&mut contract, final_time).unwrap(); + + println!("Step 7: Full Unlock Complete (Day 120)"); + println!(" Husband total: 350,000 ONC"); + println!(" Daughter total: 150,000 ONC"); + println!(" Status: {:?}", contract.status); + + println!("\nāœ… INHERITANCE SUCCESSFULLY DISTRIBUTED"); + println!("āœ… NO LAWYER FEES"); + println!("āœ… NO COURT PROCESS"); + println!("āœ… FULLY AUTOMATED"); + println!("āœ… PRIVACY PRESERVED"); + + println!("\nšŸŽ‰ THIS IS THE FUTURE OF CRYPTO INHERITANCE!"); +} diff --git a/examples/timing_demo.rs b/examples/timing_demo.rs new file mode 100644 index 0000000..b2dfdff --- /dev/null +++ b/examples/timing_demo.rs @@ -0,0 +1,191 @@ +/// Demonstration of OnionCoin's unique timing obfuscation features +/// +/// This example shows how OnionCoin uses Tor latency as a privacy feature +/// to make transaction timing analysis impossible. + +use chrono::Utc; +use onioncoin_timing::*; +use onioncoin_timing::delay::DelaySequence; +use std::time::Instant; + +#[tokio::main] +async fn main() { + println!("=== OnionCoin Timing Obfuscation Demo ===\n"); + + // 1. Fuzzy Timestamps + demo_fuzzy_timestamps(); + println!(); + + // 2. Time Range Proofs + demo_time_proofs(); + println!(); + + // 3. Delay Strategies + demo_delays().await; + println!(); + + // 4. Mixing Pool + demo_mixing_pool(); + println!(); + + // 5. Complete Transaction Flow + demo_complete_flow().await; +} + +fn demo_fuzzy_timestamps() { + println!("šŸ“… FUZZY TIMESTAMPS"); + println!("------------------"); + + let real_time = Utc::now(); + println!("Real creation time: {}", real_time.format("%Y-%m-%d %H:%M:%S")); + + // Create fuzzy time range + let range = TimeRange::new_fuzzy(real_time); + + println!("Timestamp range: {} to {}", + chrono::DateTime::from_timestamp(range.earliest, 0).unwrap().format("%Y-%m-%d %H:%M:%S"), + chrono::DateTime::from_timestamp(range.latest, 0).unwrap().format("%Y-%m-%d %H:%M:%S"), + ); + + println!("Range duration: {} hours", range.duration_seconds() / 3600); + println!("\nāœ… Observer cannot determine exact creation time!"); +} + +fn demo_time_proofs() { + println!("šŸ” ZERO-KNOWLEDGE TIME PROOFS"); + println!("-----------------------------"); + + let real_time = Utc::now(); + let seed = [42u8; 32]; + let range = TimeRange::new_fuzzy(real_time); + + let proof = TimeRangeProof::generate(&seed, real_time, &range) + .expect("Proof generation failed"); + + println!("Generated ZK proof:"); + println!(" - Earliest hash: {:x?}...", &proof.earliest_hash[..4]); + println!(" - Latest hash: {:x?}...", &proof.latest_hash[..4]); + println!(" - Time commit: {:x?}...", &proof.time_commitment[..4]); + + let is_valid = proof.verify(&range); + println!("\nProof verification: {}", if is_valid { "āœ… VALID" } else { "āŒ INVALID" }); + println!("Real time is hidden but provably within range!"); +} + +async fn demo_delays() { + println!("ā±ļø STRATEGIC DELAYS"); + println!("-------------------"); + + // Wallet broadcast delay + println!("1. Wallet broadcast delay (5-60 min):"); + let strategy = DelayStrategy::wallet_broadcast(); + let delay = strategy.calculate(); + println!(" Random delay: {} seconds ({:.1} minutes)", delay.as_secs(), delay.as_secs() as f64 / 60.0); + + // Dandelion STEM delays + println!("\n2. Dandelion STEM sequence (1-4 hops):"); + let mut sequence = DelaySequence::dandelion_stem(); + println!(" Hops: {}", sequence.len()); + + let mut hop = 1; + while let Some(strategy) = sequence.next() { + let delay = strategy.calculate(); + println!(" Hop {}: {} seconds", hop, delay.as_secs()); + hop += 1; + } + + // Node rebroadcast delay + println!("\n3. Node rebroadcast delay (10s-2min):"); + let strategy = DelayStrategy::node_rebroadcast(); + let delay = strategy.calculate(); + println!(" Random delay: {} seconds", delay.as_secs()); + + println!("\nāœ… Multiple layers of random delays obscure transaction origin!"); +} + +fn demo_mixing_pool() { + println!("šŸ”€ MIXING POOL"); + println!("-------------"); + + let mut pool = MixingPool::::new( + std::time::Duration::from_secs(10), // 10s min (demo) + std::time::Duration::from_secs(30), // 30s max (demo) + 100, + ); + + println!("Adding transactions to mixing pool..."); + for i in 1..=10 { + pool.add(i); + println!(" Added tx #{}", i); + } + + println!("\nPool size: {} transactions", pool.len()); + println!("Waiting for minimum batch duration..."); + + std::thread::sleep(std::time::Duration::from_secs(11)); + + if pool.should_release() { + let batch = pool.release_batch(); + println!("\nāœ… Released shuffled batch:"); + println!(" Original order: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10"); + println!(" Shuffled order: {:?}", batch); + println!("\nTemporal ordering destroyed!"); + } +} + +async fn demo_complete_flow() { + println!("🌊 COMPLETE TRANSACTION FLOW"); + println!("============================"); + + let real_time = Utc::now(); + println!("T+0:00 User creates transaction"); + println!(" Real time: {}", real_time.format("%H:%M:%S")); + + // Step 1: Fuzzy timestamp + let seed = [42u8; 32]; + let timing = TimingMetadata::new(real_time, &seed) + .expect("Failed to create timing metadata"); + + println!(" Timestamp range: ±{} hours", timing.time_range.duration_seconds() / 3600 / 2); + + // Step 2: Wallet delay + println!("\nT+0:00 Wallet applies random delay..."); + let wallet_delay = DelayStrategy::Random { + min: std::time::Duration::from_secs(2), // Shortened for demo + max: std::time::Duration::from_secs(5), + }; + let actual_delay = wallet_delay.calculate(); + println!(" Waiting {} seconds", actual_delay.as_secs()); + + let start = Instant::now(); + tokio::time::sleep(actual_delay).await; + + println!("T+{:04} Transaction broadcast to Tor", start.elapsed().as_secs()); + + // Step 3: Dandelion STEM + println!("\nT+{:04} Entering STEM phase...", start.elapsed().as_secs()); + let mut sequence = DelaySequence::new(vec![ + DelayStrategy::Fixed(std::time::Duration::from_secs(1)), + DelayStrategy::Fixed(std::time::Duration::from_secs(1)), + ]); + + let mut hop = 1; + while let Some(strategy) = sequence.next() { + strategy.sleep().await; + println!("T+{:04} STEM hop {} complete", start.elapsed().as_secs(), hop); + hop += 1; + } + + // Step 4: Transition to FLUFF + println!("\nT+{:04} Transitioning to FLUFF phase", start.elapsed().as_secs()); + println!(" Broadcasting to network..."); + + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + + println!("\nT+{:04} āœ… Transaction propagated!", start.elapsed().as_secs()); + println!("\nšŸŽÆ PRIVACY ACHIEVED:"); + println!(" - Real creation time: HIDDEN (±{} hours ambiguity)", timing.time_range.duration_seconds() / 3600 / 2); + println!(" - Origin node: UNKNOWN (Dandelion++ + Tor)"); + println!(" - Propagation path: UNTRACEABLE (random delays)"); + println!(" - Transaction correlation: VERY DIFFICULT (mixing pool)"); +} -- cgit v1.2.3