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で書くのとそこまで変わりませんね。