【Rust】Proof of StakeをRustで書きたい

use std::collections::HashMap;
use chrono::{Utc, Local, DateTime, Date};
use sha2::Sha256;
use sha2::Digest;
use rand::Rng;
use std::io;
use std::io::Error;

#[derive(Debug)]
struct Block {
    index: u32,
    previous_hash: String,
    timestamp: DateTime<Utc>,
    data: Vec<String>,
    validator: String,
    hash: String,
}

#[derive(Debug)]
struct BlockChain {
    chain: Vec<Block>,
    unconfirmed_data: Vec<String>,
    validators: HashMap<String, i32>,
    staked_tokens: Vec<i32>,
}

impl BlockChain {

    const minimum_stake: i32 = 10;

    fn last_block(&self) -> &Block {
        return self.chain.last().unwrap();
    }

    fn add_data(&mut self, new_data:String) {
        self.unconfirmed_data.push(new_data);
    }

    fn add_validator(&mut self, validator: String, stake: i32) {
        if stake >= Self::minimum_stake {
            self.validators.insert(validator, stake);
            self.staked_tokens.push(stake);
        } else {
            println!("{} does not meet the minimum stake requirement.", validator);
        }
    }

    fn select_validator(self) -> String {
        let total_stake: i32 = self.staked_tokens.iter().sum();
        let mut selected_validator: String = "".to_string();
        let mut rnd = rand::thread_rng();
        while selected_validator == "".to_string() {
            let pick = rnd.gen_range(0..total_stake);
            let mut current: i32 = 0;
            for (validator, stake) in &self.validators {
                // println!("{} {}", validator, stake);
                current += stake;
                if current > pick{
                    selected_validator = validator.to_string();
                    break;
                }
            }
        }
        return selected_validator;
    }

    fn create_block(mut self, validator: String)-> Result<(), String> {
        if self.unconfirmed_data.is_empty() {
            return Err("No transaction".to_string());
        }
        let last_block = self.last_block(); 
        let new_block = Block {
            index: last_block.index + 1,
            previous_hash: last_block.hash.clone(),
            timestamp: Utc::now(),
            data : self.unconfirmed_data.clone(),
            validator: validator,
            hash: "".to_string() 
        };
        self.chain.push(new_block);
        self.unconfirmed_data.clear();
        Ok(())
    }

    fn display_chain(self) {
        println!("{:?}", self.chain);
    }

}

fn calculate_hash(data: String) -> String {
    let mut hasher = Sha256::new();
    hasher.update(data);
    let hashed_sha256 = hasher.finalize();
    return hex::encode(hashed_sha256);
}

fn main() {
    let genesis_hash = calculate_hash("Genesis Block".to_string());
    let genesis_block = Block { index: 0, previous_hash: "".to_string(), timestamp: Utc::now(), data: vec!["Genesis Block".to_string()], validator: "".to_string(), hash: genesis_hash };

    let mut blockchain = BlockChain { chain: vec![genesis_block], unconfirmed_data: vec![], validators: HashMap::from([]), staked_tokens: vec![]};

    blockchain.add_validator("Alice".to_string(), 200);
    blockchain.add_validator("Bob".to_string(), 300);
    blockchain.add_validator("Chan".to_string(), 400);

    blockchain.add_data("James got 1000 token".to_string());
    blockchain.add_data("James sent 500 token to Jhon".to_string());

    let selected_validator = blockchain.select_validator();
    println!("Selected validator is {}", selected_validator);
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
Running `target/debug/sample`
Selected validator is Bob

基本的にPythonで書くのとそこまで変わりませんね。