├── blockchain_rust_part_1 ├── src │ ├── utils │ │ ├── mod.rs │ │ └── serializer.rs │ ├── blocks │ │ ├── mod.rs │ │ ├── blockchain.rs │ │ └── block.rs │ ├── error.rs │ └── lib.rs ├── examples │ └── gen_bc.rs ├── Cargo.toml └── Cargo.lock ├── blockchain_rust_part_2 ├── src │ ├── utils │ │ ├── mod.rs │ │ └── serializer.rs │ ├── blocks │ │ ├── mod.rs │ │ ├── blockchain.rs │ │ ├── pow.rs │ │ └── block.rs │ ├── error.rs │ └── lib.rs ├── examples │ └── gen_bc.rs ├── Cargo.toml └── Cargo.lock ├── blockchain_rust_part_3 ├── src │ ├── utils │ │ ├── mod.rs │ │ └── serializer.rs │ ├── blocks │ │ ├── mod.rs │ │ ├── pow.rs │ │ ├── block.rs │ │ └── blockchain.rs │ ├── lib.rs │ ├── error.rs │ └── storage │ │ ├── mod.rs │ │ └── sleddb.rs ├── examples │ └── gen_bc.rs ├── Cargo.toml └── Cargo.lock ├── blockchain_rust_part_4 ├── src │ ├── utils │ │ ├── mod.rs │ │ └── serializer.rs │ ├── blocks │ │ ├── mod.rs │ │ ├── pow.rs │ │ ├── block.rs │ │ └── blockchain.rs │ ├── transactions │ │ ├── mod.rs │ │ ├── tx_output.rs │ │ ├── tx_input.rs │ │ ├── utxo_set.rs │ │ └── transaction.rs │ ├── error.rs │ ├── lib.rs │ └── storage │ │ ├── mod.rs │ │ └── sleddb.rs ├── examples │ ├── gen_bc.rs │ └── gen_trx.rs ├── Cargo.toml └── Cargo.lock ├── blockchain_rust_part_5 ├── src │ ├── utils │ │ ├── mod.rs │ │ ├── serializer.rs │ │ └── secret.rs │ ├── wallets │ │ ├── mod.rs │ │ ├── wallet.rs │ │ └── wallets.rs │ ├── blocks │ │ ├── mod.rs │ │ ├── pow.rs │ │ ├── block.rs │ │ └── blockchain.rs │ ├── transactions │ │ ├── mod.rs │ │ ├── tx_output.rs │ │ ├── tx_input.rs │ │ ├── utxo_set.rs │ │ └── transaction.rs │ ├── error.rs │ ├── lib.rs │ └── storage │ │ ├── mod.rs │ │ └── sleddb.rs ├── examples │ ├── gen_bc.rs │ └── gen_trx.rs ├── Cargo.toml └── Cargo.lock ├── blockchain_rust_part_6 ├── src │ ├── utils │ │ ├── mod.rs │ │ ├── serializer.rs │ │ └── secret.rs │ ├── wallets │ │ ├── mod.rs │ │ ├── wallet.rs │ │ └── wallets.rs │ ├── blocks │ │ ├── mod.rs │ │ ├── pow.rs │ │ ├── block.rs │ │ └── blockchain.rs │ ├── transactions │ │ ├── mod.rs │ │ ├── tx_output.rs │ │ ├── tx_input.rs │ │ ├── utxo_set.rs │ │ └── transaction.rs │ ├── error.rs │ ├── lib.rs │ ├── server.rs │ ├── networks │ │ ├── command.rs │ │ ├── mod.rs │ │ ├── behaviour.rs │ │ └── node.rs │ └── storage │ │ ├── mod.rs │ │ └── sleddb.rs ├── examples │ ├── gen_bc.rs │ └── gen_trx.rs └── Cargo.toml └── README.md /blockchain_rust_part_1/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | mod serializer; 2 | 3 | pub use serializer::*; -------------------------------------------------------------------------------- /blockchain_rust_part_2/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | mod serializer; 2 | 3 | pub use serializer::*; -------------------------------------------------------------------------------- /blockchain_rust_part_3/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | mod serializer; 2 | 3 | pub use serializer::*; -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | mod serializer; 2 | 3 | pub use serializer::*; -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | mod serializer; 2 | mod secret; 3 | 4 | pub use serializer::*; 5 | pub use secret::*; -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/wallets/mod.rs: -------------------------------------------------------------------------------- 1 | mod wallet; 2 | mod wallets; 3 | 4 | pub use wallet::*; 5 | pub use wallets::Wallets; -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | mod serializer; 2 | mod secret; 3 | 4 | pub use serializer::*; 5 | pub use secret::*; -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/wallets/mod.rs: -------------------------------------------------------------------------------- 1 | mod wallet; 2 | mod wallets; 3 | 4 | pub use wallet::*; 5 | pub use wallets::Wallets; -------------------------------------------------------------------------------- /blockchain_rust_part_1/src/blocks/mod.rs: -------------------------------------------------------------------------------- 1 | mod block; 2 | mod blockchain; 3 | 4 | pub use block::Block; 5 | pub use blockchain::Blockchain; -------------------------------------------------------------------------------- /blockchain_rust_part_3/src/blocks/mod.rs: -------------------------------------------------------------------------------- 1 | mod block; 2 | mod blockchain; 3 | mod pow; 4 | 5 | pub use block::Block; 6 | pub use blockchain::*; 7 | pub use pow::ProofOfWork; -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/blocks/mod.rs: -------------------------------------------------------------------------------- 1 | mod block; 2 | mod blockchain; 3 | mod pow; 4 | 5 | pub use block::Block; 6 | pub use blockchain::*; 7 | pub use pow::ProofOfWork; -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/blocks/mod.rs: -------------------------------------------------------------------------------- 1 | mod block; 2 | mod blockchain; 3 | mod pow; 4 | 5 | pub use block::Block; 6 | pub use blockchain::*; 7 | pub use pow::ProofOfWork; -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/blocks/mod.rs: -------------------------------------------------------------------------------- 1 | mod block; 2 | mod blockchain; 3 | mod pow; 4 | 5 | pub use block::Block; 6 | pub use blockchain::*; 7 | pub use pow::ProofOfWork; -------------------------------------------------------------------------------- /blockchain_rust_part_2/src/blocks/mod.rs: -------------------------------------------------------------------------------- 1 | mod block; 2 | mod blockchain; 3 | mod pow; 4 | 5 | pub use block::Block; 6 | pub use blockchain::Blockchain; 7 | pub use pow::ProofOfWork; -------------------------------------------------------------------------------- /blockchain_rust_part_1/src/error.rs: -------------------------------------------------------------------------------- 1 | use thiserror::Error; 2 | 3 | #[derive(Debug, Error)] 4 | pub enum BlockchainError { 5 | #[error("Serialize or Deserialize error")] 6 | SerializeError(#[from] Box), 7 | } -------------------------------------------------------------------------------- /blockchain_rust_part_2/src/error.rs: -------------------------------------------------------------------------------- 1 | use thiserror::Error; 2 | 3 | #[derive(Debug, Error)] 4 | pub enum BlockchainError { 5 | #[error("Serialize or Deserialize error")] 6 | SerializeError(#[from] Box), 7 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/transactions/mod.rs: -------------------------------------------------------------------------------- 1 | mod transaction; 2 | mod tx_input; 3 | mod tx_output; 4 | mod utxo_set; 5 | 6 | pub use transaction::*; 7 | pub use tx_input::Txinput; 8 | pub use tx_output::Txoutput; 9 | pub use utxo_set::UTXOSet; 10 | -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/transactions/mod.rs: -------------------------------------------------------------------------------- 1 | mod transaction; 2 | mod tx_input; 3 | mod tx_output; 4 | mod utxo_set; 5 | 6 | pub use transaction::*; 7 | pub use tx_input::Txinput; 8 | pub use tx_output::Txoutput; 9 | pub use utxo_set::UTXOSet; 10 | -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/transactions/mod.rs: -------------------------------------------------------------------------------- 1 | mod transaction; 2 | mod tx_input; 3 | mod tx_output; 4 | mod utxo_set; 5 | 6 | pub use transaction::*; 7 | pub use tx_input::Txinput; 8 | pub use tx_output::Txoutput; 9 | pub use utxo_set::UTXOSet; 10 | -------------------------------------------------------------------------------- /blockchain_rust_part_1/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod error; 2 | mod utils; 3 | mod blocks; 4 | 5 | pub use blocks::*; 6 | 7 | #[cfg(test)] 8 | mod tests { 9 | #[test] 10 | fn it_works() { 11 | let result = 2 + 2; 12 | assert_eq!(result, 4); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /blockchain_rust_part_2/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod error; 2 | mod utils; 3 | mod blocks; 4 | 5 | pub use blocks::*; 6 | 7 | #[cfg(test)] 8 | mod tests { 9 | #[test] 10 | fn it_works() { 11 | let result = 2 + 2; 12 | assert_eq!(result, 4); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /blockchain_rust_part_3/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod error; 2 | mod utils; 3 | mod blocks; 4 | mod storage; 5 | 6 | pub use blocks::*; 7 | pub use storage::*; 8 | 9 | #[cfg(test)] 10 | mod tests { 11 | #[test] 12 | fn it_works() { 13 | let result = 2 + 2; 14 | assert_eq!(result, 4); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /blockchain_rust_part_3/src/error.rs: -------------------------------------------------------------------------------- 1 | use thiserror::Error; 2 | 3 | #[derive(Debug, Error)] 4 | pub enum BlockchainError { 5 | #[error("Serialize or Deserialize error")] 6 | SerializeError(#[from] Box), 7 | 8 | #[error("Failed to access sled db")] 9 | SledError(#[from] sled::Error), 10 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/error.rs: -------------------------------------------------------------------------------- 1 | use thiserror::Error; 2 | 3 | #[derive(Debug, Error)] 4 | pub enum BlockchainError { 5 | #[error("Serialize or Deserialize error")] 6 | SerializeError(#[from] Box), 7 | 8 | #[error("Failed to access sled db")] 9 | SledError(#[from] sled::Error), 10 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/error.rs: -------------------------------------------------------------------------------- 1 | use thiserror::Error; 2 | 3 | #[derive(Debug, Error)] 4 | pub enum BlockchainError { 5 | #[error("Serialize or Deserialize error")] 6 | SerializeError(#[from] Box), 7 | 8 | #[error("Failed to access sled db")] 9 | SledError(#[from] sled::Error), 10 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/error.rs: -------------------------------------------------------------------------------- 1 | use thiserror::Error; 2 | 3 | #[derive(Debug, Error)] 4 | pub enum BlockchainError { 5 | #[error("Serialize or Deserialize error")] 6 | SerializeError(#[from] Box), 7 | 8 | #[error("Failed to access sled db")] 9 | SledError(#[from] sled::Error), 10 | } -------------------------------------------------------------------------------- /blockchain_rust_part_1/examples/gen_bc.rs: -------------------------------------------------------------------------------- 1 | use blockchain_rust_part_1::Blockchain; 2 | 3 | 4 | fn main() { 5 | tracing_subscriber::fmt().init(); 6 | 7 | let mut bc = Blockchain::new(); 8 | 9 | bc.mine_block("Justin -> Bob 2 btc"); 10 | bc.mine_block("Justin -> Bruce 2 btc"); 11 | 12 | bc.blocks_info(); 13 | } -------------------------------------------------------------------------------- /blockchain_rust_part_2/examples/gen_bc.rs: -------------------------------------------------------------------------------- 1 | use blockchain_rust_part_2::Blockchain; 2 | 3 | 4 | fn main() { 5 | tracing_subscriber::fmt().init(); 6 | 7 | let mut bc = Blockchain::new(); 8 | 9 | bc.mine_block("Justin -> Bob 2 btc"); 10 | // bc.mine_block("Justin -> Bruce 2 btc"); 11 | 12 | bc.blocks_info(); 13 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod error; 2 | mod utils; 3 | mod blocks; 4 | mod storage; 5 | mod transactions; 6 | 7 | pub use blocks::*; 8 | pub use storage::*; 9 | pub use transactions::*; 10 | 11 | #[cfg(test)] 12 | mod tests { 13 | #[test] 14 | fn it_works() { 15 | let result = 2 + 2; 16 | assert_eq!(result, 4); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod error; 2 | mod utils; 3 | mod blocks; 4 | mod storage; 5 | mod transactions; 6 | mod wallets; 7 | 8 | pub use blocks::*; 9 | pub use storage::*; 10 | pub use transactions::*; 11 | pub use wallets::*; 12 | 13 | #[cfg(test)] 14 | mod tests { 15 | #[test] 16 | fn it_works() { 17 | let result = 2 + 2; 18 | assert_eq!(result, 4); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /blockchain_rust_part_3/examples/gen_bc.rs: -------------------------------------------------------------------------------- 1 | use std::env::current_dir; 2 | 3 | use blockchain_rust_part_3::{Blockchain, SledDb}; 4 | 5 | 6 | fn main() { 7 | tracing_subscriber::fmt().init(); 8 | 9 | let path = current_dir().unwrap().join("data"); 10 | let mut bc = Blockchain::new(SledDb::new(path)); 11 | 12 | bc.mine_block("Justin -> Bob 2 btc"); 13 | bc.mine_block("Justin -> Bruce 2 btc"); 14 | 15 | bc.blocks_info(); 16 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod error; 2 | mod utils; 3 | mod blocks; 4 | mod storage; 5 | mod transactions; 6 | mod wallets; 7 | mod networks; 8 | 9 | pub use blocks::*; 10 | pub use storage::*; 11 | pub use transactions::*; 12 | pub use wallets::*; 13 | pub use networks::*; 14 | 15 | #[cfg(test)] 16 | mod tests { 17 | #[test] 18 | fn it_works() { 19 | let result = 2 + 2; 20 | assert_eq!(result, 4); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /blockchain_rust_part_4/examples/gen_bc.rs: -------------------------------------------------------------------------------- 1 | use std::{env::current_dir, sync::Arc}; 2 | 3 | use blockchain_rust_part_4::{Blockchain, SledDb, UTXOSet}; 4 | 5 | 6 | fn main() { 7 | tracing_subscriber::fmt().init(); 8 | 9 | let genesis_addr = "Justin"; 10 | 11 | let path = current_dir().unwrap().join("data"); 12 | let storage = Arc::new(SledDb::new(path)); 13 | 14 | let bc = Blockchain::new(storage.clone(), genesis_addr); 15 | let utxos = UTXOSet::new(storage); 16 | utxos.reindex(&bc).unwrap(); 17 | 18 | bc.blocks_info(); 19 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/server.rs: -------------------------------------------------------------------------------- 1 | use std::{env::{current_dir, self}, sync::Arc}; 2 | 3 | use anyhow::Result; 4 | use blockchain_rust_part_6::{Node, SledDb}; 5 | 6 | #[tokio::main] 7 | async fn main() -> Result<()> { 8 | tracing_subscriber::fmt::init(); 9 | 10 | let mut path = String::from("data"); 11 | if let Some(args) = env::args().nth(2) { 12 | path = args; 13 | } 14 | 15 | let path = current_dir().unwrap().join(path); 16 | let db = Arc::new(SledDb::new(path)); 17 | let mut node = Node::new(db).await?; 18 | node.start().await?; 19 | Ok(()) 20 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/transactions/tx_output.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | 3 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 4 | pub struct Txoutput { 5 | value: i32, 6 | to_addr: String, 7 | } 8 | 9 | impl Txoutput { 10 | pub fn new(value: i32, to_addr: &str) -> Self { 11 | Self { 12 | value, 13 | to_addr: to_addr.into(), 14 | } 15 | } 16 | 17 | pub fn is_locked(&self, address: &str) -> bool { 18 | self.to_addr.eq(address) 19 | } 20 | 21 | pub fn get_value(&self) -> i32 { 22 | self.value 23 | } 24 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/examples/gen_bc.rs: -------------------------------------------------------------------------------- 1 | use std::{env::current_dir, sync::Arc}; 2 | 3 | use blockchain_rust_part_5::{Blockchain, SledDb, UTXOSet, Wallets}; 4 | 5 | 6 | fn main() { 7 | tracing_subscriber::fmt().init(); 8 | 9 | let mut wallets = Wallets::new().unwrap(); 10 | let genesis_addr = wallets.create_wallet(); 11 | println!("==> genesis address: {}", genesis_addr); 12 | 13 | let path = current_dir().unwrap().join("data"); 14 | let storage = Arc::new(SledDb::new(path)); 15 | 16 | let bc = Blockchain::new(storage.clone(), &genesis_addr); 17 | let utxos = UTXOSet::new(storage); 18 | utxos.reindex(&bc).unwrap(); 19 | 20 | bc.blocks_info(); 21 | } -------------------------------------------------------------------------------- /blockchain_rust_part_2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blockchain_rust_part_2" 3 | authors = ["Justin "] 4 | version = "0.1.0" 5 | edition = "2021" 6 | readme = "README.md" 7 | homepage = "https://github.com/Justin02180218" 8 | repository = "https://github.com/Justin02180218" 9 | keywords = ["blockchain", "rust", "exercise"] 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | anyhow = "1" 15 | tracing = "0.1" 16 | tracing-subscriber = "0.2" 17 | thiserror = "1" 18 | serde = { version = "1", features = ["derive"] } 19 | bincode = "1.3.3" 20 | rust-crypto = "0.2.36" 21 | chrono = "0.4.19" 22 | bigint = "4.4.3" -------------------------------------------------------------------------------- /blockchain_rust_part_1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blockchain_rust_part_1" 3 | authors = ["Justin "] 4 | version = "0.1.0" 5 | edition = "2021" 6 | readme = "README.md" 7 | homepage = "https://github.com/Justin02180218/blockchain_rust" 8 | repository = "https://github.com/Justin02180218/blockchain_rust" 9 | keywords = ["blockchain", "rust", "exercise"] 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | anyhow = "1" 15 | tracing = "0.1" 16 | tracing-subscriber = "0.2" 17 | thiserror = "1" 18 | serde = { version = "1", features = ["derive"] } 19 | bincode = "1.3.3" 20 | rust-crypto = "0.2.36" 21 | chrono = "0.4.19" -------------------------------------------------------------------------------- /blockchain_rust_part_3/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blockchain_rust_part_3" 3 | authors = ["Justin "] 4 | version = "0.1.0" 5 | edition = "2021" 6 | readme = "README.md" 7 | homepage = "https://github.com/Justin02180218" 8 | repository = "https://github.com/Justin02180218" 9 | keywords = ["blockchain", "rust", "exercise"] 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | anyhow = "1" 15 | tracing = "0.1" 16 | tracing-subscriber = "0.2" 17 | thiserror = "1" 18 | serde = { version = "1", features = ["derive"] } 19 | bincode = "1.3.3" 20 | rust-crypto = "0.2.36" 21 | chrono = "0.4.19" 22 | bigint = "4.4.3" 23 | sled = "0.34" 24 | -------------------------------------------------------------------------------- /blockchain_rust_part_4/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blockchain_rust_part_4" 3 | authors = ["Justin "] 4 | version = "0.1.0" 5 | edition = "2021" 6 | readme = "README.md" 7 | homepage = "https://github.com/Justin02180218" 8 | repository = "https://github.com/Justin02180218" 9 | keywords = ["blockchain", "rust", "exercise"] 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | anyhow = "1" 15 | tracing = "0.1" 16 | tracing-subscriber = "0.2" 17 | thiserror = "1" 18 | serde = { version = "1", features = ["derive"] } 19 | bincode = "1.3.3" 20 | rust-crypto = "0.2.36" 21 | chrono = "0.4.19" 22 | bigint = "4.4.3" 23 | sled = "0.34" 24 | -------------------------------------------------------------------------------- /blockchain_rust_part_6/examples/gen_bc.rs: -------------------------------------------------------------------------------- 1 | use std::{env::current_dir, sync::Arc}; 2 | 3 | use blockchain_rust_part_6::{Blockchain, SledDb, UTXOSet, Wallets}; 4 | 5 | 6 | fn main() { 7 | tracing_subscriber::fmt().init(); 8 | 9 | let mut wallets = Wallets::new().unwrap(); 10 | let genesis_addr = wallets.create_wallet(); 11 | println!("==> genesis address: {}", genesis_addr); 12 | 13 | let path = current_dir().unwrap().join("data"); 14 | let storage = Arc::new(SledDb::new(path)); 15 | 16 | let mut bc = Blockchain::new(storage.clone()); 17 | bc.create_genesis_block(&genesis_addr); 18 | 19 | let utxos = UTXOSet::new(storage); 20 | utxos.reindex(&bc).unwrap(); 21 | 22 | bc.blocks_info(); 23 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/networks/command.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | 3 | use crate::Block; 4 | 5 | #[derive(Debug, Serialize, Deserialize)] 6 | pub enum Commands { 7 | Genesis(String), 8 | Blocks(String), 9 | Sync(String), 10 | CreateWallet(String), 11 | GetAddress(String), 12 | Trans { 13 | from: String, 14 | to: String, 15 | amount: String, 16 | }, 17 | } 18 | 19 | #[derive(Debug, Serialize, Deserialize)] 20 | pub enum Messages { 21 | Version { 22 | best_height: usize, 23 | from_addr: String, 24 | }, 25 | Blocks { 26 | blocks: Vec, 27 | height: usize, 28 | to_addr: String, 29 | }, 30 | Block { 31 | block: Block, 32 | } 33 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/transactions/tx_input.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | 3 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 4 | pub struct Txinput { 5 | txid: String, 6 | vout: usize, 7 | from_addr: String, 8 | } 9 | 10 | impl Txinput { 11 | pub fn new(txid: String, vout: usize, from_addr: &str) -> Self { 12 | Self { 13 | txid, 14 | vout, 15 | from_addr: from_addr.into(), 16 | } 17 | } 18 | 19 | pub fn can_unlock_output(&self, address: &str) -> bool { 20 | self.from_addr.eq(address) 21 | } 22 | 23 | pub fn get_txid(&self) -> String { 24 | self.txid.clone() 25 | } 26 | 27 | pub fn get_vout(&self) -> usize { 28 | self.vout 29 | } 30 | } -------------------------------------------------------------------------------- /blockchain_rust_part_1/src/blocks/blockchain.rs: -------------------------------------------------------------------------------- 1 | use tracing::info; 2 | 3 | use crate::Block; 4 | 5 | pub struct Blockchain { 6 | blocks: Vec, 7 | height: usize, 8 | } 9 | 10 | impl Blockchain { 11 | pub fn new() -> Self { 12 | Self { 13 | blocks: vec![Block::create_genesis_block()], 14 | height: 0, 15 | } 16 | } 17 | 18 | pub fn mine_block(&mut self, data: &str) { 19 | let prev_block = self.blocks.last().unwrap(); 20 | let block = Block::new(data, prev_block.get_hash().as_str()); 21 | self.blocks.push(block); 22 | self.height += 1; 23 | } 24 | 25 | pub fn blocks_info(&self) { 26 | for block in self.blocks.iter() { 27 | info!("{:#?}", block); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blockchain_rust_part_5" 3 | authors = ["Justin "] 4 | version = "0.1.0" 5 | edition = "2021" 6 | readme = "README.md" 7 | homepage = "https://github.com/Justin02180218" 8 | repository = "https://github.com/Justin02180218" 9 | keywords = ["blockchain", "rust", "exercise"] 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | anyhow = "1" 15 | tracing = "0.1" 16 | tracing-subscriber = "0.2" 17 | thiserror = "1" 18 | serde = { version = "1", features = ["derive"] } 19 | bincode = "1.3.3" 20 | rust-crypto = "0.2.36" 21 | chrono = "0.4.19" 22 | bigint = "4.4.3" 23 | sled = "0.34" 24 | ring = "0.16.20" 25 | rustc-serialize = "0.3.24" 26 | bs58 = "0.4.0" -------------------------------------------------------------------------------- /blockchain_rust_part_2/src/blocks/blockchain.rs: -------------------------------------------------------------------------------- 1 | use tracing::info; 2 | 3 | use crate::Block; 4 | 5 | const CURR_BITS: usize = 8; 6 | 7 | pub struct Blockchain { 8 | blocks: Vec, 9 | height: usize, 10 | } 11 | 12 | impl Blockchain { 13 | pub fn new() -> Self { 14 | Self { 15 | blocks: vec![Block::create_genesis_block(CURR_BITS)], 16 | height: 0, 17 | } 18 | } 19 | 20 | pub fn mine_block(&mut self, data: &str) { 21 | let prev_block = self.blocks.last().unwrap(); 22 | let block = Block::new(data, prev_block.get_hash().as_str(), CURR_BITS); 23 | self.blocks.push(block); 24 | self.height += 1; 25 | } 26 | 27 | pub fn blocks_info(&self) { 28 | for block in self.blocks.iter() { 29 | info!("{:#?}", block); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/examples/gen_trx.rs: -------------------------------------------------------------------------------- 1 | use std::{env::current_dir, sync::Arc}; 2 | 3 | use blockchain_rust_part_4::{Blockchain, SledDb, UTXOSet, Transaction}; 4 | 5 | 6 | fn main() { 7 | tracing_subscriber::fmt().init(); 8 | 9 | let justin_addr = "Justin"; 10 | let bob_addr = "Bob"; 11 | // let bruce_addr = "Bruce"; 12 | 13 | let path = current_dir().unwrap().join("data"); 14 | let storage = Arc::new(SledDb::new(path)); 15 | 16 | let mut bc = Blockchain::new(storage.clone(), justin_addr); 17 | let utxos = UTXOSet::new(storage); 18 | 19 | let tx_1 = Transaction::new_utxo(justin_addr, bob_addr, 4, &utxos); 20 | // let tx_2 = Transaction::new_utxo(justin_addr, bruce_addr, 2, &utxos); 21 | 22 | let txs = vec![tx_1]; 23 | 24 | bc.mine_block(&txs); 25 | utxos.reindex(&bc).unwrap(); 26 | 27 | bc.blocks_info(); 28 | } -------------------------------------------------------------------------------- /blockchain_rust_part_2/src/utils/serializer.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use crypto::{sha3::Sha3, digest::Digest}; 3 | use serde::{Serialize, Deserialize}; 4 | 5 | use crate::error::BlockchainError; 6 | 7 | pub fn serialize(data: &T) -> Result, BlockchainError> 8 | where 9 | T: Serialize + ?Sized 10 | { 11 | Ok(bincode::serialize(data)?) 12 | } 13 | 14 | #[allow(dead_code)] 15 | pub fn deserialize<'a, T>(data: &'a [u8]) -> Result 16 | where 17 | T: Deserialize<'a> + ?Sized 18 | { 19 | Ok(bincode::deserialize(data)?) 20 | } 21 | 22 | pub fn hash_to_str(data: &[u8]) -> String { 23 | let mut hasher = Sha3::sha3_256(); 24 | hasher.input(data); 25 | hasher.result_str() 26 | } 27 | 28 | pub fn hash_to_u8(data: &[u8], out: &mut [u8]) { 29 | let mut hasher = Sha3::sha3_256(); 30 | hasher.input(data); 31 | hasher.result(out); 32 | } -------------------------------------------------------------------------------- /blockchain_rust_part_3/src/utils/serializer.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use crypto::{sha3::Sha3, digest::Digest}; 3 | use serde::{Serialize, Deserialize}; 4 | 5 | use crate::error::BlockchainError; 6 | 7 | pub fn serialize(data: &T) -> Result, BlockchainError> 8 | where 9 | T: Serialize + ?Sized 10 | { 11 | Ok(bincode::serialize(data)?) 12 | } 13 | 14 | #[allow(dead_code)] 15 | pub fn deserialize<'a, T>(data: &'a [u8]) -> Result 16 | where 17 | T: Deserialize<'a> + ?Sized 18 | { 19 | Ok(bincode::deserialize(data)?) 20 | } 21 | 22 | pub fn hash_to_str(data: &[u8]) -> String { 23 | let mut hasher = Sha3::sha3_256(); 24 | hasher.input(data); 25 | hasher.result_str() 26 | } 27 | 28 | pub fn hash_to_u8(data: &[u8], out: &mut [u8]) { 29 | let mut hasher = Sha3::sha3_256(); 30 | hasher.input(data); 31 | hasher.result(out); 32 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/utils/serializer.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use crypto::{sha3::Sha3, digest::Digest}; 3 | use serde::{Serialize, Deserialize}; 4 | 5 | use crate::error::BlockchainError; 6 | 7 | pub fn serialize(data: &T) -> Result, BlockchainError> 8 | where 9 | T: Serialize + ?Sized 10 | { 11 | Ok(bincode::serialize(data)?) 12 | } 13 | 14 | #[allow(dead_code)] 15 | pub fn deserialize<'a, T>(data: &'a [u8]) -> Result 16 | where 17 | T: Deserialize<'a> + ?Sized 18 | { 19 | Ok(bincode::deserialize(data)?) 20 | } 21 | 22 | pub fn hash_to_str(data: &[u8]) -> String { 23 | let mut hasher = Sha3::sha3_256(); 24 | hasher.input(data); 25 | hasher.result_str() 26 | } 27 | 28 | pub fn hash_to_u8(data: &[u8], out: &mut [u8]) { 29 | let mut hasher = Sha3::sha3_256(); 30 | hasher.input(data); 31 | hasher.result(out); 32 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/utils/serializer.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use crypto::{sha3::Sha3, digest::Digest}; 3 | use serde::{Serialize, Deserialize}; 4 | 5 | use crate::error::BlockchainError; 6 | 7 | pub fn serialize(data: &T) -> Result, BlockchainError> 8 | where 9 | T: Serialize + ?Sized 10 | { 11 | Ok(bincode::serialize(data)?) 12 | } 13 | 14 | #[allow(dead_code)] 15 | pub fn deserialize<'a, T>(data: &'a [u8]) -> Result 16 | where 17 | T: Deserialize<'a> + ?Sized 18 | { 19 | Ok(bincode::deserialize(data)?) 20 | } 21 | 22 | pub fn hash_to_str(data: &[u8]) -> String { 23 | let mut hasher = Sha3::sha3_256(); 24 | hasher.input(data); 25 | hasher.result_str() 26 | } 27 | 28 | pub fn hash_to_u8(data: &[u8], out: &mut [u8]) { 29 | let mut hasher = Sha3::sha3_256(); 30 | hasher.input(data); 31 | hasher.result(out); 32 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/utils/serializer.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use crypto::{sha3::Sha3, digest::Digest}; 3 | use serde::{Serialize, Deserialize}; 4 | 5 | use crate::error::BlockchainError; 6 | 7 | pub fn serialize(data: &T) -> Result, BlockchainError> 8 | where 9 | T: Serialize + ?Sized 10 | { 11 | Ok(bincode::serialize(data)?) 12 | } 13 | 14 | #[allow(dead_code)] 15 | pub fn deserialize<'a, T>(data: &'a [u8]) -> Result 16 | where 17 | T: Deserialize<'a> + ?Sized 18 | { 19 | Ok(bincode::deserialize(data)?) 20 | } 21 | 22 | pub fn hash_to_str(data: &[u8]) -> String { 23 | let mut hasher = Sha3::sha3_256(); 24 | hasher.input(data); 25 | hasher.result_str() 26 | } 27 | 28 | pub fn hash_to_u8(data: &[u8], out: &mut [u8]) { 29 | let mut hasher = Sha3::sha3_256(); 30 | hasher.input(data); 31 | hasher.result(out); 32 | } -------------------------------------------------------------------------------- /blockchain_rust_part_1/src/utils/serializer.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use crypto::{sha3::Sha3, digest::Digest}; 3 | use serde::{Serialize, Deserialize}; 4 | 5 | use crate::error::BlockchainError; 6 | 7 | pub fn serialize(data: &T) -> Result, BlockchainError> 8 | where 9 | T: Serialize + ?Sized 10 | { 11 | Ok(bincode::serialize(data)?) 12 | } 13 | 14 | #[allow(dead_code)] 15 | pub fn deserialize<'a, T>(data: &'a [u8]) -> Result 16 | where 17 | T: Deserialize<'a> + ?Sized 18 | { 19 | Ok(bincode::deserialize(data)?) 20 | } 21 | 22 | pub fn hash_to_str(data: &[u8]) -> String { 23 | let mut hasher = Sha3::sha3_256(); 24 | hasher.input(data); 25 | hasher.result_str() 26 | } 27 | 28 | #[allow(dead_code)] 29 | pub fn hash_to_u8(data: &[u8], out: &mut [u8]) { 30 | let mut hasher = Sha3::sha3_256(); 31 | hasher.input(data); 32 | hasher.result(out); 33 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/examples/gen_trx.rs: -------------------------------------------------------------------------------- 1 | use std::{env::current_dir, sync::Arc}; 2 | 3 | use blockchain_rust_part_6::{Blockchain, SledDb, UTXOSet, Transaction, Wallets}; 4 | 5 | 6 | fn main() { 7 | tracing_subscriber::fmt().init(); 8 | 9 | let justin_addr = "1527MzPRt2eTh9GGrHKRX3qkCj6oA4w54F"; 10 | 11 | let mut wallets = Wallets::new().unwrap(); 12 | let bob_addr = wallets.create_wallet(); 13 | let bruce_addr = wallets.create_wallet(); 14 | 15 | let path = current_dir().unwrap().join("data"); 16 | let storage = Arc::new(SledDb::new(path)); 17 | 18 | let mut bc = Blockchain::new(storage.clone()); 19 | let utxos = UTXOSet::new(storage); 20 | 21 | let tx_1 = Transaction::new_utxo(justin_addr, &bob_addr, 4, &utxos, &bc); 22 | let tx_2 = Transaction::new_utxo(justin_addr, &bruce_addr, 2, &utxos, &bc); 23 | 24 | let txs = vec![tx_1, tx_2]; 25 | 26 | bc.mine_block(&txs); 27 | utxos.reindex(&bc).unwrap(); 28 | 29 | bc.blocks_info(); 30 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/examples/gen_trx.rs: -------------------------------------------------------------------------------- 1 | use std::{env::current_dir, sync::Arc}; 2 | 3 | use blockchain_rust_part_5::{Blockchain, SledDb, UTXOSet, Transaction, Wallets}; 4 | 5 | 6 | fn main() { 7 | tracing_subscriber::fmt().init(); 8 | 9 | let justin_addr = "1M684nX5dTNQYi2ELSCazjyz5dgegJ3mVD"; 10 | 11 | let mut wallets = Wallets::new().unwrap(); 12 | let bob_addr = wallets.create_wallet(); 13 | let bruce_addr = wallets.create_wallet(); 14 | 15 | let path = current_dir().unwrap().join("data"); 16 | let storage = Arc::new(SledDb::new(path)); 17 | 18 | let mut bc = Blockchain::new(storage.clone(), justin_addr); 19 | let utxos = UTXOSet::new(storage); 20 | 21 | let tx_1 = Transaction::new_utxo(justin_addr, &bob_addr, 4, &utxos, &bc); 22 | let tx_2 = Transaction::new_utxo(justin_addr, &bruce_addr, 2, &utxos, &bc); 23 | 24 | let txs = vec![tx_1, tx_2]; 25 | 26 | bc.mine_block(&txs); 27 | utxos.reindex(&bc).unwrap(); 28 | 29 | bc.blocks_info(); 30 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blockchain_rust_part_6" 3 | authors = ["Justin "] 4 | version = "0.1.0" 5 | edition = "2021" 6 | readme = "README.md" 7 | homepage = "https://github.com/Justin02180218" 8 | repository = "https://github.com/Justin02180218" 9 | keywords = ["blockchain", "rust", "exercise"] 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [[bin]] 14 | name = "server" 15 | path = "src/server.rs" 16 | 17 | [dependencies] 18 | anyhow = "1" 19 | tracing = "0.1" 20 | tracing-subscriber = "0.2" 21 | thiserror = "1" 22 | serde = { version = "1", features = ["derive"] } 23 | serde_json = "1.0.79" 24 | bincode = "1.3.3" 25 | rust-crypto = "0.2.36" 26 | chrono = "0.4.19" 27 | bigint = "4.4.3" 28 | sled = "0.34" 29 | ring = "0.16.20" 30 | rustc-serialize = "0.3.24" 31 | bs58 = "0.4.0" 32 | futures = "0.3" 33 | libp2p = { version = "0.39", features = ["tcp-tokio"] } 34 | tokio = { version = "1", features = ["full"] } 35 | tokio-util = { version = "0.6", features = ["codec"] } 36 | once_cell = "1.10.0" 37 | -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/transactions/tx_output.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | 3 | use crate::{utils::base58_decode, ADDRESS_CHECKSUM_LEN}; 4 | 5 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 6 | pub struct Txoutput { 7 | value: i32, 8 | pub_key_hash: Vec, 9 | } 10 | 11 | impl Txoutput { 12 | pub fn new(value: i32, to_addr: &str) -> Self { 13 | let mut output = Txoutput { 14 | value, 15 | pub_key_hash: vec![], 16 | }; 17 | output.lock(to_addr); 18 | output 19 | } 20 | 21 | fn lock(&mut self, address: &str) { 22 | let payload = base58_decode(address); 23 | let pub_key_hash = payload[1..payload.len() - ADDRESS_CHECKSUM_LEN].to_vec(); 24 | self.pub_key_hash = pub_key_hash 25 | } 26 | 27 | pub fn is_locked(&self, pub_key_hash: &[u8]) -> bool { 28 | self.pub_key_hash.eq(pub_key_hash) 29 | } 30 | 31 | pub fn get_value(&self) -> i32 { 32 | self.value 33 | } 34 | 35 | pub fn get_pub_key_hash(&self) -> &[u8] { 36 | self.pub_key_hash.as_slice() 37 | } 38 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/transactions/tx_output.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | 3 | use crate::{utils::base58_decode, ADDRESS_CHECKSUM_LEN}; 4 | 5 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 6 | pub struct Txoutput { 7 | value: i32, 8 | pub_key_hash: Vec, 9 | } 10 | 11 | impl Txoutput { 12 | pub fn new(value: i32, to_addr: &str) -> Self { 13 | let mut output = Txoutput { 14 | value, 15 | pub_key_hash: vec![], 16 | }; 17 | output.lock(to_addr); 18 | output 19 | } 20 | 21 | fn lock(&mut self, address: &str) { 22 | let payload = base58_decode(address); 23 | let pub_key_hash = payload[1..payload.len() - ADDRESS_CHECKSUM_LEN].to_vec(); 24 | self.pub_key_hash = pub_key_hash 25 | } 26 | 27 | pub fn is_locked(&self, pub_key_hash: &[u8]) -> bool { 28 | self.pub_key_hash.eq(pub_key_hash) 29 | } 30 | 31 | pub fn get_value(&self) -> i32 { 32 | self.value 33 | } 34 | 35 | pub fn get_pub_key_hash(&self) -> &[u8] { 36 | self.pub_key_hash.as_slice() 37 | } 38 | } -------------------------------------------------------------------------------- /blockchain_rust_part_3/src/storage/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::{error::BlockchainError, Block}; 2 | 3 | mod sleddb; 4 | 5 | pub use sleddb::SledDb; 6 | 7 | pub const TIP_KEY: &str = "tip_hash"; 8 | pub const HEIGHT: &str = "height"; 9 | pub const TABLE_OF_BLOCK: &str = "blocks"; 10 | 11 | pub trait Storage: Send + Sync + 'static { 12 | fn get_tip(&self) -> Result, BlockchainError>; 13 | fn get_block(&self, key: &str) -> Result, BlockchainError>; 14 | fn get_height(&self) -> Result, BlockchainError>; 15 | fn update_blocks(&self, key: &str, block: &Block, height: usize); 16 | fn get_block_iter(&self) -> Result>, BlockchainError>; 17 | } 18 | 19 | pub struct StorageIterator { 20 | data: T 21 | } 22 | 23 | impl StorageIterator { 24 | pub fn new(data: T) -> Self { 25 | Self { data } 26 | } 27 | } 28 | 29 | impl Iterator for StorageIterator 30 | where 31 | T: Iterator, 32 | T::Item: Into 33 | { 34 | type Item = Block; 35 | 36 | fn next(&mut self) -> Option { 37 | self.data.next().map(|v| v.into()) 38 | } 39 | } -------------------------------------------------------------------------------- /blockchain_rust_part_1/src/blocks/block.rs: -------------------------------------------------------------------------------- 1 | use chrono::Utc; 2 | use serde::{Serialize, Deserialize}; 3 | 4 | use crate::utils::{serialize, hash_to_str}; 5 | 6 | #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] 7 | pub struct BlockHeader { 8 | timestamp: i64, 9 | prev_hash: String, 10 | nonce: usize, 11 | } 12 | 13 | #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] 14 | pub struct Block { 15 | header: BlockHeader, 16 | data: String, 17 | hash: String, 18 | } 19 | 20 | impl Block { 21 | pub fn new(data: &str, prev_hash: &str) -> Self { 22 | let mut block = Block { 23 | header: BlockHeader { 24 | timestamp: Utc::now().timestamp(), 25 | prev_hash: prev_hash.into(), 26 | nonce: 0, 27 | }, 28 | data: data.into(), 29 | hash: String::new(), 30 | }; 31 | block.set_hash(); 32 | 33 | block 34 | } 35 | 36 | pub fn create_genesis_block() -> Self { 37 | Self::new("创世区块", "") 38 | } 39 | 40 | pub fn get_hash(&self) -> String { 41 | self.hash.clone() 42 | } 43 | 44 | fn set_hash(&mut self) { 45 | if let Ok(serialized) = serialize(&self.header) { 46 | self.hash = hash_to_str(&serialized) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /blockchain_rust_part_2/src/blocks/pow.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use std::ops::Shl; 3 | use bigint::U256; 4 | use crate::{utils::{serialize, hash_to_u8, hash_to_str}, Block}; 5 | 6 | const MAX_NONCE: usize = usize::MAX; 7 | 8 | pub struct ProofOfWork { 9 | target: U256, 10 | } 11 | 12 | impl ProofOfWork { 13 | pub fn new(bits: usize) -> Self { 14 | let mut target = U256::from(1 as usize); 15 | target = target.shl(256 - bits); 16 | 17 | Self { 18 | target 19 | } 20 | } 21 | 22 | pub fn run(&self, block: &mut Block) { 23 | let mut nonce = 0; 24 | while nonce < MAX_NONCE { 25 | if let Ok(pre_hash) = Self::prepare_data(block, nonce) { 26 | let mut hash_u: [u8; 32] = [0; 32]; 27 | hash_to_u8(&pre_hash,&mut hash_u); 28 | let pre_hash_int = U256::from(hash_u); 29 | 30 | if pre_hash_int.lt(&(self.target)) { 31 | block.set_hash(hash_to_str(&pre_hash)); 32 | break; 33 | }else { 34 | nonce += 1; 35 | } 36 | } 37 | } 38 | } 39 | 40 | fn prepare_data(block: &mut Block, nonce: usize) -> Result> { 41 | block.set_nonce(nonce); 42 | Ok(serialize(&(block.get_header()))?) 43 | } 44 | } -------------------------------------------------------------------------------- /blockchain_rust_part_3/src/blocks/pow.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use std::ops::Shl; 3 | use bigint::U256; 4 | use crate::{utils::{serialize, hash_to_u8, hash_to_str}, Block}; 5 | 6 | const MAX_NONCE: usize = usize::MAX; 7 | 8 | pub struct ProofOfWork { 9 | target: U256, 10 | } 11 | 12 | impl ProofOfWork { 13 | pub fn new(bits: usize) -> Self { 14 | let mut target = U256::from(1 as usize); 15 | target = target.shl(256 - bits); 16 | 17 | Self { 18 | target 19 | } 20 | } 21 | 22 | pub fn run(&self, block: &mut Block) { 23 | let mut nonce = 0; 24 | while nonce < MAX_NONCE { 25 | if let Ok(pre_hash) = Self::prepare_data(block, nonce) { 26 | let mut hash_u: [u8; 32] = [0; 32]; 27 | hash_to_u8(&pre_hash,&mut hash_u); 28 | let pre_hash_int = U256::from(hash_u); 29 | 30 | if pre_hash_int.lt(&(self.target)) { 31 | block.set_hash(hash_to_str(&pre_hash)); 32 | break; 33 | }else { 34 | nonce += 1; 35 | } 36 | } 37 | } 38 | } 39 | 40 | fn prepare_data(block: &mut Block, nonce: usize) -> Result> { 41 | block.set_nonce(nonce); 42 | Ok(serialize(&(block.get_header()))?) 43 | } 44 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/blocks/pow.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use std::ops::Shl; 3 | use bigint::U256; 4 | use crate::{utils::{serialize, hash_to_u8, hash_to_str}, Block}; 5 | 6 | const MAX_NONCE: usize = usize::MAX; 7 | 8 | pub struct ProofOfWork { 9 | target: U256, 10 | } 11 | 12 | impl ProofOfWork { 13 | pub fn new(bits: usize) -> Self { 14 | let mut target = U256::from(1 as usize); 15 | target = target.shl(256 - bits); 16 | 17 | Self { 18 | target 19 | } 20 | } 21 | 22 | pub fn run(&self, block: &mut Block) { 23 | let mut nonce = 0; 24 | while nonce < MAX_NONCE { 25 | if let Ok(pre_hash) = Self::prepare_data(block, nonce) { 26 | let mut hash_u: [u8; 32] = [0; 32]; 27 | hash_to_u8(&pre_hash,&mut hash_u); 28 | let pre_hash_int = U256::from(hash_u); 29 | 30 | if pre_hash_int.lt(&(self.target)) { 31 | block.set_hash(hash_to_str(&pre_hash)); 32 | break; 33 | }else { 34 | nonce += 1; 35 | } 36 | } 37 | } 38 | } 39 | 40 | fn prepare_data(block: &mut Block, nonce: usize) -> Result> { 41 | block.set_nonce(nonce); 42 | Ok(serialize(&(block.get_header()))?) 43 | } 44 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/blocks/pow.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use std::ops::Shl; 3 | use bigint::U256; 4 | use crate::{utils::{serialize, hash_to_u8, hash_to_str}, Block}; 5 | 6 | const MAX_NONCE: usize = usize::MAX; 7 | 8 | pub struct ProofOfWork { 9 | target: U256, 10 | } 11 | 12 | impl ProofOfWork { 13 | pub fn new(bits: usize) -> Self { 14 | let mut target = U256::from(1 as usize); 15 | target = target.shl(256 - bits); 16 | 17 | Self { 18 | target 19 | } 20 | } 21 | 22 | pub fn run(&self, block: &mut Block) { 23 | let mut nonce = 0; 24 | while nonce < MAX_NONCE { 25 | if let Ok(pre_hash) = Self::prepare_data(block, nonce) { 26 | let mut hash_u: [u8; 32] = [0; 32]; 27 | hash_to_u8(&pre_hash,&mut hash_u); 28 | let pre_hash_int = U256::from(hash_u); 29 | 30 | if pre_hash_int.lt(&(self.target)) { 31 | block.set_hash(hash_to_str(&pre_hash)); 32 | break; 33 | }else { 34 | nonce += 1; 35 | } 36 | } 37 | } 38 | } 39 | 40 | fn prepare_data(block: &mut Block, nonce: usize) -> Result> { 41 | block.set_nonce(nonce); 42 | Ok(serialize(&(block.get_header()))?) 43 | } 44 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/transactions/tx_input.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | 3 | use crate::hash_pub_key; 4 | 5 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 6 | pub struct Txinput { 7 | txid: String, 8 | vout: usize, 9 | signature: Vec, 10 | pub_key: Vec 11 | } 12 | 13 | impl Txinput { 14 | pub fn new(txid: String, vout: usize, pub_key: Vec) -> Self { 15 | Self { 16 | txid, 17 | vout, 18 | signature: vec![], 19 | pub_key, 20 | } 21 | } 22 | 23 | pub fn can_unlock_output(&self, pub_key_hash: &[u8]) -> bool { 24 | let locked_hash = hash_pub_key(&self.pub_key); 25 | locked_hash.eq(pub_key_hash) 26 | } 27 | 28 | pub fn get_txid(&self) -> String { 29 | self.txid.clone() 30 | } 31 | 32 | pub fn get_vout(&self) -> usize { 33 | self.vout 34 | } 35 | 36 | pub fn get_pub_key(&self) -> &[u8] { 37 | self.pub_key.as_slice() 38 | } 39 | 40 | pub fn get_signature(&self) -> &[u8] { 41 | self.signature.as_slice() 42 | } 43 | 44 | pub fn set_signature(&mut self, signature: Vec) { 45 | self.signature = signature 46 | } 47 | 48 | pub fn set_pub_key(&mut self, pub_key: &[u8]) { 49 | self.pub_key = pub_key.to_vec(); 50 | } 51 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/blocks/pow.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use std::ops::Shl; 3 | use bigint::U256; 4 | use crate::{utils::{serialize, hash_to_u8, hash_to_str}, Block}; 5 | 6 | const MAX_NONCE: usize = usize::MAX; 7 | 8 | pub struct ProofOfWork { 9 | target: U256, 10 | } 11 | 12 | impl ProofOfWork { 13 | pub fn new(bits: usize) -> Self { 14 | let mut target = U256::from(1 as usize); 15 | target = target.shl(256 - bits); 16 | 17 | Self { 18 | target 19 | } 20 | } 21 | 22 | pub fn run(&self, block: &mut Block) { 23 | let mut nonce = 0; 24 | while nonce < MAX_NONCE { 25 | if let Ok(pre_hash) = Self::prepare_data(block, nonce) { 26 | let mut hash_u: [u8; 32] = [0; 32]; 27 | hash_to_u8(&pre_hash,&mut hash_u); 28 | let pre_hash_int = U256::from(hash_u); 29 | 30 | if pre_hash_int.lt(&(self.target)) { 31 | block.set_hash(hash_to_str(&pre_hash)); 32 | break; 33 | }else { 34 | nonce += 1; 35 | } 36 | } 37 | } 38 | } 39 | 40 | fn prepare_data(block: &mut Block, nonce: usize) -> Result> { 41 | block.set_nonce(nonce); 42 | Ok(serialize(&(block.get_header()))?) 43 | } 44 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/transactions/tx_input.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | 3 | use crate::hash_pub_key; 4 | 5 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 6 | pub struct Txinput { 7 | txid: String, 8 | vout: usize, 9 | signature: Vec, 10 | pub_key: Vec 11 | } 12 | 13 | impl Txinput { 14 | pub fn new(txid: String, vout: usize, pub_key: Vec) -> Self { 15 | Self { 16 | txid, 17 | vout, 18 | signature: vec![], 19 | pub_key, 20 | } 21 | } 22 | 23 | pub fn can_unlock_output(&self, pub_key_hash: &[u8]) -> bool { 24 | let locked_hash = hash_pub_key(&self.pub_key); 25 | locked_hash.eq(pub_key_hash) 26 | } 27 | 28 | pub fn get_txid(&self) -> String { 29 | self.txid.clone() 30 | } 31 | 32 | pub fn get_vout(&self) -> usize { 33 | self.vout 34 | } 35 | 36 | pub fn get_pub_key(&self) -> &[u8] { 37 | self.pub_key.as_slice() 38 | } 39 | 40 | pub fn get_signature(&self) -> &[u8] { 41 | self.signature.as_slice() 42 | } 43 | 44 | pub fn set_signature(&mut self, signature: Vec) { 45 | self.signature = signature 46 | } 47 | 48 | pub fn set_pub_key(&mut self, pub_key: &[u8]) { 49 | self.pub_key = pub_key.to_vec(); 50 | } 51 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/storage/mod.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use crate::{error::BlockchainError, Block, Txoutput}; 4 | 5 | mod sleddb; 6 | 7 | pub use sleddb::SledDb; 8 | 9 | pub const TIP_KEY: &str = "tip_hash"; 10 | pub const HEIGHT: &str = "height"; 11 | pub const TABLE_OF_BLOCK: &str = "blocks"; 12 | pub const UTXO_SET: &str = "utxos"; 13 | 14 | pub trait Storage: Send + Sync + 'static { 15 | fn get_tip(&self) -> Result, BlockchainError>; 16 | fn get_block(&self, key: &str) -> Result, BlockchainError>; 17 | fn get_height(&self) -> Result, BlockchainError>; 18 | fn update_blocks(&self, key: &str, block: &Block, height: usize); 19 | fn get_block_iter(&self) -> Result>, BlockchainError>; 20 | 21 | fn get_utxo_set(&self) -> HashMap>; 22 | fn write_utxo(&self, txid: &str, outs: Vec) -> Result<(), BlockchainError>; 23 | fn clear_utxo_set(&self); 24 | } 25 | 26 | pub struct StorageIterator { 27 | data: T 28 | } 29 | 30 | impl StorageIterator { 31 | pub fn new(data: T) -> Self { 32 | Self { data } 33 | } 34 | } 35 | 36 | impl Iterator for StorageIterator 37 | where 38 | T: Iterator, 39 | T::Item: Into 40 | { 41 | type Item = Block; 42 | 43 | fn next(&mut self) -> Option { 44 | self.data.next().map(|v| v.into()) 45 | } 46 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/storage/mod.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use crate::{error::BlockchainError, Block, Txoutput}; 4 | 5 | mod sleddb; 6 | 7 | pub use sleddb::SledDb; 8 | 9 | pub const TIP_KEY: &str = "tip_hash"; 10 | pub const HEIGHT: &str = "height"; 11 | pub const TABLE_OF_BLOCK: &str = "blocks"; 12 | pub const UTXO_SET: &str = "utxos"; 13 | 14 | pub trait Storage: Send + Sync + 'static { 15 | fn get_tip(&self) -> Result, BlockchainError>; 16 | fn get_block(&self, key: &str) -> Result, BlockchainError>; 17 | fn get_height(&self) -> Result, BlockchainError>; 18 | fn update_blocks(&self, key: &str, block: &Block, height: usize); 19 | fn get_block_iter(&self) -> Result>, BlockchainError>; 20 | 21 | fn get_utxo_set(&self) -> HashMap>; 22 | fn write_utxo(&self, txid: &str, outs: Vec) -> Result<(), BlockchainError>; 23 | fn clear_utxo_set(&self); 24 | } 25 | 26 | pub struct StorageIterator { 27 | data: T 28 | } 29 | 30 | impl StorageIterator { 31 | pub fn new(data: T) -> Self { 32 | Self { data } 33 | } 34 | } 35 | 36 | impl Iterator for StorageIterator 37 | where 38 | T: Iterator, 39 | T::Item: Into 40 | { 41 | type Item = Block; 42 | 43 | fn next(&mut self) -> Option { 44 | self.data.next().map(|v| v.into()) 45 | } 46 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/storage/mod.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use crate::{error::BlockchainError, Block, Txoutput}; 4 | 5 | mod sleddb; 6 | 7 | pub use sleddb::SledDb; 8 | 9 | pub const TIP_KEY: &str = "tip_hash"; 10 | pub const HEIGHT: &str = "height"; 11 | pub const TABLE_OF_BLOCK: &str = "blocks"; 12 | pub const UTXO_SET: &str = "utxos"; 13 | 14 | pub trait Storage: Send + Sync + 'static { 15 | fn get_tip(&self) -> Result, BlockchainError>; 16 | fn get_block(&self, key: &str) -> Result, BlockchainError>; 17 | fn get_height(&self) -> Result, BlockchainError>; 18 | fn update_blocks(&self, key: &str, block: &Block, height: usize); 19 | fn get_block_iter(&self) -> Result>, BlockchainError>; 20 | 21 | fn get_utxo_set(&self) -> HashMap>; 22 | fn write_utxo(&self, txid: &str, outs: Vec) -> Result<(), BlockchainError>; 23 | fn clear_utxo_set(&self); 24 | } 25 | 26 | pub struct StorageIterator { 27 | data: T 28 | } 29 | 30 | impl StorageIterator { 31 | pub fn new(data: T) -> Self { 32 | Self { data } 33 | } 34 | } 35 | 36 | impl Iterator for StorageIterator 37 | where 38 | T: Iterator, 39 | T::Item: Into 40 | { 41 | type Item = Block; 42 | 43 | fn next(&mut self) -> Option { 44 | self.data.next().map(|v| v.into()) 45 | } 46 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/transactions/utxo_set.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashMap, sync::Arc}; 2 | 3 | use crate::{Storage, Blockchain, error::BlockchainError}; 4 | 5 | 6 | pub struct UTXOSet { 7 | storage: Arc 8 | } 9 | 10 | impl UTXOSet { 11 | pub fn new(storage: Arc) -> Self { 12 | Self { 13 | storage 14 | } 15 | } 16 | 17 | pub fn reindex(&self, bc: &Blockchain) -> Result<(), BlockchainError> { 18 | self.storage.clear_utxo_set(); 19 | let map = bc.find_utxo(); 20 | for (txid, outs) in map { 21 | self.storage.write_utxo(&txid, outs)?; 22 | } 23 | Ok(()) 24 | } 25 | 26 | pub fn find_spendable_outputs(&self, from_addr: &str, amount: i32) -> (i32, HashMap>) { 27 | let mut unspent_outputs = HashMap::new(); 28 | let mut accumulated = 0; 29 | let utxo_set = self.storage.get_utxo_set(); 30 | 31 | for (txid, outs) in utxo_set.iter() { 32 | for (idx, out) in outs.iter().enumerate() { 33 | if out.is_locked(from_addr) && accumulated < amount { 34 | accumulated += out.get_value(); 35 | unspent_outputs.entry(txid.to_string()) 36 | .and_modify(|v: &mut Vec| v.push(idx)) 37 | .or_insert(vec![idx]); 38 | } 39 | } 40 | } 41 | 42 | (accumulated, unspent_outputs) 43 | } 44 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/transactions/utxo_set.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashMap, sync::Arc}; 2 | 3 | use crate::{Storage, Blockchain, error::BlockchainError}; 4 | 5 | 6 | pub struct UTXOSet { 7 | storage: Arc 8 | } 9 | 10 | impl UTXOSet { 11 | pub fn new(storage: Arc) -> Self { 12 | Self { 13 | storage 14 | } 15 | } 16 | 17 | pub fn reindex(&self, bc: &Blockchain) -> Result<(), BlockchainError> { 18 | self.storage.clear_utxo_set(); 19 | let map = bc.find_utxo(); 20 | for (txid, outs) in map { 21 | self.storage.write_utxo(&txid, outs)?; 22 | } 23 | Ok(()) 24 | } 25 | 26 | pub fn find_spendable_outputs(&self, public_key_hash: &[u8], amount: i32) -> (i32, HashMap>) { 27 | let mut unspent_outputs = HashMap::new(); 28 | let mut accumulated = 0; 29 | let utxo_set = self.storage.get_utxo_set(); 30 | 31 | for (txid, outs) in utxo_set.iter() { 32 | for (idx, out) in outs.iter().enumerate() { 33 | if out.is_locked(public_key_hash) && accumulated < amount { 34 | accumulated += out.get_value(); 35 | unspent_outputs.entry(txid.to_string()) 36 | .and_modify(|v: &mut Vec| v.push(idx)) 37 | .or_insert(vec![idx]); 38 | } 39 | } 40 | } 41 | 42 | (accumulated, unspent_outputs) 43 | } 44 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/transactions/utxo_set.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashMap, sync::Arc}; 2 | 3 | use crate::{Storage, Blockchain, error::BlockchainError}; 4 | 5 | 6 | pub struct UTXOSet { 7 | storage: Arc 8 | } 9 | 10 | impl UTXOSet { 11 | pub fn new(storage: Arc) -> Self { 12 | Self { 13 | storage 14 | } 15 | } 16 | 17 | pub fn reindex(&self, bc: &Blockchain) -> Result<(), BlockchainError> { 18 | self.storage.clear_utxo_set(); 19 | let map = bc.find_utxo(); 20 | for (txid, outs) in map { 21 | self.storage.write_utxo(&txid, outs)?; 22 | } 23 | Ok(()) 24 | } 25 | 26 | pub fn find_spendable_outputs(&self, public_key_hash: &[u8], amount: i32) -> (i32, HashMap>) { 27 | let mut unspent_outputs = HashMap::new(); 28 | let mut accumulated = 0; 29 | let utxo_set = self.storage.get_utxo_set(); 30 | 31 | for (txid, outs) in utxo_set.iter() { 32 | for (idx, out) in outs.iter().enumerate() { 33 | if out.is_locked(public_key_hash) && accumulated < amount { 34 | accumulated += out.get_value(); 35 | unspent_outputs.entry(txid.to_string()) 36 | .and_modify(|v: &mut Vec| v.push(idx)) 37 | .or_insert(vec![idx]); 38 | } 39 | } 40 | } 41 | 42 | (accumulated, unspent_outputs) 43 | } 44 | } -------------------------------------------------------------------------------- /blockchain_rust_part_2/src/blocks/block.rs: -------------------------------------------------------------------------------- 1 | use chrono::Utc; 2 | use serde::{Serialize, Deserialize}; 3 | 4 | use crate::ProofOfWork; 5 | 6 | #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] 7 | pub struct BlockHeader { 8 | timestamp: i64, 9 | prev_hash: String, 10 | bits: usize, 11 | nonce: usize, 12 | } 13 | 14 | impl BlockHeader { 15 | fn new(prev_hash: &str, bits: usize) -> Self { 16 | Self { 17 | timestamp: Utc::now().timestamp(), 18 | prev_hash: prev_hash.into(), 19 | bits, 20 | nonce: 0, 21 | } 22 | } 23 | } 24 | 25 | #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] 26 | pub struct Block { 27 | header: BlockHeader, 28 | data: String, 29 | hash: String, 30 | } 31 | 32 | impl Block { 33 | pub fn new(data: &str, prev_hash: &str, bits: usize) -> Self { 34 | let mut block = Block { 35 | header: BlockHeader::new(prev_hash, bits), 36 | data: data.into(), 37 | hash: String::new(), 38 | }; 39 | let pow = ProofOfWork::new(bits); 40 | pow.run(&mut block); 41 | 42 | block 43 | } 44 | 45 | pub fn create_genesis_block(bits: usize) -> Self { 46 | Self::new("创世区块", "", bits) 47 | } 48 | 49 | pub fn get_hash(&self) -> String { 50 | self.hash.clone() 51 | } 52 | 53 | pub fn get_header(&self) -> BlockHeader { 54 | self.header.clone() 55 | } 56 | 57 | pub fn set_nonce(&mut self, nonce: usize) { 58 | self.header.nonce = nonce; 59 | } 60 | 61 | pub fn set_hash(&mut self, hash: String) { 62 | self.hash = hash; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /blockchain_rust_part_3/src/blocks/block.rs: -------------------------------------------------------------------------------- 1 | use chrono::Utc; 2 | use serde::{Serialize, Deserialize}; 3 | 4 | use crate::ProofOfWork; 5 | 6 | #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)] 7 | pub struct BlockHeader { 8 | timestamp: i64, 9 | prev_hash: String, 10 | bits: usize, 11 | nonce: usize, 12 | } 13 | 14 | impl BlockHeader { 15 | fn new(prev_hash: &str, bits: usize) -> Self { 16 | Self { 17 | timestamp: Utc::now().timestamp(), 18 | prev_hash: prev_hash.into(), 19 | bits, 20 | nonce: 0, 21 | } 22 | } 23 | } 24 | 25 | #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)] 26 | pub struct Block { 27 | header: BlockHeader, 28 | data: String, 29 | hash: String, 30 | } 31 | 32 | impl Block { 33 | pub fn new(data: &str, prev_hash: &str, bits: usize) -> Self { 34 | let mut block = Block { 35 | header: BlockHeader::new(prev_hash, bits), 36 | data: data.into(), 37 | hash: String::new(), 38 | }; 39 | let pow = ProofOfWork::new(bits); 40 | pow.run(&mut block); 41 | 42 | block 43 | } 44 | 45 | pub fn create_genesis_block(bits: usize) -> Self { 46 | Self::new("创世区块", "", bits) 47 | } 48 | 49 | pub fn get_hash(&self) -> String { 50 | self.hash.clone() 51 | } 52 | 53 | pub fn get_header(&self) -> BlockHeader { 54 | self.header.clone() 55 | } 56 | 57 | pub fn set_nonce(&mut self, nonce: usize) { 58 | self.header.nonce = nonce; 59 | } 60 | 61 | pub fn set_hash(&mut self, hash: String) { 62 | self.hash = hash; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /blockchain_rust_part_3/src/blocks/blockchain.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{Arc, RwLock, atomic::{AtomicUsize, Ordering}}; 2 | 3 | use tracing::info; 4 | 5 | use crate::{Block, SledDb, Storage}; 6 | 7 | pub const CURR_BITS: usize = 8; 8 | 9 | pub struct Blockchain { 10 | storage: T, 11 | tip: Arc>, 12 | height: AtomicUsize, 13 | } 14 | 15 | impl Blockchain { 16 | pub fn new(storage: T) -> Self { 17 | if let Ok(Some(tip)) = storage.get_tip() { 18 | let height = storage.get_height().unwrap(); 19 | Self { 20 | storage, 21 | tip: Arc::new(RwLock::new(tip)), 22 | height: AtomicUsize::new(height.unwrap()), 23 | } 24 | }else { 25 | let genesis_block = Block::create_genesis_block(CURR_BITS); 26 | let hash = genesis_block.get_hash(); 27 | storage.update_blocks(&hash, &genesis_block, 0 as usize); 28 | 29 | Self { 30 | storage, 31 | tip: Arc::new(RwLock::new(hash)), 32 | height: AtomicUsize::new(0), 33 | } 34 | } 35 | } 36 | 37 | pub fn mine_block(&mut self, data: &str) { 38 | let block = Block::new(data, &self.tip.read().unwrap(), CURR_BITS); 39 | let hash = block.get_hash(); 40 | self.height.fetch_add(1, Ordering::Relaxed); 41 | self.storage.update_blocks(&hash, &block, self.height.load(Ordering::Relaxed)); 42 | 43 | let mut tip = self.tip.write().unwrap(); 44 | *tip = hash; 45 | } 46 | 47 | pub fn blocks_info(&self) { 48 | let blocks = self.storage.get_block_iter().unwrap(); 49 | for block in blocks { 50 | info!("{:#?}", block); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # blockchain_rust 2 | 本系列是用Rust实现简单的区块链,包括区块和区块链,工作量证明,交易和UTXO集合,持久化,钱包及用rust-libp2p实现的点对点分布式网络。 3 | 4 | 一,[用Rust实现区块链 - 1 区块和区块链](https://mp.weixin.qq.com/s?__biz=Mzg5MjA1ODYzNg==&mid=2247484460&idx=1&sn=b79b1051f40db383a2d2feb568cb3fe8&chksm=cfc2a94ff8b52059b2402785330133ce6a6734a3abcd3343c08154716acca5eb8369a4f4cd12&token=1912223334&lang=zh_CN#rd) 5 | 6 | 二,[用Rust实现区块链 - 2 工作量证明(PoW)](https://mp.weixin.qq.com/s?__biz=Mzg5MjA1ODYzNg==&mid=2247484469&idx=1&sn=c722722580f9838b9136cf3ac6611c8e&chksm=cfc2a956f8b520405e0aa11fc1484d3b676f6f9b19cb536165e7fb0602d4db03f63167dcf59b&token=1151139300&lang=zh_CN#rd) 7 | 8 | 三,[用Rust实现区块链 - 3 持久化](https://mp.weixin.qq.com/s?__biz=Mzg5MjA1ODYzNg==&mid=2247484477&idx=1&sn=cf1789dcbc1a7ca9381539e36314a2e9&chksm=cfc2a95ef8b52048027a6466c097f5954815a50e29ba0a22687fc6f218a552378e963ff6a9a2&token=1609755589&lang=zh_CN#rd) 9 | 10 | 四,[用Rust实现区块链 - 4 交易与UTXO集合](https://mp.weixin.qq.com/s?__biz=Mzg5MjA1ODYzNg==&mid=2247484487&idx=1&sn=01802f8dc60ac7dd1924888937b65d50&chksm=cfc2a924f8b520326a25718a2b97e24aac25355578ab727ae5fd6e907030ec39cc434cb90752&token=1933715555&lang=zh_CN#rd) 11 | 12 | 五,[用Rust实现区块链 - 5 钱包](https://mp.weixin.qq.com/s?__biz=Mzg5MjA1ODYzNg==&mid=2247484495&idx=1&sn=4eea98f046a92bb9e87163bab44aff68&chksm=cfc2a92cf8b5203af27a527d01f1cf699d77089a3ad2e7082fc7e707ae2885e96a611a8069f8&token=391513474&lang=zh_CN#rd) 13 | 14 | 六,[用Rust实现区块链 - 6 点对点网络(P2P)](https://mp.weixin.qq.com/s?__biz=Mzg5MjA1ODYzNg==&mid=2247484503&idx=1&sn=82427d27153bce04488b95878e7584f0&chksm=cfc2a934f8b5202274556e6ea3294b48dc8ee5075f559fce65f7ce91d9a2619e70a915252d20&token=2032429111&lang=zh_CN#rd) 15 | 16 | ### 代码详解,请关注微信公众号:coding到灯火阑珊 17 | 18 | ![Image](https://github.com/Justin02180218/distribute-election-bully/blob/master/qrcode_for_gh_8a5b7b90c100_258.jpg) 19 | -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/wallets/wallet.rs: -------------------------------------------------------------------------------- 1 | use ring::signature::{EcdsaKeyPair, ECDSA_P256_SHA256_FIXED_SIGNING, KeyPair}; 2 | use serde::{Serialize, Deserialize}; 3 | use crate::utils::{new_private_key, base58_encode, sha256_digest, ripemd160_digest}; 4 | 5 | const VERSION: u8 = 0x00; 6 | pub const ADDRESS_CHECKSUM_LEN: usize = 4; 7 | 8 | #[derive(Serialize, Deserialize, Clone)] 9 | pub struct Wallet { 10 | pkcs8: Vec, 11 | public_key: Vec, 12 | } 13 | 14 | impl Wallet { 15 | pub fn new() -> Self { 16 | let pkcs8 = new_private_key(); 17 | let key_pair = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, pkcs8.as_ref()).unwrap(); 18 | let public_key = key_pair.public_key().as_ref().to_vec(); 19 | 20 | Self { pkcs8, public_key } 21 | } 22 | 23 | pub fn get_address(&self) -> String { 24 | let pub_key_hash = hash_pub_key(self.public_key.as_slice()); 25 | let mut payload = vec![]; 26 | payload.push(VERSION); 27 | payload.extend(pub_key_hash.as_slice()); 28 | let checksum = checksum(payload.as_slice()); 29 | payload.extend(checksum.as_slice()); 30 | base58_encode(payload.as_slice()) 31 | } 32 | 33 | pub fn get_pkcs8(&self) -> &[u8] { 34 | self.pkcs8.as_slice() 35 | } 36 | 37 | pub fn get_public_key(&self) -> &[u8] { 38 | self.public_key.as_slice() 39 | } 40 | } 41 | 42 | pub fn hash_pub_key(pub_key: &[u8]) -> Vec { 43 | let pub_key_sha256 = sha256_digest(pub_key); 44 | let pub_key_ripemd160 = ripemd160_digest(&pub_key_sha256); 45 | pub_key_ripemd160 46 | } 47 | 48 | pub fn checksum(payload: &[u8]) -> Vec { 49 | let first_sha = sha256_digest(payload); 50 | let second_sha = sha256_digest(&first_sha); 51 | second_sha[0..ADDRESS_CHECKSUM_LEN].to_vec() 52 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/wallets/wallet.rs: -------------------------------------------------------------------------------- 1 | use ring::signature::{EcdsaKeyPair, ECDSA_P256_SHA256_FIXED_SIGNING, KeyPair}; 2 | use serde::{Serialize, Deserialize}; 3 | use crate::utils::{new_private_key, base58_encode, sha256_digest, ripemd160_digest}; 4 | 5 | const VERSION: u8 = 0x00; 6 | pub const ADDRESS_CHECKSUM_LEN: usize = 4; 7 | 8 | #[derive(Serialize, Deserialize, Clone)] 9 | pub struct Wallet { 10 | pkcs8: Vec, 11 | public_key: Vec, 12 | } 13 | 14 | impl Wallet { 15 | pub fn new() -> Self { 16 | let pkcs8 = new_private_key(); 17 | let key_pair = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, pkcs8.as_ref()).unwrap(); 18 | let public_key = key_pair.public_key().as_ref().to_vec(); 19 | 20 | Self { pkcs8, public_key } 21 | } 22 | 23 | pub fn get_address(&self) -> String { 24 | let pub_key_hash = hash_pub_key(self.public_key.as_slice()); 25 | let mut payload = vec![]; 26 | payload.push(VERSION); 27 | payload.extend(pub_key_hash.as_slice()); 28 | let checksum = checksum(payload.as_slice()); 29 | payload.extend(checksum.as_slice()); 30 | base58_encode(payload.as_slice()) 31 | } 32 | 33 | pub fn get_pkcs8(&self) -> &[u8] { 34 | self.pkcs8.as_slice() 35 | } 36 | 37 | pub fn get_public_key(&self) -> &[u8] { 38 | self.public_key.as_slice() 39 | } 40 | } 41 | 42 | pub fn hash_pub_key(pub_key: &[u8]) -> Vec { 43 | let pub_key_sha256 = sha256_digest(pub_key); 44 | let pub_key_ripemd160 = ripemd160_digest(&pub_key_sha256); 45 | pub_key_ripemd160 46 | } 47 | 48 | pub fn checksum(payload: &[u8]) -> Vec { 49 | let first_sha = sha256_digest(payload); 50 | let second_sha = sha256_digest(&first_sha); 51 | second_sha[0..ADDRESS_CHECKSUM_LEN].to_vec() 52 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/utils/secret.rs: -------------------------------------------------------------------------------- 1 | use std::iter::repeat; 2 | 3 | use crypto::digest::Digest; 4 | use crypto::ripemd160::Ripemd160; 5 | use ring::rand::SystemRandom; 6 | use ring::signature::{EcdsaKeyPair, ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P256_SHA256_FIXED}; 7 | use ring::digest::{Context, SHA256}; 8 | 9 | 10 | pub fn new_private_key() -> Vec { 11 | let rng = SystemRandom::new(); 12 | let pkcs8 = EcdsaKeyPair::generate_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, &rng).unwrap(); 13 | pkcs8.as_ref().to_vec() 14 | } 15 | 16 | pub fn sha256_digest(data: &[u8]) -> Vec { 17 | let mut context = Context::new(&SHA256); 18 | context.update(data); 19 | context.finish().as_ref().to_vec() 20 | } 21 | 22 | pub fn ripemd160_digest(data: &[u8]) -> Vec { 23 | let mut ripemd160 = Ripemd160::new(); 24 | ripemd160.input(data); 25 | let mut buf: Vec = repeat(0).take(ripemd160.output_bytes()).collect(); 26 | ripemd160.result(&mut buf); 27 | return buf; 28 | } 29 | 30 | pub fn base58_encode(data: &[u8]) -> String { 31 | bs58::encode(data).into_string() 32 | } 33 | 34 | pub fn base58_decode(data: &str) -> Vec { 35 | bs58::decode(data).into_vec().unwrap() 36 | } 37 | 38 | pub fn ecdsa_p256_sha256_sign_digest(pkcs8: &[u8], message: &[u8]) -> Vec { 39 | let key_pair = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, pkcs8).unwrap(); 40 | let rng = ring::rand::SystemRandom::new(); 41 | key_pair.sign(&rng, message).unwrap().as_ref().to_vec() 42 | } 43 | 44 | pub fn ecdsa_p256_sha256_sign_verify(public_key: &[u8], signature: &[u8], message: &[u8]) -> bool { 45 | let peer_public_key = 46 | ring::signature::UnparsedPublicKey::new(&ECDSA_P256_SHA256_FIXED, public_key); 47 | let result = peer_public_key.verify(message, signature.as_ref()); 48 | result.is_ok() 49 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/utils/secret.rs: -------------------------------------------------------------------------------- 1 | use std::iter::repeat; 2 | 3 | use crypto::digest::Digest; 4 | use crypto::ripemd160::Ripemd160; 5 | use ring::rand::SystemRandom; 6 | use ring::signature::{EcdsaKeyPair, ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P256_SHA256_FIXED}; 7 | use ring::digest::{Context, SHA256}; 8 | 9 | 10 | pub fn new_private_key() -> Vec { 11 | let rng = SystemRandom::new(); 12 | let pkcs8 = EcdsaKeyPair::generate_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, &rng).unwrap(); 13 | pkcs8.as_ref().to_vec() 14 | } 15 | 16 | pub fn sha256_digest(data: &[u8]) -> Vec { 17 | let mut context = Context::new(&SHA256); 18 | context.update(data); 19 | context.finish().as_ref().to_vec() 20 | } 21 | 22 | pub fn ripemd160_digest(data: &[u8]) -> Vec { 23 | let mut ripemd160 = Ripemd160::new(); 24 | ripemd160.input(data); 25 | let mut buf: Vec = repeat(0).take(ripemd160.output_bytes()).collect(); 26 | ripemd160.result(&mut buf); 27 | return buf; 28 | } 29 | 30 | pub fn base58_encode(data: &[u8]) -> String { 31 | bs58::encode(data).into_string() 32 | } 33 | 34 | pub fn base58_decode(data: &str) -> Vec { 35 | bs58::decode(data).into_vec().unwrap() 36 | } 37 | 38 | pub fn ecdsa_p256_sha256_sign_digest(pkcs8: &[u8], message: &[u8]) -> Vec { 39 | let key_pair = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_FIXED_SIGNING, pkcs8).unwrap(); 40 | let rng = ring::rand::SystemRandom::new(); 41 | key_pair.sign(&rng, message).unwrap().as_ref().to_vec() 42 | } 43 | 44 | pub fn ecdsa_p256_sha256_sign_verify(public_key: &[u8], signature: &[u8], message: &[u8]) -> bool { 45 | let peer_public_key = 46 | ring::signature::UnparsedPublicKey::new(&ECDSA_P256_SHA256_FIXED, public_key); 47 | let result = peer_public_key.verify(message, signature.as_ref()); 48 | result.is_ok() 49 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/wallets/wallets.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashMap, env::current_dir, fs}; 2 | 3 | use serde::{Serialize, Deserialize}; 4 | use tracing::info; 5 | 6 | use crate::{Wallet, utils::{serialize, deserialize}, error::BlockchainError}; 7 | 8 | 9 | pub const WALLET_FILE: &str = "wallet.dat"; 10 | 11 | #[derive(Serialize, Deserialize)] 12 | pub struct Wallets { 13 | wallets: HashMap, 14 | } 15 | 16 | impl Wallets { 17 | pub fn new() -> Result { 18 | let wallets = Self::load_wallet_from_file(); 19 | wallets 20 | } 21 | 22 | pub fn create_wallet(&mut self) -> String { 23 | let wallet = Wallet::new(); 24 | let address = wallet.get_address(); 25 | self.wallets.insert(address.clone(), wallet); 26 | self.save_wallet_to_file().unwrap(); 27 | address 28 | } 29 | 30 | pub fn get_wallet(&self, address: &str) -> Option<&Wallet> { 31 | self.wallets.get(address) 32 | } 33 | 34 | pub fn get_addresses(&self) -> Vec<&String> { 35 | self.wallets.keys().collect() 36 | } 37 | 38 | pub fn save_wallet_to_file(&self) -> Result<(), BlockchainError> { 39 | let path = current_dir().unwrap().join(WALLET_FILE); 40 | let wallets_ser = serialize(&self)?; 41 | fs::write(path, &wallets_ser).unwrap(); 42 | Ok(()) 43 | } 44 | 45 | pub fn load_wallet_from_file() -> Result { 46 | let path = current_dir().unwrap().join(WALLET_FILE); 47 | info!("Wallet path: {:?}", path); 48 | if !path.exists() { 49 | let wallets = Wallets { 50 | wallets: HashMap::new(), 51 | }; 52 | return Ok(wallets); 53 | } 54 | 55 | let wallets_ser = fs::read(&path).unwrap(); 56 | let wallets = deserialize(&wallets_ser); 57 | wallets 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/wallets/wallets.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashMap, env::current_dir, fs}; 2 | 3 | use serde::{Serialize, Deserialize}; 4 | use tracing::info; 5 | 6 | use crate::{Wallet, utils::{serialize, deserialize}, error::BlockchainError}; 7 | 8 | 9 | pub const WALLET_FILE: &str = "wallet.dat"; 10 | 11 | #[derive(Serialize, Deserialize)] 12 | pub struct Wallets { 13 | wallets: HashMap, 14 | } 15 | 16 | impl Wallets { 17 | pub fn new() -> Result { 18 | let wallets = Self::load_wallet_from_file(); 19 | wallets 20 | } 21 | 22 | pub fn create_wallet(&mut self) -> String { 23 | let wallet = Wallet::new(); 24 | let address = wallet.get_address(); 25 | self.wallets.insert(address.clone(), wallet); 26 | self.save_wallet_to_file().unwrap(); 27 | address 28 | } 29 | 30 | pub fn get_wallet(&self, address: &str) -> Option<&Wallet> { 31 | self.wallets.get(address) 32 | } 33 | 34 | pub fn get_addresses(&self) -> Vec<&String> { 35 | self.wallets.keys().collect() 36 | } 37 | 38 | pub fn save_wallet_to_file(&self) -> Result<(), BlockchainError> { 39 | let path = current_dir().unwrap().join(WALLET_FILE); 40 | let wallets_ser = serialize(&self)?; 41 | fs::write(path, &wallets_ser).unwrap(); 42 | Ok(()) 43 | } 44 | 45 | pub fn load_wallet_from_file() -> Result { 46 | let path = current_dir().unwrap().join(WALLET_FILE); 47 | info!("Wallet path: {:?}", path); 48 | if !path.exists() { 49 | let wallets = Wallets { 50 | wallets: HashMap::new(), 51 | }; 52 | return Ok(wallets); 53 | } 54 | 55 | let wallets_ser = fs::read(&path).unwrap(); 56 | let wallets = deserialize(&wallets_ser); 57 | wallets 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/transactions/transaction.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | 3 | use crate::{Txinput, Txoutput, utils::{serialize, hash_to_str}, UTXOSet, Storage}; 4 | 5 | const SUBSIDY: i32= 10; 6 | 7 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 8 | pub struct Transaction { 9 | id: String, 10 | vin: Vec, 11 | vout: Vec, 12 | } 13 | 14 | impl Transaction { 15 | pub fn new_coinbase(to: &str) -> Self { 16 | let txin = Txinput::default(); 17 | let txout = Txoutput::new(SUBSIDY, to); 18 | 19 | let mut tx = Transaction { 20 | id: String::new(), 21 | vin: vec![txin], 22 | vout: vec![txout], 23 | }; 24 | tx.set_hash(); 25 | 26 | tx 27 | } 28 | 29 | pub fn new_utxo(from: &str, to: &str, amount: i32, utxo_set: &UTXOSet) -> Self { 30 | let (accumulated, valid_outputs) = utxo_set.find_spendable_outputs(from, amount); 31 | if accumulated < amount { 32 | panic!("Error not enough funds"); 33 | } 34 | 35 | let mut inputs = vec![]; 36 | for (txid, outputs) in valid_outputs { 37 | for idx in outputs { 38 | let input = Txinput::new(txid.clone(), idx.clone(), from); 39 | inputs.push(input); 40 | } 41 | } 42 | 43 | let mut outputs = vec![Txoutput::new(amount, &to)]; 44 | if accumulated > amount { 45 | outputs.push(Txoutput::new(accumulated - amount, &from)); 46 | } 47 | 48 | let mut tx = Transaction { 49 | id: String::new(), 50 | vin: inputs, 51 | vout: outputs, 52 | }; 53 | tx.set_hash(); 54 | 55 | tx 56 | } 57 | 58 | fn set_hash(&mut self) { 59 | if let Ok(tx_ser) = serialize(self) { 60 | self.id = hash_to_str(&tx_ser) 61 | } 62 | } 63 | 64 | pub fn get_id(&self) -> String { 65 | self.id.clone() 66 | } 67 | 68 | pub fn get_vout(&self) -> &[Txoutput] { 69 | self.vout.as_slice() 70 | } 71 | 72 | pub fn get_vin(&self) -> &[Txinput] { 73 | self.vin.as_slice() 74 | } 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/blocks/block.rs: -------------------------------------------------------------------------------- 1 | use chrono::Utc; 2 | use serde::{Serialize, Deserialize}; 3 | 4 | use crate::{ProofOfWork, Transaction, utils::{serialize, hash_to_str}}; 5 | 6 | #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)] 7 | pub struct BlockHeader { 8 | timestamp: i64, 9 | prev_hash: String, 10 | txs_hash: String, 11 | bits: usize, 12 | nonce: usize, 13 | } 14 | 15 | impl BlockHeader { 16 | fn new(prev_hash: &str, bits: usize) -> Self { 17 | Self { 18 | timestamp: Utc::now().timestamp(), 19 | prev_hash: prev_hash.into(), 20 | txs_hash: String::new(), 21 | bits, 22 | nonce: 0, 23 | } 24 | } 25 | } 26 | 27 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 28 | pub struct Block { 29 | header: BlockHeader, 30 | tranxs: Vec, 31 | hash: String, 32 | } 33 | 34 | impl Block { 35 | pub fn new(txs: &[Transaction], prev_hash: &str, bits: usize) -> Self { 36 | let mut block = Block { 37 | header: BlockHeader::new(prev_hash, bits), 38 | tranxs: txs.to_vec(), 39 | hash: String::new(), 40 | }; 41 | block.set_txs_hash(txs); 42 | 43 | let pow = ProofOfWork::new(bits); 44 | pow.run(&mut block); 45 | 46 | block 47 | } 48 | 49 | pub fn create_genesis_block(bits: usize, genesis_addr: &str) -> Self { 50 | let coinbase = Transaction::new_coinbase(genesis_addr); 51 | Self::new(&vec![coinbase], "", bits) 52 | } 53 | 54 | pub fn get_hash(&self) -> String { 55 | self.hash.clone() 56 | } 57 | 58 | pub fn get_header(&self) -> BlockHeader { 59 | self.header.clone() 60 | } 61 | 62 | pub fn set_nonce(&mut self, nonce: usize) { 63 | self.header.nonce = nonce; 64 | } 65 | 66 | pub fn set_hash(&mut self, hash: String) { 67 | self.hash = hash; 68 | } 69 | 70 | fn set_txs_hash(&mut self, txs: &[Transaction]) { 71 | if let Ok(txs_ser) = serialize(txs) { 72 | self.header.txs_hash = hash_to_str(&txs_ser); 73 | } 74 | } 75 | 76 | pub fn get_tranxs(&self) -> &[Transaction] { 77 | &self.tranxs 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/blocks/block.rs: -------------------------------------------------------------------------------- 1 | use chrono::Utc; 2 | use serde::{Serialize, Deserialize}; 3 | 4 | use crate::{ProofOfWork, Transaction, utils::{serialize, hash_to_str}}; 5 | 6 | #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)] 7 | pub struct BlockHeader { 8 | timestamp: i64, 9 | prev_hash: String, 10 | txs_hash: String, 11 | bits: usize, 12 | nonce: usize, 13 | } 14 | 15 | impl BlockHeader { 16 | fn new(prev_hash: &str, bits: usize) -> Self { 17 | Self { 18 | timestamp: Utc::now().timestamp(), 19 | prev_hash: prev_hash.into(), 20 | txs_hash: String::new(), 21 | bits, 22 | nonce: 0, 23 | } 24 | } 25 | } 26 | 27 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 28 | pub struct Block { 29 | header: BlockHeader, 30 | tranxs: Vec, 31 | hash: String, 32 | } 33 | 34 | impl Block { 35 | pub fn new(txs: &[Transaction], prev_hash: &str, bits: usize) -> Self { 36 | let mut block = Block { 37 | header: BlockHeader::new(prev_hash, bits), 38 | tranxs: txs.to_vec(), 39 | hash: String::new(), 40 | }; 41 | block.set_txs_hash(txs); 42 | 43 | let pow = ProofOfWork::new(bits); 44 | pow.run(&mut block); 45 | 46 | block 47 | } 48 | 49 | pub fn create_genesis_block(bits: usize, genesis_addr: &str) -> Self { 50 | let coinbase = Transaction::new_coinbase(genesis_addr); 51 | Self::new(&vec![coinbase], "", bits) 52 | } 53 | 54 | pub fn get_hash(&self) -> String { 55 | self.hash.clone() 56 | } 57 | 58 | pub fn get_header(&self) -> BlockHeader { 59 | self.header.clone() 60 | } 61 | 62 | pub fn set_nonce(&mut self, nonce: usize) { 63 | self.header.nonce = nonce; 64 | } 65 | 66 | pub fn set_hash(&mut self, hash: String) { 67 | self.hash = hash; 68 | } 69 | 70 | fn set_txs_hash(&mut self, txs: &[Transaction]) { 71 | if let Ok(txs_ser) = serialize(txs) { 72 | self.header.txs_hash = hash_to_str(&txs_ser); 73 | } 74 | } 75 | 76 | pub fn get_tranxs(&self) -> Vec { 77 | self.tranxs.clone() 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/blocks/block.rs: -------------------------------------------------------------------------------- 1 | use chrono::Utc; 2 | use serde::{Serialize, Deserialize}; 3 | 4 | use crate::{ProofOfWork, Transaction, utils::{serialize, hash_to_str}}; 5 | 6 | #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)] 7 | pub struct BlockHeader { 8 | timestamp: i64, 9 | prev_hash: String, 10 | txs_hash: String, 11 | bits: usize, 12 | nonce: usize, 13 | } 14 | 15 | impl BlockHeader { 16 | fn new(prev_hash: &str, bits: usize) -> Self { 17 | Self { 18 | timestamp: Utc::now().timestamp(), 19 | prev_hash: prev_hash.into(), 20 | txs_hash: String::new(), 21 | bits, 22 | nonce: 0, 23 | } 24 | } 25 | } 26 | 27 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 28 | pub struct Block { 29 | header: BlockHeader, 30 | tranxs: Vec, 31 | hash: String, 32 | } 33 | 34 | impl Block { 35 | pub fn new(txs: &[Transaction], prev_hash: &str, bits: usize) -> Self { 36 | let mut block = Block { 37 | header: BlockHeader::new(prev_hash, bits), 38 | tranxs: txs.to_vec(), 39 | hash: String::new(), 40 | }; 41 | block.set_txs_hash(txs); 42 | 43 | let pow = ProofOfWork::new(bits); 44 | pow.run(&mut block); 45 | 46 | block 47 | } 48 | 49 | pub fn create_genesis_block(bits: usize, genesis_addr: &str) -> Self { 50 | let coinbase = Transaction::new_coinbase(genesis_addr); 51 | Self::new(&vec![coinbase], "", bits) 52 | } 53 | 54 | pub fn get_hash(&self) -> String { 55 | self.hash.clone() 56 | } 57 | 58 | pub fn get_header(&self) -> BlockHeader { 59 | self.header.clone() 60 | } 61 | 62 | pub fn set_nonce(&mut self, nonce: usize) { 63 | self.header.nonce = nonce; 64 | } 65 | 66 | pub fn set_hash(&mut self, hash: String) { 67 | self.hash = hash; 68 | } 69 | 70 | fn set_txs_hash(&mut self, txs: &[Transaction]) { 71 | if let Ok(txs_ser) = serialize(txs) { 72 | self.header.txs_hash = hash_to_str(&txs_ser); 73 | } 74 | } 75 | 76 | pub fn get_tranxs(&self) -> Vec { 77 | self.tranxs.clone() 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/networks/mod.rs: -------------------------------------------------------------------------------- 1 | mod behaviour; 2 | mod node; 3 | mod command; 4 | 5 | pub use behaviour::*; 6 | pub use node::*; 7 | pub use command::*; 8 | 9 | use once_cell::sync::Lazy; 10 | use tokio::sync::{mpsc, Mutex}; 11 | use std::{ 12 | time::Duration, 13 | collections::{hash_map::DefaultHasher, HashMap}, 14 | hash::{Hasher, Hash}, sync::Arc, 15 | }; 16 | use anyhow::Result; 17 | use libp2p::{ 18 | gossipsub::{IdentTopic as Topic, GossipsubConfigBuilder, ValidationMode, MessageId, GossipsubMessage}, 19 | swarm::SwarmBuilder, 20 | identity::Keypair, 21 | tcp::TokioTcpConfig, 22 | core::upgrade, 23 | Swarm, PeerId, noise, yamux, Transport, 24 | }; 25 | 26 | static ID_KEYS: Lazy = Lazy::new(Keypair::generate_ed25519); 27 | static PEER_ID: Lazy = Lazy::new(|| PeerId::from(ID_KEYS.public())); 28 | static BLOCK_TOPIC: Lazy = Lazy::new(|| Topic::new("blocks")); 29 | static TRANX_TOPIC: Lazy = Lazy::new(|| Topic::new("tranxs")); 30 | 31 | static WALLET_MAP: Lazy>>> = Lazy::new(|| Arc::new(Mutex::new(HashMap::new()))); 32 | 33 | async fn create_swarm(topics: Vec, msg_sender: mpsc::UnboundedSender) -> Result> { 34 | println!("Local peer id: {:?}", *PEER_ID); 35 | 36 | let noise_keys = noise::Keypair::::new().into_authentic(&ID_KEYS)?; 37 | 38 | let transport = TokioTcpConfig::new() 39 | .nodelay(true) 40 | .upgrade(upgrade::Version::V1) 41 | .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) 42 | .multiplex(yamux::YamuxConfig::default()) 43 | .boxed(); 44 | 45 | let message_id_fn = |message: &GossipsubMessage| { 46 | let mut s = DefaultHasher::new(); 47 | message.data.hash(&mut s); 48 | MessageId::from(s.finish().to_string()) 49 | }; 50 | 51 | let gossipsub_config = GossipsubConfigBuilder::default() 52 | .heartbeat_interval(Duration::from_secs(10)) 53 | .validation_mode(ValidationMode::Strict) 54 | .message_id_fn(message_id_fn) 55 | .build() 56 | .expect("Valid config"); 57 | 58 | let mut behaviour = BlockchainBehaviour::new(ID_KEYS.clone(), gossipsub_config, msg_sender).await?; 59 | for topic in topics.iter() { 60 | behaviour.gossipsub.subscribe(topic).unwrap(); 61 | } 62 | 63 | let swarm = SwarmBuilder::new(transport, behaviour, PEER_ID.clone()) 64 | .executor(Box::new(|fut| { 65 | tokio::spawn(fut); 66 | })).build(); 67 | 68 | Ok(swarm) 69 | } -------------------------------------------------------------------------------- /blockchain_rust_part_3/src/storage/sleddb.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use sled::{Db, IVec, transaction::TransactionResult}; 3 | 4 | use crate::{Storage, error::BlockchainError, Block, utils::{deserialize, serialize}, TIP_KEY, TABLE_OF_BLOCK, HEIGHT, StorageIterator}; 5 | 6 | pub struct SledDb { 7 | db: Db 8 | } 9 | 10 | impl SledDb { 11 | pub fn new(path: impl AsRef) -> Self { 12 | Self { 13 | db: sled::open(path).unwrap() 14 | } 15 | } 16 | 17 | fn get_full_key(table: &str, key: &str) -> String { 18 | format!("{}:{}", table, key) 19 | } 20 | } 21 | 22 | impl Storage for SledDb { 23 | fn get_tip(&self) -> Result, BlockchainError> { 24 | let result = self.db.get(TIP_KEY)?.map(|v| deserialize::(&v.to_vec())); 25 | result.map_or(Ok(None), |v| v.map(Some)) 26 | } 27 | 28 | fn get_block(&self, key: &str) -> Result, BlockchainError> { 29 | let name = Self::get_full_key(TABLE_OF_BLOCK, key); 30 | let result = self.db.get(name)?.map(|v| v.into()); 31 | Ok(result) 32 | } 33 | 34 | fn get_height(&self) -> Result, BlockchainError> { 35 | let result = self.db.get(HEIGHT)?.map(|v| deserialize::(&v.to_vec())); 36 | result.map_or(Ok(None), |v| v.map(Some)) 37 | } 38 | 39 | fn update_blocks(&self, key: &str, block: &Block, height: usize) { 40 | let _: TransactionResult<(), ()> = self.db.transaction(|db| { 41 | let name = Self::get_full_key(TABLE_OF_BLOCK, key); 42 | db.insert(name.as_str(), serialize(block).unwrap())?; 43 | db.insert(TIP_KEY, serialize(key).unwrap())?; 44 | db.insert(HEIGHT, serialize(&height).unwrap())?; 45 | db.flush(); 46 | Ok(()) 47 | }); 48 | } 49 | 50 | fn get_block_iter(&self) -> Result>, BlockchainError> { 51 | let prefix = format!("{}:", TABLE_OF_BLOCK); 52 | let iter = StorageIterator::new(self.db.scan_prefix(prefix)); 53 | Ok(Box::new(iter)) 54 | } 55 | } 56 | 57 | impl From for Block { 58 | fn from(v: IVec) -> Self { 59 | let result = deserialize::(&v.to_vec()); 60 | match result { 61 | Ok(block) => block, 62 | Err(_) => Block::default(), 63 | } 64 | } 65 | } 66 | 67 | impl From> for Block { 68 | fn from(result: Result<(IVec, IVec), sled::Error>) -> Self { 69 | match result { 70 | Ok((_, v)) => match deserialize::(&v.to_vec()) { 71 | Ok(block) => block, 72 | Err(_) => Block::default(), 73 | }, 74 | Err(_) => Block::default(), 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/networks/behaviour.rs: -------------------------------------------------------------------------------- 1 | use libp2p::{ 2 | NetworkBehaviour, 3 | gossipsub::{Gossipsub, GossipsubConfig, MessageAuthenticity, GossipsubEvent}, 4 | mdns::{Mdns, MdnsEvent}, 5 | identity::Keypair, 6 | swarm::NetworkBehaviourEventProcess 7 | }; 8 | use anyhow::Result; 9 | use tokio::sync::mpsc; 10 | use tracing::{info, error}; 11 | 12 | use crate::Messages; 13 | 14 | #[derive(NetworkBehaviour)] 15 | #[behaviour(event_process = true)] 16 | pub struct BlockchainBehaviour { 17 | pub gossipsub: Gossipsub, 18 | pub mdns: Mdns, 19 | #[behaviour(ignore)] 20 | pub msg_sender: mpsc::UnboundedSender, 21 | } 22 | 23 | impl BlockchainBehaviour { 24 | pub async fn new(key_pair: Keypair, config: GossipsubConfig, msg_sender: mpsc::UnboundedSender) -> Result { 25 | Ok(Self { 26 | gossipsub: Gossipsub::new(MessageAuthenticity::Signed(key_pair), config).unwrap(), 27 | mdns: Mdns::new(Default::default()).await?, 28 | msg_sender, 29 | }) 30 | } 31 | } 32 | 33 | impl NetworkBehaviourEventProcess for BlockchainBehaviour { 34 | fn inject_event(&mut self, event: GossipsubEvent) { 35 | match event { 36 | GossipsubEvent::Message { 37 | propagation_source: peer_id, 38 | message_id: id, 39 | message, 40 | } => { 41 | info!("Got message with id: {} from peer: {:?}", id, peer_id); 42 | let msg: Messages = serde_json::from_slice(&message.data).unwrap(); 43 | if let Err(e) = self.msg_sender.send(msg) { 44 | error!("error sending messages via channel, {}", e); 45 | } 46 | }, 47 | GossipsubEvent::Subscribed { peer_id, topic} => { 48 | info!("Subscribe topic: {} with id: {}", topic, peer_id); 49 | }, 50 | GossipsubEvent::Unsubscribed { peer_id, topic} => { 51 | info!("Unsubscribe topic: {} with id: {}", topic, peer_id); 52 | }, 53 | } 54 | } 55 | } 56 | 57 | impl NetworkBehaviourEventProcess for BlockchainBehaviour { 58 | fn inject_event(&mut self, event: MdnsEvent) { 59 | match event { 60 | MdnsEvent::Discovered(list) => { 61 | for (id, addr) in list { 62 | println!("Got peer: {} with addr {}", &id, &addr); 63 | self.gossipsub.add_explicit_peer(&id); 64 | } 65 | }, 66 | MdnsEvent::Expired(list) => { 67 | for (id, addr) in list { 68 | println!("Removed peer: {} with addr {}", &id, &addr); 69 | self.gossipsub.remove_explicit_peer(&id); 70 | } 71 | } 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/blocks/blockchain.rs: -------------------------------------------------------------------------------- 1 | use std::{sync::{Arc, RwLock, atomic::{AtomicUsize, Ordering}}, collections::HashMap}; 2 | 3 | use tracing::info; 4 | 5 | use crate::{Block, SledDb, Storage, Transaction, Txoutput}; 6 | 7 | pub const CURR_BITS: usize = 8; 8 | 9 | pub struct Blockchain { 10 | storage: Arc, 11 | tip: Arc>, 12 | height: AtomicUsize, 13 | } 14 | 15 | impl Blockchain { 16 | pub fn new(storage: Arc, genesis_addr: &str) -> Self { 17 | if let Ok(Some(tip)) = storage.get_tip() { 18 | let height = storage.get_height().unwrap(); 19 | Self { 20 | storage, 21 | tip: Arc::new(RwLock::new(tip)), 22 | height: AtomicUsize::new(height.unwrap()), 23 | } 24 | }else { 25 | let genesis_block = Block::create_genesis_block(CURR_BITS, genesis_addr); 26 | let hash = genesis_block.get_hash(); 27 | storage.update_blocks(&hash, &genesis_block, 0 as usize); 28 | 29 | Self { 30 | storage, 31 | tip: Arc::new(RwLock::new(hash)), 32 | height: AtomicUsize::new(0), 33 | } 34 | } 35 | } 36 | 37 | pub fn mine_block(&mut self, txs: &[Transaction]) { 38 | let block = Block::new(txs, &self.tip.read().unwrap(), CURR_BITS); 39 | let hash = block.get_hash(); 40 | self.height.fetch_add(1, Ordering::Relaxed); 41 | self.storage.update_blocks(&hash, &block, self.height.load(Ordering::Relaxed)); 42 | 43 | let mut tip = self.tip.write().unwrap(); 44 | *tip = hash; 45 | } 46 | 47 | pub fn find_utxo(&self) -> HashMap> { 48 | let mut utxo = HashMap::new(); 49 | let mut spent_txos = HashMap::new(); 50 | 51 | let blocks = self.storage.get_block_iter().unwrap(); 52 | for block in blocks { 53 | for tx in block.get_tranxs() { 54 | for (idx, txout) in tx.get_vout().iter().enumerate() { 55 | if let Some(outs) = spent_txos.get(&tx.get_id()) { 56 | for out in outs { 57 | if idx.eq(out) { 58 | break; 59 | } 60 | 61 | utxo.entry(tx.get_id()) 62 | .and_modify(|v: &mut Vec| v.push(txout.clone())) 63 | .or_insert(vec![txout.clone()]); 64 | } 65 | }else { 66 | utxo.entry(tx.get_id()) 67 | .and_modify(|v: &mut Vec| v.push(txout.clone())) 68 | .or_insert(vec![txout.clone()]); 69 | } 70 | } 71 | 72 | for txin in tx.get_vin() { 73 | spent_txos.entry(txin.get_txid()) 74 | .and_modify(|v: &mut Vec| v.push(txin.get_vout())) 75 | .or_insert(vec![txin.get_vout()]); 76 | } 77 | } 78 | } 79 | 80 | utxo 81 | } 82 | 83 | pub fn blocks_info(&self) { 84 | let blocks = self.storage.get_block_iter().unwrap(); 85 | for block in blocks { 86 | info!("{:#?}", block); 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /blockchain_rust_part_4/src/storage/sleddb.rs: -------------------------------------------------------------------------------- 1 | use std::{path::Path, collections::HashMap}; 2 | use sled::{Db, IVec, transaction::TransactionResult}; 3 | 4 | use crate::{Storage, error::BlockchainError, Block, utils::{deserialize, serialize}, TIP_KEY, TABLE_OF_BLOCK, HEIGHT, StorageIterator, UTXO_SET, Txoutput}; 5 | 6 | pub struct SledDb { 7 | db: Db 8 | } 9 | 10 | impl SledDb { 11 | pub fn new(path: impl AsRef) -> Self { 12 | Self { 13 | db: sled::open(path).unwrap() 14 | } 15 | } 16 | 17 | fn get_full_key(table: &str, key: &str) -> String { 18 | format!("{}:{}", table, key) 19 | } 20 | } 21 | 22 | impl Storage for SledDb { 23 | fn get_tip(&self) -> Result, BlockchainError> { 24 | let result = self.db.get(TIP_KEY)?.map(|v| deserialize::(&v.to_vec())); 25 | result.map_or(Ok(None), |v| v.map(Some)) 26 | } 27 | 28 | fn get_block(&self, key: &str) -> Result, BlockchainError> { 29 | let name = Self::get_full_key(TABLE_OF_BLOCK, key); 30 | let result = self.db.get(name)?.map(|v| v.into()); 31 | Ok(result) 32 | } 33 | 34 | fn get_height(&self) -> Result, BlockchainError> { 35 | let result = self.db.get(HEIGHT)?.map(|v| deserialize::(&v.to_vec())); 36 | result.map_or(Ok(None), |v| v.map(Some)) 37 | } 38 | 39 | fn update_blocks(&self, key: &str, block: &Block, height: usize) { 40 | let _: TransactionResult<(), ()> = self.db.transaction(|db| { 41 | let name = Self::get_full_key(TABLE_OF_BLOCK, key); 42 | db.insert(name.as_str(), serialize(block).unwrap())?; 43 | db.insert(TIP_KEY, serialize(key).unwrap())?; 44 | db.insert(HEIGHT, serialize(&height).unwrap())?; 45 | db.flush(); 46 | Ok(()) 47 | }); 48 | } 49 | 50 | fn get_block_iter(&self) -> Result>, BlockchainError> { 51 | let prefix = format!("{}:", TABLE_OF_BLOCK); 52 | let iter = StorageIterator::new(self.db.scan_prefix(prefix)); 53 | Ok(Box::new(iter)) 54 | } 55 | 56 | fn get_utxo_set(&self) -> HashMap> { 57 | let mut map = HashMap::new(); 58 | 59 | let prefix = format!("{}:", UTXO_SET); 60 | 61 | for item in self.db.scan_prefix(prefix) { 62 | let (k, v) = item.unwrap(); 63 | let txid = String::from_utf8(k.to_vec()).unwrap(); 64 | let txid = txid.split(":").collect::>()[1].into(); 65 | let outputs = deserialize::>(&v.to_vec()).unwrap(); 66 | 67 | map.insert(txid, outputs); 68 | } 69 | 70 | map 71 | } 72 | 73 | fn write_utxo(&self, txid: &str, outs: Vec) -> Result<(), BlockchainError> { 74 | let name = format!("{}:{}", UTXO_SET, txid); 75 | self.db.insert(name, serialize(&outs)?)?; 76 | Ok(()) 77 | } 78 | 79 | fn clear_utxo_set(&self) { 80 | let prefix = format!("{}:", UTXO_SET); 81 | self.db.remove(prefix).unwrap(); 82 | } 83 | } 84 | 85 | impl From for Block { 86 | fn from(v: IVec) -> Self { 87 | let result = deserialize::(&v.to_vec()); 88 | match result { 89 | Ok(block) => block, 90 | Err(_) => Block::default(), 91 | } 92 | } 93 | } 94 | 95 | impl From> for Block { 96 | fn from(result: Result<(IVec, IVec), sled::Error>) -> Self { 97 | match result { 98 | Ok((_, v)) => match deserialize::(&v.to_vec()) { 99 | Ok(block) => block, 100 | Err(_) => Block::default(), 101 | }, 102 | Err(_) => Block::default(), 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/storage/sleddb.rs: -------------------------------------------------------------------------------- 1 | use std::{path::Path, collections::HashMap}; 2 | use sled::{Db, IVec, transaction::TransactionResult}; 3 | 4 | use crate::{Storage, error::BlockchainError, Block, utils::{deserialize, serialize}, TIP_KEY, TABLE_OF_BLOCK, HEIGHT, StorageIterator, UTXO_SET, Txoutput}; 5 | 6 | pub struct SledDb { 7 | db: Db 8 | } 9 | 10 | impl SledDb { 11 | pub fn new(path: impl AsRef) -> Self { 12 | Self { 13 | db: sled::open(path).unwrap() 14 | } 15 | } 16 | 17 | fn get_full_key(table: &str, key: &str) -> String { 18 | format!("{}:{}", table, key) 19 | } 20 | } 21 | 22 | impl Storage for SledDb { 23 | fn get_tip(&self) -> Result, BlockchainError> { 24 | let result = self.db.get(TIP_KEY)?.map(|v| deserialize::(&v.to_vec())); 25 | result.map_or(Ok(None), |v| v.map(Some)) 26 | } 27 | 28 | fn get_block(&self, key: &str) -> Result, BlockchainError> { 29 | let name = Self::get_full_key(TABLE_OF_BLOCK, key); 30 | let result = self.db.get(name)?.map(|v| v.into()); 31 | Ok(result) 32 | } 33 | 34 | fn get_height(&self) -> Result, BlockchainError> { 35 | let result = self.db.get(HEIGHT)?.map(|v| deserialize::(&v.to_vec())); 36 | result.map_or(Ok(None), |v| v.map(Some)) 37 | } 38 | 39 | fn update_blocks(&self, key: &str, block: &Block, height: usize) { 40 | let _: TransactionResult<(), ()> = self.db.transaction(|db| { 41 | let name = Self::get_full_key(TABLE_OF_BLOCK, key); 42 | db.insert(name.as_str(), serialize(block).unwrap())?; 43 | db.insert(TIP_KEY, serialize(key).unwrap())?; 44 | db.insert(HEIGHT, serialize(&height).unwrap())?; 45 | db.flush(); 46 | Ok(()) 47 | }); 48 | } 49 | 50 | fn get_block_iter(&self) -> Result>, BlockchainError> { 51 | let prefix = format!("{}:", TABLE_OF_BLOCK); 52 | let iter = StorageIterator::new(self.db.scan_prefix(prefix)); 53 | Ok(Box::new(iter)) 54 | } 55 | 56 | fn get_utxo_set(&self) -> HashMap> { 57 | let mut map = HashMap::new(); 58 | 59 | let prefix = format!("{}:", UTXO_SET); 60 | 61 | for item in self.db.scan_prefix(prefix) { 62 | let (k, v) = item.unwrap(); 63 | let txid = String::from_utf8(k.to_vec()).unwrap(); 64 | let txid = txid.split(":").collect::>()[1].into(); 65 | let outputs = deserialize::>(&v.to_vec()).unwrap(); 66 | 67 | map.insert(txid, outputs); 68 | } 69 | 70 | map 71 | } 72 | 73 | fn write_utxo(&self, txid: &str, outs: Vec) -> Result<(), BlockchainError> { 74 | let name = format!("{}:{}", UTXO_SET, txid); 75 | self.db.insert(name, serialize(&outs)?)?; 76 | Ok(()) 77 | } 78 | 79 | fn clear_utxo_set(&self) { 80 | let prefix = format!("{}:", UTXO_SET); 81 | self.db.remove(prefix).unwrap(); 82 | } 83 | } 84 | 85 | impl From for Block { 86 | fn from(v: IVec) -> Self { 87 | let result = deserialize::(&v.to_vec()); 88 | match result { 89 | Ok(block) => block, 90 | Err(_) => Block::default(), 91 | } 92 | } 93 | } 94 | 95 | impl From> for Block { 96 | fn from(result: Result<(IVec, IVec), sled::Error>) -> Self { 97 | match result { 98 | Ok((_, v)) => match deserialize::(&v.to_vec()) { 99 | Ok(block) => block, 100 | Err(_) => Block::default(), 101 | }, 102 | Err(_) => Block::default(), 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/storage/sleddb.rs: -------------------------------------------------------------------------------- 1 | use std::{path::Path, collections::HashMap}; 2 | use sled::{Db, IVec, transaction::TransactionResult}; 3 | 4 | use crate::{Storage, error::BlockchainError, Block, utils::{deserialize, serialize}, TIP_KEY, TABLE_OF_BLOCK, HEIGHT, StorageIterator, UTXO_SET, Txoutput}; 5 | 6 | pub struct SledDb { 7 | db: Db 8 | } 9 | 10 | impl SledDb { 11 | pub fn new(path: impl AsRef) -> Self { 12 | Self { 13 | db: sled::open(path).unwrap() 14 | } 15 | } 16 | 17 | fn get_full_key(table: &str, key: &str) -> String { 18 | format!("{}:{}", table, key) 19 | } 20 | } 21 | 22 | impl Storage for SledDb { 23 | fn get_tip(&self) -> Result, BlockchainError> { 24 | let result = self.db.get(TIP_KEY)?.map(|v| deserialize::(&v.to_vec())); 25 | result.map_or(Ok(None), |v| v.map(Some)) 26 | } 27 | 28 | fn get_block(&self, key: &str) -> Result, BlockchainError> { 29 | let name = Self::get_full_key(TABLE_OF_BLOCK, key); 30 | let result = self.db.get(name)?.map(|v| v.into()); 31 | Ok(result) 32 | } 33 | 34 | fn get_height(&self) -> Result, BlockchainError> { 35 | let result = self.db.get(HEIGHT)?.map(|v| deserialize::(&v.to_vec())); 36 | result.map_or(Ok(None), |v| v.map(Some)) 37 | } 38 | 39 | fn update_blocks(&self, key: &str, block: &Block, height: usize) { 40 | let _: TransactionResult<(), ()> = self.db.transaction(|db| { 41 | let name = Self::get_full_key(TABLE_OF_BLOCK, key); 42 | db.insert(name.as_str(), serialize(block).unwrap())?; 43 | db.insert(TIP_KEY, serialize(key).unwrap())?; 44 | db.insert(HEIGHT, serialize(&height).unwrap())?; 45 | db.flush(); 46 | Ok(()) 47 | }); 48 | } 49 | 50 | fn get_block_iter(&self) -> Result>, BlockchainError> { 51 | let prefix = format!("{}:", TABLE_OF_BLOCK); 52 | let iter = StorageIterator::new(self.db.scan_prefix(prefix)); 53 | Ok(Box::new(iter)) 54 | } 55 | 56 | fn get_utxo_set(&self) -> HashMap> { 57 | let mut map = HashMap::new(); 58 | 59 | let prefix = format!("{}:", UTXO_SET); 60 | 61 | for item in self.db.scan_prefix(prefix) { 62 | let (k, v) = item.unwrap(); 63 | let txid = String::from_utf8(k.to_vec()).unwrap(); 64 | let txid = txid.split(":").collect::>()[1].into(); 65 | let outputs = deserialize::>(&v.to_vec()).unwrap(); 66 | 67 | map.insert(txid, outputs); 68 | } 69 | 70 | map 71 | } 72 | 73 | fn write_utxo(&self, txid: &str, outs: Vec) -> Result<(), BlockchainError> { 74 | let name = format!("{}:{}", UTXO_SET, txid); 75 | self.db.insert(name, serialize(&outs)?)?; 76 | Ok(()) 77 | } 78 | 79 | fn clear_utxo_set(&self) { 80 | let prefix = format!("{}:", UTXO_SET); 81 | self.db.remove(prefix).unwrap(); 82 | } 83 | } 84 | 85 | impl From for Block { 86 | fn from(v: IVec) -> Self { 87 | let result = deserialize::(&v.to_vec()); 88 | match result { 89 | Ok(block) => block, 90 | Err(_) => Block::default(), 91 | } 92 | } 93 | } 94 | 95 | impl From> for Block { 96 | fn from(result: Result<(IVec, IVec), sled::Error>) -> Self { 97 | match result { 98 | Ok((_, v)) => match deserialize::(&v.to_vec()) { 99 | Ok(block) => block, 100 | Err(_) => Block::default(), 101 | }, 102 | Err(_) => Block::default(), 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/blocks/blockchain.rs: -------------------------------------------------------------------------------- 1 | use std::{sync::{Arc, RwLock, atomic::{AtomicUsize, Ordering}}, collections::HashMap}; 2 | 3 | use tracing::info; 4 | 5 | use crate::{Block, SledDb, Storage, Transaction, Txoutput}; 6 | 7 | pub const CURR_BITS: usize = 8; 8 | 9 | pub struct Blockchain { 10 | storage: Arc, 11 | tip: Arc>, 12 | height: AtomicUsize, 13 | } 14 | 15 | impl Blockchain { 16 | pub fn new(storage: Arc, genesis_addr: &str) -> Self { 17 | if let Ok(Some(tip)) = storage.get_tip() { 18 | let height = storage.get_height().unwrap(); 19 | Self { 20 | storage, 21 | tip: Arc::new(RwLock::new(tip)), 22 | height: AtomicUsize::new(height.unwrap()), 23 | } 24 | }else { 25 | let genesis_block = Block::create_genesis_block(CURR_BITS, genesis_addr); 26 | let hash = genesis_block.get_hash(); 27 | storage.update_blocks(&hash, &genesis_block, 0 as usize); 28 | 29 | Self { 30 | storage, 31 | tip: Arc::new(RwLock::new(hash)), 32 | height: AtomicUsize::new(0), 33 | } 34 | } 35 | } 36 | 37 | pub fn mine_block(&mut self, txs: &[Transaction]) { 38 | for tx in txs { 39 | if tx.verify(self) == false { 40 | panic!("ERROR: Invalid transaction") 41 | } 42 | } 43 | 44 | let block = Block::new(txs, &self.tip.read().unwrap(), CURR_BITS); 45 | let hash = block.get_hash(); 46 | self.height.fetch_add(1, Ordering::Relaxed); 47 | self.storage.update_blocks(&hash, &block, self.height.load(Ordering::Relaxed)); 48 | 49 | let mut tip = self.tip.write().unwrap(); 50 | *tip = hash; 51 | } 52 | 53 | pub fn find_utxo(&self) -> HashMap> { 54 | let mut utxo = HashMap::new(); 55 | let mut spent_txos = HashMap::new(); 56 | 57 | let blocks = self.storage.get_block_iter().unwrap(); 58 | for block in blocks { 59 | for tx in block.get_tranxs() { 60 | for (idx, txout) in tx.get_vout().iter().enumerate() { 61 | if let Some(outs) = spent_txos.get(&tx.get_id()) { 62 | for out in outs { 63 | if idx.eq(out) { 64 | break; 65 | } 66 | 67 | utxo.entry(tx.get_id()) 68 | .and_modify(|v: &mut Vec| v.push(txout.clone())) 69 | .or_insert(vec![txout.clone()]); 70 | } 71 | }else { 72 | utxo.entry(tx.get_id()) 73 | .and_modify(|v: &mut Vec| v.push(txout.clone())) 74 | .or_insert(vec![txout.clone()]); 75 | } 76 | } 77 | 78 | for txin in tx.get_vin() { 79 | spent_txos.entry(txin.get_txid()) 80 | .and_modify(|v: &mut Vec| v.push(txin.get_vout())) 81 | .or_insert(vec![txin.get_vout()]); 82 | } 83 | } 84 | } 85 | 86 | utxo 87 | } 88 | 89 | pub fn find_transaction(&self, txid: String) -> Option { 90 | let blocks = self.storage.get_block_iter().unwrap(); 91 | for block in blocks { 92 | for tx in block.get_tranxs() { 93 | if tx.get_id() == txid { 94 | return Some(tx); 95 | } 96 | } 97 | } 98 | None 99 | } 100 | 101 | pub fn blocks_info(&self) { 102 | let blocks = self.storage.get_block_iter().unwrap(); 103 | for block in blocks { 104 | info!("{:#?}", block); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/blocks/blockchain.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | sync::{ 3 | Arc, RwLock, 4 | atomic::{AtomicUsize, Ordering} 5 | }, 6 | collections::HashMap 7 | }; 8 | 9 | use tracing::info; 10 | 11 | use crate::{Block, SledDb, Storage, Transaction, Txoutput, error::BlockchainError}; 12 | 13 | pub const CURR_BITS: usize = 8; 14 | 15 | #[derive(Debug, Default)] 16 | pub struct Blockchain { 17 | storage: Arc, 18 | tip: Arc>, 19 | height: AtomicUsize, 20 | } 21 | 22 | impl Blockchain { 23 | pub fn new(storage: Arc) -> Self { 24 | if let Ok(Some(tip)) = storage.get_tip() { 25 | let height = storage.get_height().unwrap(); 26 | Self { 27 | storage, 28 | tip: Arc::new(RwLock::new(tip)), 29 | height: AtomicUsize::new(height.unwrap()), 30 | } 31 | }else { 32 | Self { 33 | storage, 34 | tip: Arc::new(RwLock::new(String::new())), 35 | height: AtomicUsize::new(0), 36 | } 37 | } 38 | } 39 | 40 | pub fn create_genesis_block(&mut self, genesis_addr: &str) { 41 | let genesis_block = Block::create_genesis_block(CURR_BITS, genesis_addr); 42 | let hash = genesis_block.get_hash(); 43 | self.height.fetch_add(1, Ordering::Relaxed); 44 | self.storage.update_blocks(&hash, &genesis_block, self.height.load(Ordering::Relaxed)); 45 | let mut tip = self.tip.write().unwrap(); 46 | *tip = hash; 47 | } 48 | 49 | pub fn mine_block(&mut self, txs: &[Transaction]) -> Block { 50 | for tx in txs { 51 | if tx.verify(self) == false { 52 | panic!("ERROR: Invalid transaction") 53 | } 54 | } 55 | 56 | let block = Block::new(txs, &self.tip.read().unwrap(), CURR_BITS); 57 | let hash = block.get_hash(); 58 | self.height.fetch_add(1, Ordering::Relaxed); 59 | self.storage.update_blocks(&hash, &block, self.height.load(Ordering::Relaxed)); 60 | let mut tip = self.tip.write().unwrap(); 61 | *tip = hash; 62 | 63 | block 64 | } 65 | 66 | pub fn add_block(&mut self, block: Block) -> Result<(), BlockchainError> { 67 | let hash = block.get_hash(); 68 | if let Some(_) = self.storage.get_block(&hash)? { 69 | info!("Block {} already exists", hash); 70 | }else { 71 | self.height.fetch_add(1, Ordering::Relaxed); 72 | self.storage.update_blocks(&hash, &block, self.height.load(Ordering::Relaxed)); 73 | let mut tip = self.tip.write().unwrap(); 74 | *tip = hash; 75 | } 76 | Ok(()) 77 | } 78 | 79 | pub fn find_utxo(&self) -> HashMap> { 80 | let mut utxo = HashMap::new(); 81 | let mut spent_txos = HashMap::new(); 82 | 83 | let blocks = self.storage.get_block_iter().unwrap(); 84 | for block in blocks { 85 | for tx in block.get_tranxs() { 86 | for (idx, txout) in tx.get_vout().iter().enumerate() { 87 | if let Some(outs) = spent_txos.get(&tx.get_id()) { 88 | for out in outs { 89 | if idx.eq(out) { 90 | break; 91 | } 92 | 93 | utxo.entry(tx.get_id()) 94 | .and_modify(|v: &mut Vec| v.push(txout.clone())) 95 | .or_insert(vec![txout.clone()]); 96 | } 97 | }else { 98 | utxo.entry(tx.get_id()) 99 | .and_modify(|v: &mut Vec| v.push(txout.clone())) 100 | .or_insert(vec![txout.clone()]); 101 | } 102 | } 103 | 104 | for txin in tx.get_vin() { 105 | spent_txos.entry(txin.get_txid()) 106 | .and_modify(|v: &mut Vec| v.push(txin.get_vout())) 107 | .or_insert(vec![txin.get_vout()]); 108 | } 109 | } 110 | } 111 | 112 | utxo 113 | } 114 | 115 | pub fn find_transaction(&self, txid: String) -> Option { 116 | let blocks = self.storage.get_block_iter().unwrap(); 117 | for block in blocks { 118 | for tx in block.get_tranxs() { 119 | if tx.get_id() == txid { 120 | return Some(tx); 121 | } 122 | } 123 | } 124 | None 125 | } 126 | 127 | pub fn blocks_info(&self) { 128 | let blocks = self.storage.get_block_iter().unwrap(); 129 | for block in blocks { 130 | info!("{:#?}", block); 131 | } 132 | } 133 | 134 | pub fn get_blocks(&self) -> Vec { 135 | self.storage.get_block_iter().unwrap().collect() 136 | } 137 | 138 | pub fn get_tip(&self) -> String { 139 | self.tip.read().unwrap().to_string() 140 | } 141 | 142 | pub fn get_height(&self) -> usize { 143 | self.height.load(Ordering::Relaxed) 144 | } 145 | } -------------------------------------------------------------------------------- /blockchain_rust_part_5/src/transactions/transaction.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | 3 | use crate::{Txinput, Txoutput, utils::{serialize, hash_to_str, ecdsa_p256_sha256_sign_digest, ecdsa_p256_sha256_sign_verify}, UTXOSet, Storage, Wallets, hash_pub_key, Blockchain}; 4 | 5 | const SUBSIDY: i32= 10; 6 | 7 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 8 | pub struct Transaction { 9 | id: String, 10 | vin: Vec, 11 | vout: Vec, 12 | } 13 | 14 | impl Transaction { 15 | pub fn new_coinbase(to: &str) -> Self { 16 | let txin = Txinput::default(); 17 | let txout = Txoutput::new(SUBSIDY, to); 18 | 19 | let mut tx = Transaction { 20 | id: String::new(), 21 | vin: vec![txin], 22 | vout: vec![txout], 23 | }; 24 | tx.set_hash(); 25 | 26 | tx 27 | } 28 | 29 | pub fn new_utxo(from: &str, to: &str, amount: i32, utxo_set: &UTXOSet, bc: &Blockchain) -> Self { 30 | let wallets = Wallets::new().unwrap(); 31 | let wallet = wallets.get_wallet(from).unwrap(); 32 | let public_key_hash = hash_pub_key(wallet.get_public_key()); 33 | 34 | let (accumulated, valid_outputs) = utxo_set.find_spendable_outputs(&public_key_hash, amount); 35 | if accumulated < amount { 36 | panic!("Error not enough funds"); 37 | } 38 | 39 | let mut inputs = vec![]; 40 | for (txid, outputs) in valid_outputs { 41 | for idx in outputs { 42 | let input = Txinput::new(txid.clone(), idx.clone(), wallet.get_public_key().to_vec()); 43 | inputs.push(input); 44 | } 45 | } 46 | 47 | let mut outputs = vec![Txoutput::new(amount, &to)]; 48 | if accumulated > amount { 49 | outputs.push(Txoutput::new(accumulated - amount, &from)); 50 | } 51 | 52 | let mut tx = Transaction { 53 | id: String::new(), 54 | vin: inputs, 55 | vout: outputs, 56 | }; 57 | tx.set_hash(); 58 | tx.sign(bc, wallet.get_pkcs8()); 59 | 60 | tx 61 | } 62 | 63 | fn set_hash(&mut self) { 64 | if let Ok(tx_ser) = serialize(self) { 65 | self.id = hash_to_str(&tx_ser) 66 | } 67 | } 68 | 69 | fn sign(&mut self, bc: &Blockchain, pkcs8: &[u8]) { 70 | let mut tx_copy = self.trimmed_copy(); 71 | 72 | for (idx, vin) in self.vin.iter_mut().enumerate() { 73 | // 查找输入引用的交易 74 | let prev_tx_option = bc.find_transaction(vin.get_txid()); 75 | if prev_tx_option.is_none() { 76 | panic!("ERROR: Previous transaction is not correct") 77 | } 78 | let prev_tx = prev_tx_option.unwrap(); 79 | tx_copy.vin[idx].set_signature(vec![]); 80 | tx_copy.vin[idx].set_pub_key(prev_tx.vout[vin.get_vout()].get_pub_key_hash()); 81 | tx_copy.set_hash(); 82 | 83 | tx_copy.vin[idx].set_pub_key(&vec![]); 84 | 85 | // 使用私钥对数据签名 86 | let signature = ecdsa_p256_sha256_sign_digest(pkcs8, tx_copy.id.as_bytes()); 87 | vin.set_signature(signature); 88 | } 89 | } 90 | 91 | pub fn verify(&self, bc: &Blockchain) -> bool { 92 | if self.is_coinbase() { 93 | return true; 94 | } 95 | let mut tx_copy = self.trimmed_copy(); 96 | for (idx, vin) in self.vin.iter().enumerate() { 97 | let prev_tx_option = bc.find_transaction(vin.get_txid()); 98 | if prev_tx_option.is_none() { 99 | panic!("ERROR: Previous transaction is not correct") 100 | } 101 | let prev_tx = prev_tx_option.unwrap(); 102 | tx_copy.vin[idx].set_signature(vec![]); 103 | tx_copy.vin[idx].set_pub_key(prev_tx.vout[vin.get_vout()].get_pub_key_hash()); 104 | tx_copy.set_hash(); 105 | 106 | tx_copy.vin[idx].set_pub_key(&vec![]); 107 | 108 | // 使用公钥验证签名 109 | let verify = ecdsa_p256_sha256_sign_verify( 110 | vin.get_pub_key(), 111 | vin.get_signature(), 112 | tx_copy.id.as_bytes(), 113 | ); 114 | if !verify { 115 | return false; 116 | } 117 | } 118 | true 119 | } 120 | 121 | // 判断是否是 coinbase 交易 122 | pub fn is_coinbase(&self) -> bool { 123 | self.vin.len() == 1 && self.vin[0].get_pub_key().len() == 0 124 | } 125 | 126 | fn trimmed_copy(&self) -> Transaction { 127 | let mut inputs = vec![]; 128 | let mut outputs = vec![]; 129 | for input in &self.vin { 130 | let txinput = Txinput::new(input.get_txid(), input.get_vout(), vec![]); 131 | inputs.push(txinput); 132 | } 133 | for output in &self.vout { 134 | outputs.push(output.clone()); 135 | } 136 | Transaction { 137 | id: self.id.clone(), 138 | vin: inputs, 139 | vout: outputs, 140 | } 141 | } 142 | 143 | pub fn get_id(&self) -> String { 144 | self.id.clone() 145 | } 146 | 147 | pub fn get_vout(&self) -> &[Txoutput] { 148 | self.vout.as_slice() 149 | } 150 | 151 | pub fn get_vin(&self) -> &[Txinput] { 152 | self.vin.as_slice() 153 | } 154 | } 155 | 156 | 157 | -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/transactions/transaction.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | 3 | use crate::{Txinput, Txoutput, utils::{serialize, hash_to_str, ecdsa_p256_sha256_sign_digest, ecdsa_p256_sha256_sign_verify}, UTXOSet, Storage, Wallets, hash_pub_key, Blockchain}; 4 | 5 | const SUBSIDY: i32= 10; 6 | 7 | #[derive(Debug, Serialize, Deserialize, Clone, Default)] 8 | pub struct Transaction { 9 | id: String, 10 | vin: Vec, 11 | vout: Vec, 12 | } 13 | 14 | impl Transaction { 15 | pub fn new_coinbase(to: &str) -> Self { 16 | let txin = Txinput::default(); 17 | let txout = Txoutput::new(SUBSIDY, to); 18 | 19 | let mut tx = Transaction { 20 | id: String::new(), 21 | vin: vec![txin], 22 | vout: vec![txout], 23 | }; 24 | tx.set_hash(); 25 | 26 | tx 27 | } 28 | 29 | pub fn new_utxo(from: &str, to: &str, amount: i32, utxo_set: &UTXOSet, bc: &Blockchain) -> Self { 30 | let wallets = Wallets::new().unwrap(); 31 | let wallet = wallets.get_wallet(from).unwrap(); 32 | let public_key_hash = hash_pub_key(wallet.get_public_key()); 33 | 34 | let (accumulated, valid_outputs) = utxo_set.find_spendable_outputs(&public_key_hash, amount); 35 | if accumulated < amount { 36 | panic!("Error not enough funds"); 37 | } 38 | 39 | let mut inputs = vec![]; 40 | for (txid, outputs) in valid_outputs { 41 | for idx in outputs { 42 | let input = Txinput::new(txid.clone(), idx.clone(), wallet.get_public_key().to_vec()); 43 | inputs.push(input); 44 | } 45 | } 46 | 47 | let mut outputs = vec![Txoutput::new(amount, &to)]; 48 | if accumulated > amount { 49 | outputs.push(Txoutput::new(accumulated - amount, &from)); 50 | } 51 | 52 | let mut tx = Transaction { 53 | id: String::new(), 54 | vin: inputs, 55 | vout: outputs, 56 | }; 57 | tx.set_hash(); 58 | tx.sign(bc, wallet.get_pkcs8()); 59 | 60 | tx 61 | } 62 | 63 | fn set_hash(&mut self) { 64 | if let Ok(tx_ser) = serialize(self) { 65 | self.id = hash_to_str(&tx_ser) 66 | } 67 | } 68 | 69 | fn sign(&mut self, bc: &Blockchain, pkcs8: &[u8]) { 70 | let mut tx_copy = self.trimmed_copy(); 71 | 72 | for (idx, vin) in self.vin.iter_mut().enumerate() { 73 | // 查找输入引用的交易 74 | let prev_tx_option = bc.find_transaction(vin.get_txid()); 75 | if prev_tx_option.is_none() { 76 | panic!("ERROR: Previous transaction is not correct") 77 | } 78 | let prev_tx = prev_tx_option.unwrap(); 79 | tx_copy.vin[idx].set_signature(vec![]); 80 | tx_copy.vin[idx].set_pub_key(prev_tx.vout[vin.get_vout()].get_pub_key_hash()); 81 | tx_copy.set_hash(); 82 | 83 | tx_copy.vin[idx].set_pub_key(&vec![]); 84 | 85 | // 使用私钥对数据签名 86 | let signature = ecdsa_p256_sha256_sign_digest(pkcs8, tx_copy.id.as_bytes()); 87 | vin.set_signature(signature); 88 | } 89 | } 90 | 91 | pub fn verify(&self, bc: &Blockchain) -> bool { 92 | if self.is_coinbase() { 93 | return true; 94 | } 95 | let mut tx_copy = self.trimmed_copy(); 96 | for (idx, vin) in self.vin.iter().enumerate() { 97 | let prev_tx_option = bc.find_transaction(vin.get_txid()); 98 | if prev_tx_option.is_none() { 99 | panic!("ERROR: Previous transaction is not correct") 100 | } 101 | let prev_tx = prev_tx_option.unwrap(); 102 | tx_copy.vin[idx].set_signature(vec![]); 103 | tx_copy.vin[idx].set_pub_key(prev_tx.vout[vin.get_vout()].get_pub_key_hash()); 104 | tx_copy.set_hash(); 105 | 106 | tx_copy.vin[idx].set_pub_key(&vec![]); 107 | 108 | // 使用公钥验证签名 109 | let verify = ecdsa_p256_sha256_sign_verify( 110 | vin.get_pub_key(), 111 | vin.get_signature(), 112 | tx_copy.id.as_bytes(), 113 | ); 114 | if !verify { 115 | return false; 116 | } 117 | } 118 | true 119 | } 120 | 121 | /// 判断是否是 coinbase 交易 122 | pub fn is_coinbase(&self) -> bool { 123 | self.vin.len() == 1 && self.vin[0].get_pub_key().len() == 0 124 | } 125 | 126 | fn trimmed_copy(&self) -> Transaction { 127 | let mut inputs = vec![]; 128 | let mut outputs = vec![]; 129 | for input in &self.vin { 130 | let txinput = Txinput::new(input.get_txid(), input.get_vout(), vec![]); 131 | inputs.push(txinput); 132 | } 133 | for output in &self.vout { 134 | outputs.push(output.clone()); 135 | } 136 | Transaction { 137 | id: self.id.clone(), 138 | vin: inputs, 139 | vout: outputs, 140 | } 141 | } 142 | 143 | pub fn get_id(&self) -> String { 144 | self.id.clone() 145 | } 146 | 147 | pub fn get_vout(&self) -> &[Txoutput] { 148 | self.vout.as_slice() 149 | } 150 | 151 | pub fn get_vin(&self) -> &[Txinput] { 152 | self.vin.as_slice() 153 | } 154 | } 155 | 156 | 157 | -------------------------------------------------------------------------------- /blockchain_rust_part_6/src/networks/node.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | use futures::StreamExt; 3 | use libp2p::{Swarm, swarm::SwarmEvent, PeerId}; 4 | use anyhow::Result; 5 | use tokio::{ 6 | io::{BufReader, stdin, AsyncBufReadExt}, 7 | sync::mpsc 8 | }; 9 | use tracing::{info, error}; 10 | use crate::{Blockchain, BlockchainBehaviour, Storage, SledDb, UTXOSet, Commands, Messages, Block, Wallets, Transaction}; 11 | 12 | use super::{create_swarm, BLOCK_TOPIC, TRANX_TOPIC, PEER_ID, WALLET_MAP}; 13 | 14 | pub struct Node { 15 | bc: Blockchain, 16 | utxos: UTXOSet, 17 | msg_receiver: mpsc::UnboundedReceiver, 18 | swarm: Swarm, 19 | } 20 | 21 | impl Node { 22 | pub async fn new(storage: Arc) -> Result { 23 | let (msg_sender, msg_receiver) = mpsc::unbounded_channel(); 24 | 25 | Ok(Self { 26 | bc: Blockchain::new(storage.clone()), 27 | utxos: UTXOSet::new(storage), 28 | msg_receiver, 29 | swarm: create_swarm(vec![BLOCK_TOPIC.clone(), TRANX_TOPIC.clone()], msg_sender).await?, 30 | }) 31 | } 32 | 33 | pub async fn list_peers(&mut self) -> Result> { 34 | let nodes = self.swarm.behaviour().mdns.discovered_nodes(); 35 | let peers = nodes.collect::>(); 36 | Ok(peers) 37 | } 38 | 39 | async fn sync(&mut self) -> Result<()> { 40 | let version = Messages::Version { 41 | best_height: self.bc.get_height(), 42 | from_addr: PEER_ID.to_string(), 43 | }; 44 | 45 | let line = serde_json::to_vec(&version)?; 46 | self.swarm.behaviour_mut().gossipsub 47 | .publish(BLOCK_TOPIC.clone(), line).unwrap(); 48 | 49 | Ok(()) 50 | } 51 | 52 | async fn mine_block(&mut self, from: &str, to: &str, amount: i32) -> Result<()> { 53 | let tx = Transaction::new_utxo(from, to, amount, &self.utxos, &self.bc); 54 | let txs = vec![tx]; 55 | let block = self.bc.mine_block(&txs); 56 | self.utxos.reindex(&self.bc).unwrap(); 57 | 58 | let b = Messages::Block { block }; 59 | let line = serde_json::to_vec(&b)?; 60 | self.swarm.behaviour_mut().gossipsub 61 | .publish(BLOCK_TOPIC.clone(), line).unwrap(); 62 | Ok(()) 63 | } 64 | 65 | async fn process_version_msg(&mut self, best_height: usize, from_addr: String) -> Result<()> { 66 | if self.bc.get_height() > best_height { 67 | let blocks = Messages::Blocks { 68 | blocks: self.bc.get_blocks(), 69 | height: self.bc.get_height(), 70 | to_addr: from_addr, 71 | }; 72 | let msg = serde_json::to_vec(&blocks)?; 73 | self.swarm.behaviour_mut().gossipsub 74 | .publish(BLOCK_TOPIC.clone(), msg).unwrap(); 75 | } 76 | Ok(()) 77 | } 78 | 79 | async fn process_blocks_msg(&mut self, blocks: Vec, to_addr: String, height: usize) -> Result<()> { 80 | if PEER_ID.to_string() == to_addr && self.bc.get_height() < height { 81 | for block in blocks { 82 | self.bc.add_block(block)?; 83 | } 84 | 85 | self.utxos.reindex(&self.bc).unwrap(); 86 | } 87 | Ok(()) 88 | } 89 | 90 | pub async fn process_block_msg(&mut self, block: Block) -> Result<()> { 91 | self.bc.add_block(block)?; 92 | self.utxos.reindex(&self.bc).unwrap(); 93 | Ok(()) 94 | } 95 | 96 | pub async fn start(&mut self) -> Result<()> { 97 | self.swarm.listen_on("/ip4/127.0.0.1/tcp/0".parse()?)?; 98 | 99 | let mut stdin = BufReader::new(stdin()).lines(); 100 | 101 | loop { 102 | tokio::select! { 103 | line = stdin.next_line() => { 104 | let line = line?.expect("stdin closed"); 105 | let command = serde_json::from_str(line.as_str()); 106 | match command { 107 | Ok(cmd) => match cmd { 108 | Commands::Genesis(addr) => { 109 | if self.bc.get_tip().is_empty() { 110 | self.bc.create_genesis_block(addr.as_str()); 111 | self.utxos.reindex(&self.bc)?; 112 | info!("Genesis block was created success!"); 113 | }else { 114 | info!("Already exists blockchain, don't need genesis block!"); 115 | continue; 116 | } 117 | }, 118 | Commands::Blocks(_) => { 119 | self.bc.blocks_info(); 120 | info!("tip: {}", self.bc.get_tip()); 121 | info!("height: {}", self.bc.get_height()); 122 | }, 123 | Commands::Sync(_) => { 124 | self.sync().await?; 125 | }, 126 | Commands::CreateWallet(name) => { 127 | WALLET_MAP.lock().await.entry(name.clone()).or_insert_with(|| { 128 | let mut wallets = Wallets::new().unwrap(); 129 | let addr = wallets.create_wallet(); 130 | info!("{}'s address is {}", name, addr); 131 | addr 132 | }); 133 | }, 134 | Commands::GetAddress(name) => { 135 | info!("{}'s address is {}", name, WALLET_MAP.clone().lock().await.get(&name).unwrap()); 136 | }, 137 | Commands::Trans{from, to, amount} => { 138 | self.mine_block(&from, &to, amount.parse::().unwrap()).await?; 139 | }, 140 | }, 141 | Err(e) => { 142 | error!("Parse command error: {}", e); 143 | continue; 144 | }, 145 | } 146 | }, 147 | messages = self.msg_receiver.recv() => { 148 | if let Some(msg) = messages { 149 | match msg { 150 | Messages::Version{best_height, from_addr} => { 151 | self.process_version_msg(best_height, from_addr).await?; 152 | }, 153 | Messages::Blocks{blocks, to_addr, height} => { 154 | self.process_blocks_msg(blocks, to_addr, height).await?; 155 | }, 156 | Messages::Block{block} => { 157 | self.process_block_msg(block).await?; 158 | } 159 | } 160 | } 161 | }, 162 | event = self.swarm.select_next_some() => { 163 | if let SwarmEvent::NewListenAddr { address, .. } = event { 164 | println!("Listening on {:?}", address); 165 | } 166 | } 167 | } 168 | } 169 | } 170 | } -------------------------------------------------------------------------------- /blockchain_rust_part_1/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ansi_term" 7 | version = "0.12.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 10 | dependencies = [ 11 | "winapi", 12 | ] 13 | 14 | [[package]] 15 | name = "anyhow" 16 | version = "1.0.56" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.1.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 25 | 26 | [[package]] 27 | name = "bincode" 28 | version = "1.3.3" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 31 | dependencies = [ 32 | "serde", 33 | ] 34 | 35 | [[package]] 36 | name = "blockchain_rust_part_1" 37 | version = "0.1.0" 38 | dependencies = [ 39 | "anyhow", 40 | "bincode", 41 | "chrono", 42 | "rust-crypto", 43 | "serde", 44 | "thiserror", 45 | "tracing", 46 | "tracing-subscriber", 47 | ] 48 | 49 | [[package]] 50 | name = "cfg-if" 51 | version = "1.0.0" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 54 | 55 | [[package]] 56 | name = "chrono" 57 | version = "0.4.19" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" 60 | dependencies = [ 61 | "libc", 62 | "num-integer", 63 | "num-traits", 64 | "time", 65 | "winapi", 66 | ] 67 | 68 | [[package]] 69 | name = "fuchsia-cprng" 70 | version = "0.1.1" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 73 | 74 | [[package]] 75 | name = "gcc" 76 | version = "0.3.55" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" 79 | 80 | [[package]] 81 | name = "itoa" 82 | version = "1.0.1" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 85 | 86 | [[package]] 87 | name = "lazy_static" 88 | version = "1.4.0" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 91 | 92 | [[package]] 93 | name = "libc" 94 | version = "0.2.122" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" 97 | 98 | [[package]] 99 | name = "log" 100 | version = "0.4.16" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" 103 | dependencies = [ 104 | "cfg-if", 105 | ] 106 | 107 | [[package]] 108 | name = "matchers" 109 | version = "0.0.1" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" 112 | dependencies = [ 113 | "regex-automata", 114 | ] 115 | 116 | [[package]] 117 | name = "num-integer" 118 | version = "0.1.44" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 121 | dependencies = [ 122 | "autocfg", 123 | "num-traits", 124 | ] 125 | 126 | [[package]] 127 | name = "num-traits" 128 | version = "0.2.14" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 131 | dependencies = [ 132 | "autocfg", 133 | ] 134 | 135 | [[package]] 136 | name = "once_cell" 137 | version = "1.10.0" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 140 | 141 | [[package]] 142 | name = "pin-project-lite" 143 | version = "0.2.8" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" 146 | 147 | [[package]] 148 | name = "proc-macro2" 149 | version = "1.0.37" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" 152 | dependencies = [ 153 | "unicode-xid", 154 | ] 155 | 156 | [[package]] 157 | name = "quote" 158 | version = "1.0.17" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" 161 | dependencies = [ 162 | "proc-macro2", 163 | ] 164 | 165 | [[package]] 166 | name = "rand" 167 | version = "0.3.23" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" 170 | dependencies = [ 171 | "libc", 172 | "rand 0.4.6", 173 | ] 174 | 175 | [[package]] 176 | name = "rand" 177 | version = "0.4.6" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 180 | dependencies = [ 181 | "fuchsia-cprng", 182 | "libc", 183 | "rand_core 0.3.1", 184 | "rdrand", 185 | "winapi", 186 | ] 187 | 188 | [[package]] 189 | name = "rand_core" 190 | version = "0.3.1" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 193 | dependencies = [ 194 | "rand_core 0.4.2", 195 | ] 196 | 197 | [[package]] 198 | name = "rand_core" 199 | version = "0.4.2" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 202 | 203 | [[package]] 204 | name = "rdrand" 205 | version = "0.4.0" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 208 | dependencies = [ 209 | "rand_core 0.3.1", 210 | ] 211 | 212 | [[package]] 213 | name = "regex" 214 | version = "1.5.5" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 217 | dependencies = [ 218 | "regex-syntax", 219 | ] 220 | 221 | [[package]] 222 | name = "regex-automata" 223 | version = "0.1.10" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 226 | dependencies = [ 227 | "regex-syntax", 228 | ] 229 | 230 | [[package]] 231 | name = "regex-syntax" 232 | version = "0.6.25" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 235 | 236 | [[package]] 237 | name = "rust-crypto" 238 | version = "0.2.36" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" 241 | dependencies = [ 242 | "gcc", 243 | "libc", 244 | "rand 0.3.23", 245 | "rustc-serialize", 246 | "time", 247 | ] 248 | 249 | [[package]] 250 | name = "rustc-serialize" 251 | version = "0.3.24" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" 254 | 255 | [[package]] 256 | name = "ryu" 257 | version = "1.0.9" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 260 | 261 | [[package]] 262 | name = "serde" 263 | version = "1.0.136" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 266 | dependencies = [ 267 | "serde_derive", 268 | ] 269 | 270 | [[package]] 271 | name = "serde_derive" 272 | version = "1.0.136" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" 275 | dependencies = [ 276 | "proc-macro2", 277 | "quote", 278 | "syn", 279 | ] 280 | 281 | [[package]] 282 | name = "serde_json" 283 | version = "1.0.79" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" 286 | dependencies = [ 287 | "itoa", 288 | "ryu", 289 | "serde", 290 | ] 291 | 292 | [[package]] 293 | name = "sharded-slab" 294 | version = "0.1.4" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 297 | dependencies = [ 298 | "lazy_static", 299 | ] 300 | 301 | [[package]] 302 | name = "smallvec" 303 | version = "1.8.0" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 306 | 307 | [[package]] 308 | name = "syn" 309 | version = "1.0.91" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" 312 | dependencies = [ 313 | "proc-macro2", 314 | "quote", 315 | "unicode-xid", 316 | ] 317 | 318 | [[package]] 319 | name = "thiserror" 320 | version = "1.0.30" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 323 | dependencies = [ 324 | "thiserror-impl", 325 | ] 326 | 327 | [[package]] 328 | name = "thiserror-impl" 329 | version = "1.0.30" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 332 | dependencies = [ 333 | "proc-macro2", 334 | "quote", 335 | "syn", 336 | ] 337 | 338 | [[package]] 339 | name = "thread_local" 340 | version = "1.1.4" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" 343 | dependencies = [ 344 | "once_cell", 345 | ] 346 | 347 | [[package]] 348 | name = "time" 349 | version = "0.1.44" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" 352 | dependencies = [ 353 | "libc", 354 | "wasi", 355 | "winapi", 356 | ] 357 | 358 | [[package]] 359 | name = "tracing" 360 | version = "0.1.32" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" 363 | dependencies = [ 364 | "cfg-if", 365 | "pin-project-lite", 366 | "tracing-attributes", 367 | "tracing-core", 368 | ] 369 | 370 | [[package]] 371 | name = "tracing-attributes" 372 | version = "0.1.20" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" 375 | dependencies = [ 376 | "proc-macro2", 377 | "quote", 378 | "syn", 379 | ] 380 | 381 | [[package]] 382 | name = "tracing-core" 383 | version = "0.1.24" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee" 386 | dependencies = [ 387 | "lazy_static", 388 | "valuable", 389 | ] 390 | 391 | [[package]] 392 | name = "tracing-log" 393 | version = "0.1.2" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" 396 | dependencies = [ 397 | "lazy_static", 398 | "log", 399 | "tracing-core", 400 | ] 401 | 402 | [[package]] 403 | name = "tracing-serde" 404 | version = "0.1.3" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" 407 | dependencies = [ 408 | "serde", 409 | "tracing-core", 410 | ] 411 | 412 | [[package]] 413 | name = "tracing-subscriber" 414 | version = "0.2.25" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" 417 | dependencies = [ 418 | "ansi_term", 419 | "chrono", 420 | "lazy_static", 421 | "matchers", 422 | "regex", 423 | "serde", 424 | "serde_json", 425 | "sharded-slab", 426 | "smallvec", 427 | "thread_local", 428 | "tracing", 429 | "tracing-core", 430 | "tracing-log", 431 | "tracing-serde", 432 | ] 433 | 434 | [[package]] 435 | name = "unicode-xid" 436 | version = "0.2.2" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 439 | 440 | [[package]] 441 | name = "valuable" 442 | version = "0.1.0" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 445 | 446 | [[package]] 447 | name = "wasi" 448 | version = "0.10.0+wasi-snapshot-preview1" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 451 | 452 | [[package]] 453 | name = "winapi" 454 | version = "0.3.9" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 457 | dependencies = [ 458 | "winapi-i686-pc-windows-gnu", 459 | "winapi-x86_64-pc-windows-gnu", 460 | ] 461 | 462 | [[package]] 463 | name = "winapi-i686-pc-windows-gnu" 464 | version = "0.4.0" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 467 | 468 | [[package]] 469 | name = "winapi-x86_64-pc-windows-gnu" 470 | version = "0.4.0" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 473 | -------------------------------------------------------------------------------- /blockchain_rust_part_2/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ansi_term" 7 | version = "0.12.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 10 | dependencies = [ 11 | "winapi", 12 | ] 13 | 14 | [[package]] 15 | name = "anyhow" 16 | version = "1.0.56" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.1.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 25 | 26 | [[package]] 27 | name = "bigint" 28 | version = "4.4.3" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "c0e8c8a600052b52482eff2cf4d810e462fdff1f656ac1ecb6232132a1ed7def" 31 | dependencies = [ 32 | "byteorder", 33 | "crunchy", 34 | ] 35 | 36 | [[package]] 37 | name = "bincode" 38 | version = "1.3.3" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 41 | dependencies = [ 42 | "serde", 43 | ] 44 | 45 | [[package]] 46 | name = "blockchain_rust_part_2" 47 | version = "0.1.0" 48 | dependencies = [ 49 | "anyhow", 50 | "bigint", 51 | "bincode", 52 | "chrono", 53 | "rust-crypto", 54 | "serde", 55 | "thiserror", 56 | "tracing", 57 | "tracing-subscriber", 58 | ] 59 | 60 | [[package]] 61 | name = "byteorder" 62 | version = "1.4.3" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 65 | 66 | [[package]] 67 | name = "cfg-if" 68 | version = "1.0.0" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 71 | 72 | [[package]] 73 | name = "chrono" 74 | version = "0.4.19" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" 77 | dependencies = [ 78 | "libc", 79 | "num-integer", 80 | "num-traits", 81 | "time", 82 | "winapi", 83 | ] 84 | 85 | [[package]] 86 | name = "crunchy" 87 | version = "0.1.6" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" 90 | 91 | [[package]] 92 | name = "fuchsia-cprng" 93 | version = "0.1.1" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 96 | 97 | [[package]] 98 | name = "gcc" 99 | version = "0.3.55" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" 102 | 103 | [[package]] 104 | name = "itoa" 105 | version = "1.0.1" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 108 | 109 | [[package]] 110 | name = "lazy_static" 111 | version = "1.4.0" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 114 | 115 | [[package]] 116 | name = "libc" 117 | version = "0.2.122" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" 120 | 121 | [[package]] 122 | name = "log" 123 | version = "0.4.16" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" 126 | dependencies = [ 127 | "cfg-if", 128 | ] 129 | 130 | [[package]] 131 | name = "matchers" 132 | version = "0.0.1" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" 135 | dependencies = [ 136 | "regex-automata", 137 | ] 138 | 139 | [[package]] 140 | name = "num-integer" 141 | version = "0.1.44" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 144 | dependencies = [ 145 | "autocfg", 146 | "num-traits", 147 | ] 148 | 149 | [[package]] 150 | name = "num-traits" 151 | version = "0.2.14" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 154 | dependencies = [ 155 | "autocfg", 156 | ] 157 | 158 | [[package]] 159 | name = "once_cell" 160 | version = "1.10.0" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 163 | 164 | [[package]] 165 | name = "pin-project-lite" 166 | version = "0.2.8" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" 169 | 170 | [[package]] 171 | name = "proc-macro2" 172 | version = "1.0.37" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" 175 | dependencies = [ 176 | "unicode-xid", 177 | ] 178 | 179 | [[package]] 180 | name = "quote" 181 | version = "1.0.17" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" 184 | dependencies = [ 185 | "proc-macro2", 186 | ] 187 | 188 | [[package]] 189 | name = "rand" 190 | version = "0.3.23" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" 193 | dependencies = [ 194 | "libc", 195 | "rand 0.4.6", 196 | ] 197 | 198 | [[package]] 199 | name = "rand" 200 | version = "0.4.6" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 203 | dependencies = [ 204 | "fuchsia-cprng", 205 | "libc", 206 | "rand_core 0.3.1", 207 | "rdrand", 208 | "winapi", 209 | ] 210 | 211 | [[package]] 212 | name = "rand_core" 213 | version = "0.3.1" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 216 | dependencies = [ 217 | "rand_core 0.4.2", 218 | ] 219 | 220 | [[package]] 221 | name = "rand_core" 222 | version = "0.4.2" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 225 | 226 | [[package]] 227 | name = "rdrand" 228 | version = "0.4.0" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 231 | dependencies = [ 232 | "rand_core 0.3.1", 233 | ] 234 | 235 | [[package]] 236 | name = "regex" 237 | version = "1.5.5" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 240 | dependencies = [ 241 | "regex-syntax", 242 | ] 243 | 244 | [[package]] 245 | name = "regex-automata" 246 | version = "0.1.10" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 249 | dependencies = [ 250 | "regex-syntax", 251 | ] 252 | 253 | [[package]] 254 | name = "regex-syntax" 255 | version = "0.6.25" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 258 | 259 | [[package]] 260 | name = "rust-crypto" 261 | version = "0.2.36" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" 264 | dependencies = [ 265 | "gcc", 266 | "libc", 267 | "rand 0.3.23", 268 | "rustc-serialize", 269 | "time", 270 | ] 271 | 272 | [[package]] 273 | name = "rustc-serialize" 274 | version = "0.3.24" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" 277 | 278 | [[package]] 279 | name = "ryu" 280 | version = "1.0.9" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 283 | 284 | [[package]] 285 | name = "serde" 286 | version = "1.0.136" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 289 | dependencies = [ 290 | "serde_derive", 291 | ] 292 | 293 | [[package]] 294 | name = "serde_derive" 295 | version = "1.0.136" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" 298 | dependencies = [ 299 | "proc-macro2", 300 | "quote", 301 | "syn", 302 | ] 303 | 304 | [[package]] 305 | name = "serde_json" 306 | version = "1.0.79" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" 309 | dependencies = [ 310 | "itoa", 311 | "ryu", 312 | "serde", 313 | ] 314 | 315 | [[package]] 316 | name = "sharded-slab" 317 | version = "0.1.4" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 320 | dependencies = [ 321 | "lazy_static", 322 | ] 323 | 324 | [[package]] 325 | name = "smallvec" 326 | version = "1.8.0" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 329 | 330 | [[package]] 331 | name = "syn" 332 | version = "1.0.91" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" 335 | dependencies = [ 336 | "proc-macro2", 337 | "quote", 338 | "unicode-xid", 339 | ] 340 | 341 | [[package]] 342 | name = "thiserror" 343 | version = "1.0.30" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 346 | dependencies = [ 347 | "thiserror-impl", 348 | ] 349 | 350 | [[package]] 351 | name = "thiserror-impl" 352 | version = "1.0.30" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 355 | dependencies = [ 356 | "proc-macro2", 357 | "quote", 358 | "syn", 359 | ] 360 | 361 | [[package]] 362 | name = "thread_local" 363 | version = "1.1.4" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" 366 | dependencies = [ 367 | "once_cell", 368 | ] 369 | 370 | [[package]] 371 | name = "time" 372 | version = "0.1.44" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" 375 | dependencies = [ 376 | "libc", 377 | "wasi", 378 | "winapi", 379 | ] 380 | 381 | [[package]] 382 | name = "tracing" 383 | version = "0.1.32" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" 386 | dependencies = [ 387 | "cfg-if", 388 | "pin-project-lite", 389 | "tracing-attributes", 390 | "tracing-core", 391 | ] 392 | 393 | [[package]] 394 | name = "tracing-attributes" 395 | version = "0.1.20" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" 398 | dependencies = [ 399 | "proc-macro2", 400 | "quote", 401 | "syn", 402 | ] 403 | 404 | [[package]] 405 | name = "tracing-core" 406 | version = "0.1.24" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee" 409 | dependencies = [ 410 | "lazy_static", 411 | "valuable", 412 | ] 413 | 414 | [[package]] 415 | name = "tracing-log" 416 | version = "0.1.2" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" 419 | dependencies = [ 420 | "lazy_static", 421 | "log", 422 | "tracing-core", 423 | ] 424 | 425 | [[package]] 426 | name = "tracing-serde" 427 | version = "0.1.3" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" 430 | dependencies = [ 431 | "serde", 432 | "tracing-core", 433 | ] 434 | 435 | [[package]] 436 | name = "tracing-subscriber" 437 | version = "0.2.25" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" 440 | dependencies = [ 441 | "ansi_term", 442 | "chrono", 443 | "lazy_static", 444 | "matchers", 445 | "regex", 446 | "serde", 447 | "serde_json", 448 | "sharded-slab", 449 | "smallvec", 450 | "thread_local", 451 | "tracing", 452 | "tracing-core", 453 | "tracing-log", 454 | "tracing-serde", 455 | ] 456 | 457 | [[package]] 458 | name = "unicode-xid" 459 | version = "0.2.2" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 462 | 463 | [[package]] 464 | name = "valuable" 465 | version = "0.1.0" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 468 | 469 | [[package]] 470 | name = "wasi" 471 | version = "0.10.0+wasi-snapshot-preview1" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 474 | 475 | [[package]] 476 | name = "winapi" 477 | version = "0.3.9" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 480 | dependencies = [ 481 | "winapi-i686-pc-windows-gnu", 482 | "winapi-x86_64-pc-windows-gnu", 483 | ] 484 | 485 | [[package]] 486 | name = "winapi-i686-pc-windows-gnu" 487 | version = "0.4.0" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 490 | 491 | [[package]] 492 | name = "winapi-x86_64-pc-windows-gnu" 493 | version = "0.4.0" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 496 | -------------------------------------------------------------------------------- /blockchain_rust_part_3/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ansi_term" 7 | version = "0.12.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 10 | dependencies = [ 11 | "winapi", 12 | ] 13 | 14 | [[package]] 15 | name = "anyhow" 16 | version = "1.0.56" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.1.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 25 | 26 | [[package]] 27 | name = "bigint" 28 | version = "4.4.3" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "c0e8c8a600052b52482eff2cf4d810e462fdff1f656ac1ecb6232132a1ed7def" 31 | dependencies = [ 32 | "byteorder", 33 | "crunchy", 34 | ] 35 | 36 | [[package]] 37 | name = "bincode" 38 | version = "1.3.3" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 41 | dependencies = [ 42 | "serde", 43 | ] 44 | 45 | [[package]] 46 | name = "bitflags" 47 | version = "1.3.2" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 50 | 51 | [[package]] 52 | name = "blockchain_rust_part_3" 53 | version = "0.1.0" 54 | dependencies = [ 55 | "anyhow", 56 | "bigint", 57 | "bincode", 58 | "chrono", 59 | "rust-crypto", 60 | "serde", 61 | "sled", 62 | "thiserror", 63 | "tracing", 64 | "tracing-subscriber", 65 | ] 66 | 67 | [[package]] 68 | name = "byteorder" 69 | version = "1.4.3" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 72 | 73 | [[package]] 74 | name = "cfg-if" 75 | version = "1.0.0" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 78 | 79 | [[package]] 80 | name = "chrono" 81 | version = "0.4.19" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" 84 | dependencies = [ 85 | "libc", 86 | "num-integer", 87 | "num-traits", 88 | "time", 89 | "winapi", 90 | ] 91 | 92 | [[package]] 93 | name = "crc32fast" 94 | version = "1.3.2" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 97 | dependencies = [ 98 | "cfg-if", 99 | ] 100 | 101 | [[package]] 102 | name = "crossbeam-epoch" 103 | version = "0.9.8" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" 106 | dependencies = [ 107 | "autocfg", 108 | "cfg-if", 109 | "crossbeam-utils", 110 | "lazy_static", 111 | "memoffset", 112 | "scopeguard", 113 | ] 114 | 115 | [[package]] 116 | name = "crossbeam-utils" 117 | version = "0.8.8" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" 120 | dependencies = [ 121 | "cfg-if", 122 | "lazy_static", 123 | ] 124 | 125 | [[package]] 126 | name = "crunchy" 127 | version = "0.1.6" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" 130 | 131 | [[package]] 132 | name = "fs2" 133 | version = "0.4.3" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" 136 | dependencies = [ 137 | "libc", 138 | "winapi", 139 | ] 140 | 141 | [[package]] 142 | name = "fuchsia-cprng" 143 | version = "0.1.1" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 146 | 147 | [[package]] 148 | name = "fxhash" 149 | version = "0.2.1" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 152 | dependencies = [ 153 | "byteorder", 154 | ] 155 | 156 | [[package]] 157 | name = "gcc" 158 | version = "0.3.55" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" 161 | 162 | [[package]] 163 | name = "instant" 164 | version = "0.1.12" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 167 | dependencies = [ 168 | "cfg-if", 169 | ] 170 | 171 | [[package]] 172 | name = "itoa" 173 | version = "1.0.1" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 176 | 177 | [[package]] 178 | name = "lazy_static" 179 | version = "1.4.0" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 182 | 183 | [[package]] 184 | name = "libc" 185 | version = "0.2.122" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" 188 | 189 | [[package]] 190 | name = "lock_api" 191 | version = "0.4.7" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" 194 | dependencies = [ 195 | "autocfg", 196 | "scopeguard", 197 | ] 198 | 199 | [[package]] 200 | name = "log" 201 | version = "0.4.16" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" 204 | dependencies = [ 205 | "cfg-if", 206 | ] 207 | 208 | [[package]] 209 | name = "matchers" 210 | version = "0.0.1" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" 213 | dependencies = [ 214 | "regex-automata", 215 | ] 216 | 217 | [[package]] 218 | name = "memoffset" 219 | version = "0.6.5" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 222 | dependencies = [ 223 | "autocfg", 224 | ] 225 | 226 | [[package]] 227 | name = "num-integer" 228 | version = "0.1.44" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 231 | dependencies = [ 232 | "autocfg", 233 | "num-traits", 234 | ] 235 | 236 | [[package]] 237 | name = "num-traits" 238 | version = "0.2.14" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 241 | dependencies = [ 242 | "autocfg", 243 | ] 244 | 245 | [[package]] 246 | name = "once_cell" 247 | version = "1.10.0" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 250 | 251 | [[package]] 252 | name = "parking_lot" 253 | version = "0.11.2" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 256 | dependencies = [ 257 | "instant", 258 | "lock_api", 259 | "parking_lot_core", 260 | ] 261 | 262 | [[package]] 263 | name = "parking_lot_core" 264 | version = "0.8.5" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" 267 | dependencies = [ 268 | "cfg-if", 269 | "instant", 270 | "libc", 271 | "redox_syscall", 272 | "smallvec", 273 | "winapi", 274 | ] 275 | 276 | [[package]] 277 | name = "pin-project-lite" 278 | version = "0.2.8" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" 281 | 282 | [[package]] 283 | name = "proc-macro2" 284 | version = "1.0.37" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" 287 | dependencies = [ 288 | "unicode-xid", 289 | ] 290 | 291 | [[package]] 292 | name = "quote" 293 | version = "1.0.17" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" 296 | dependencies = [ 297 | "proc-macro2", 298 | ] 299 | 300 | [[package]] 301 | name = "rand" 302 | version = "0.3.23" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" 305 | dependencies = [ 306 | "libc", 307 | "rand 0.4.6", 308 | ] 309 | 310 | [[package]] 311 | name = "rand" 312 | version = "0.4.6" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 315 | dependencies = [ 316 | "fuchsia-cprng", 317 | "libc", 318 | "rand_core 0.3.1", 319 | "rdrand", 320 | "winapi", 321 | ] 322 | 323 | [[package]] 324 | name = "rand_core" 325 | version = "0.3.1" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 328 | dependencies = [ 329 | "rand_core 0.4.2", 330 | ] 331 | 332 | [[package]] 333 | name = "rand_core" 334 | version = "0.4.2" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 337 | 338 | [[package]] 339 | name = "rdrand" 340 | version = "0.4.0" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 343 | dependencies = [ 344 | "rand_core 0.3.1", 345 | ] 346 | 347 | [[package]] 348 | name = "redox_syscall" 349 | version = "0.2.13" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" 352 | dependencies = [ 353 | "bitflags", 354 | ] 355 | 356 | [[package]] 357 | name = "regex" 358 | version = "1.5.5" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 361 | dependencies = [ 362 | "regex-syntax", 363 | ] 364 | 365 | [[package]] 366 | name = "regex-automata" 367 | version = "0.1.10" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 370 | dependencies = [ 371 | "regex-syntax", 372 | ] 373 | 374 | [[package]] 375 | name = "regex-syntax" 376 | version = "0.6.25" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 379 | 380 | [[package]] 381 | name = "rust-crypto" 382 | version = "0.2.36" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" 385 | dependencies = [ 386 | "gcc", 387 | "libc", 388 | "rand 0.3.23", 389 | "rustc-serialize", 390 | "time", 391 | ] 392 | 393 | [[package]] 394 | name = "rustc-serialize" 395 | version = "0.3.24" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" 398 | 399 | [[package]] 400 | name = "ryu" 401 | version = "1.0.9" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 404 | 405 | [[package]] 406 | name = "scopeguard" 407 | version = "1.1.0" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 410 | 411 | [[package]] 412 | name = "serde" 413 | version = "1.0.136" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 416 | dependencies = [ 417 | "serde_derive", 418 | ] 419 | 420 | [[package]] 421 | name = "serde_derive" 422 | version = "1.0.136" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" 425 | dependencies = [ 426 | "proc-macro2", 427 | "quote", 428 | "syn", 429 | ] 430 | 431 | [[package]] 432 | name = "serde_json" 433 | version = "1.0.79" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" 436 | dependencies = [ 437 | "itoa", 438 | "ryu", 439 | "serde", 440 | ] 441 | 442 | [[package]] 443 | name = "sharded-slab" 444 | version = "0.1.4" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 447 | dependencies = [ 448 | "lazy_static", 449 | ] 450 | 451 | [[package]] 452 | name = "sled" 453 | version = "0.34.7" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" 456 | dependencies = [ 457 | "crc32fast", 458 | "crossbeam-epoch", 459 | "crossbeam-utils", 460 | "fs2", 461 | "fxhash", 462 | "libc", 463 | "log", 464 | "parking_lot", 465 | ] 466 | 467 | [[package]] 468 | name = "smallvec" 469 | version = "1.8.0" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 472 | 473 | [[package]] 474 | name = "syn" 475 | version = "1.0.91" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" 478 | dependencies = [ 479 | "proc-macro2", 480 | "quote", 481 | "unicode-xid", 482 | ] 483 | 484 | [[package]] 485 | name = "thiserror" 486 | version = "1.0.30" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 489 | dependencies = [ 490 | "thiserror-impl", 491 | ] 492 | 493 | [[package]] 494 | name = "thiserror-impl" 495 | version = "1.0.30" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 498 | dependencies = [ 499 | "proc-macro2", 500 | "quote", 501 | "syn", 502 | ] 503 | 504 | [[package]] 505 | name = "thread_local" 506 | version = "1.1.4" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" 509 | dependencies = [ 510 | "once_cell", 511 | ] 512 | 513 | [[package]] 514 | name = "time" 515 | version = "0.1.44" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" 518 | dependencies = [ 519 | "libc", 520 | "wasi", 521 | "winapi", 522 | ] 523 | 524 | [[package]] 525 | name = "tracing" 526 | version = "0.1.32" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" 529 | dependencies = [ 530 | "cfg-if", 531 | "pin-project-lite", 532 | "tracing-attributes", 533 | "tracing-core", 534 | ] 535 | 536 | [[package]] 537 | name = "tracing-attributes" 538 | version = "0.1.20" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" 541 | dependencies = [ 542 | "proc-macro2", 543 | "quote", 544 | "syn", 545 | ] 546 | 547 | [[package]] 548 | name = "tracing-core" 549 | version = "0.1.24" 550 | source = "registry+https://github.com/rust-lang/crates.io-index" 551 | checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee" 552 | dependencies = [ 553 | "lazy_static", 554 | "valuable", 555 | ] 556 | 557 | [[package]] 558 | name = "tracing-log" 559 | version = "0.1.2" 560 | source = "registry+https://github.com/rust-lang/crates.io-index" 561 | checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" 562 | dependencies = [ 563 | "lazy_static", 564 | "log", 565 | "tracing-core", 566 | ] 567 | 568 | [[package]] 569 | name = "tracing-serde" 570 | version = "0.1.3" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" 573 | dependencies = [ 574 | "serde", 575 | "tracing-core", 576 | ] 577 | 578 | [[package]] 579 | name = "tracing-subscriber" 580 | version = "0.2.25" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" 583 | dependencies = [ 584 | "ansi_term", 585 | "chrono", 586 | "lazy_static", 587 | "matchers", 588 | "regex", 589 | "serde", 590 | "serde_json", 591 | "sharded-slab", 592 | "smallvec", 593 | "thread_local", 594 | "tracing", 595 | "tracing-core", 596 | "tracing-log", 597 | "tracing-serde", 598 | ] 599 | 600 | [[package]] 601 | name = "unicode-xid" 602 | version = "0.2.2" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 605 | 606 | [[package]] 607 | name = "valuable" 608 | version = "0.1.0" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 611 | 612 | [[package]] 613 | name = "wasi" 614 | version = "0.10.0+wasi-snapshot-preview1" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 617 | 618 | [[package]] 619 | name = "winapi" 620 | version = "0.3.9" 621 | source = "registry+https://github.com/rust-lang/crates.io-index" 622 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 623 | dependencies = [ 624 | "winapi-i686-pc-windows-gnu", 625 | "winapi-x86_64-pc-windows-gnu", 626 | ] 627 | 628 | [[package]] 629 | name = "winapi-i686-pc-windows-gnu" 630 | version = "0.4.0" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 633 | 634 | [[package]] 635 | name = "winapi-x86_64-pc-windows-gnu" 636 | version = "0.4.0" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 639 | -------------------------------------------------------------------------------- /blockchain_rust_part_4/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ansi_term" 7 | version = "0.12.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 10 | dependencies = [ 11 | "winapi", 12 | ] 13 | 14 | [[package]] 15 | name = "anyhow" 16 | version = "1.0.56" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.1.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 25 | 26 | [[package]] 27 | name = "bigint" 28 | version = "4.4.3" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "c0e8c8a600052b52482eff2cf4d810e462fdff1f656ac1ecb6232132a1ed7def" 31 | dependencies = [ 32 | "byteorder", 33 | "crunchy", 34 | ] 35 | 36 | [[package]] 37 | name = "bincode" 38 | version = "1.3.3" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 41 | dependencies = [ 42 | "serde", 43 | ] 44 | 45 | [[package]] 46 | name = "bitflags" 47 | version = "1.3.2" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 50 | 51 | [[package]] 52 | name = "blockchain_rust_part_4" 53 | version = "0.1.0" 54 | dependencies = [ 55 | "anyhow", 56 | "bigint", 57 | "bincode", 58 | "chrono", 59 | "rust-crypto", 60 | "serde", 61 | "sled", 62 | "thiserror", 63 | "tracing", 64 | "tracing-subscriber", 65 | ] 66 | 67 | [[package]] 68 | name = "byteorder" 69 | version = "1.4.3" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 72 | 73 | [[package]] 74 | name = "cfg-if" 75 | version = "1.0.0" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 78 | 79 | [[package]] 80 | name = "chrono" 81 | version = "0.4.19" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" 84 | dependencies = [ 85 | "libc", 86 | "num-integer", 87 | "num-traits", 88 | "time", 89 | "winapi", 90 | ] 91 | 92 | [[package]] 93 | name = "crc32fast" 94 | version = "1.3.2" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 97 | dependencies = [ 98 | "cfg-if", 99 | ] 100 | 101 | [[package]] 102 | name = "crossbeam-epoch" 103 | version = "0.9.8" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" 106 | dependencies = [ 107 | "autocfg", 108 | "cfg-if", 109 | "crossbeam-utils", 110 | "lazy_static", 111 | "memoffset", 112 | "scopeguard", 113 | ] 114 | 115 | [[package]] 116 | name = "crossbeam-utils" 117 | version = "0.8.8" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" 120 | dependencies = [ 121 | "cfg-if", 122 | "lazy_static", 123 | ] 124 | 125 | [[package]] 126 | name = "crunchy" 127 | version = "0.1.6" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" 130 | 131 | [[package]] 132 | name = "fs2" 133 | version = "0.4.3" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" 136 | dependencies = [ 137 | "libc", 138 | "winapi", 139 | ] 140 | 141 | [[package]] 142 | name = "fuchsia-cprng" 143 | version = "0.1.1" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 146 | 147 | [[package]] 148 | name = "fxhash" 149 | version = "0.2.1" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 152 | dependencies = [ 153 | "byteorder", 154 | ] 155 | 156 | [[package]] 157 | name = "gcc" 158 | version = "0.3.55" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" 161 | 162 | [[package]] 163 | name = "instant" 164 | version = "0.1.12" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 167 | dependencies = [ 168 | "cfg-if", 169 | ] 170 | 171 | [[package]] 172 | name = "itoa" 173 | version = "1.0.1" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 176 | 177 | [[package]] 178 | name = "lazy_static" 179 | version = "1.4.0" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 182 | 183 | [[package]] 184 | name = "libc" 185 | version = "0.2.122" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" 188 | 189 | [[package]] 190 | name = "lock_api" 191 | version = "0.4.7" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" 194 | dependencies = [ 195 | "autocfg", 196 | "scopeguard", 197 | ] 198 | 199 | [[package]] 200 | name = "log" 201 | version = "0.4.16" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" 204 | dependencies = [ 205 | "cfg-if", 206 | ] 207 | 208 | [[package]] 209 | name = "matchers" 210 | version = "0.0.1" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" 213 | dependencies = [ 214 | "regex-automata", 215 | ] 216 | 217 | [[package]] 218 | name = "memoffset" 219 | version = "0.6.5" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 222 | dependencies = [ 223 | "autocfg", 224 | ] 225 | 226 | [[package]] 227 | name = "num-integer" 228 | version = "0.1.44" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 231 | dependencies = [ 232 | "autocfg", 233 | "num-traits", 234 | ] 235 | 236 | [[package]] 237 | name = "num-traits" 238 | version = "0.2.14" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 241 | dependencies = [ 242 | "autocfg", 243 | ] 244 | 245 | [[package]] 246 | name = "once_cell" 247 | version = "1.10.0" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 250 | 251 | [[package]] 252 | name = "parking_lot" 253 | version = "0.11.2" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 256 | dependencies = [ 257 | "instant", 258 | "lock_api", 259 | "parking_lot_core", 260 | ] 261 | 262 | [[package]] 263 | name = "parking_lot_core" 264 | version = "0.8.5" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" 267 | dependencies = [ 268 | "cfg-if", 269 | "instant", 270 | "libc", 271 | "redox_syscall", 272 | "smallvec", 273 | "winapi", 274 | ] 275 | 276 | [[package]] 277 | name = "pin-project-lite" 278 | version = "0.2.8" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" 281 | 282 | [[package]] 283 | name = "proc-macro2" 284 | version = "1.0.37" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" 287 | dependencies = [ 288 | "unicode-xid", 289 | ] 290 | 291 | [[package]] 292 | name = "quote" 293 | version = "1.0.17" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" 296 | dependencies = [ 297 | "proc-macro2", 298 | ] 299 | 300 | [[package]] 301 | name = "rand" 302 | version = "0.3.23" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" 305 | dependencies = [ 306 | "libc", 307 | "rand 0.4.6", 308 | ] 309 | 310 | [[package]] 311 | name = "rand" 312 | version = "0.4.6" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 315 | dependencies = [ 316 | "fuchsia-cprng", 317 | "libc", 318 | "rand_core 0.3.1", 319 | "rdrand", 320 | "winapi", 321 | ] 322 | 323 | [[package]] 324 | name = "rand_core" 325 | version = "0.3.1" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 328 | dependencies = [ 329 | "rand_core 0.4.2", 330 | ] 331 | 332 | [[package]] 333 | name = "rand_core" 334 | version = "0.4.2" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 337 | 338 | [[package]] 339 | name = "rdrand" 340 | version = "0.4.0" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 343 | dependencies = [ 344 | "rand_core 0.3.1", 345 | ] 346 | 347 | [[package]] 348 | name = "redox_syscall" 349 | version = "0.2.13" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" 352 | dependencies = [ 353 | "bitflags", 354 | ] 355 | 356 | [[package]] 357 | name = "regex" 358 | version = "1.5.5" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 361 | dependencies = [ 362 | "regex-syntax", 363 | ] 364 | 365 | [[package]] 366 | name = "regex-automata" 367 | version = "0.1.10" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 370 | dependencies = [ 371 | "regex-syntax", 372 | ] 373 | 374 | [[package]] 375 | name = "regex-syntax" 376 | version = "0.6.25" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 379 | 380 | [[package]] 381 | name = "rust-crypto" 382 | version = "0.2.36" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" 385 | dependencies = [ 386 | "gcc", 387 | "libc", 388 | "rand 0.3.23", 389 | "rustc-serialize", 390 | "time", 391 | ] 392 | 393 | [[package]] 394 | name = "rustc-serialize" 395 | version = "0.3.24" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" 398 | 399 | [[package]] 400 | name = "ryu" 401 | version = "1.0.9" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 404 | 405 | [[package]] 406 | name = "scopeguard" 407 | version = "1.1.0" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 410 | 411 | [[package]] 412 | name = "serde" 413 | version = "1.0.136" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 416 | dependencies = [ 417 | "serde_derive", 418 | ] 419 | 420 | [[package]] 421 | name = "serde_derive" 422 | version = "1.0.136" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" 425 | dependencies = [ 426 | "proc-macro2", 427 | "quote", 428 | "syn", 429 | ] 430 | 431 | [[package]] 432 | name = "serde_json" 433 | version = "1.0.79" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" 436 | dependencies = [ 437 | "itoa", 438 | "ryu", 439 | "serde", 440 | ] 441 | 442 | [[package]] 443 | name = "sharded-slab" 444 | version = "0.1.4" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 447 | dependencies = [ 448 | "lazy_static", 449 | ] 450 | 451 | [[package]] 452 | name = "sled" 453 | version = "0.34.7" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" 456 | dependencies = [ 457 | "crc32fast", 458 | "crossbeam-epoch", 459 | "crossbeam-utils", 460 | "fs2", 461 | "fxhash", 462 | "libc", 463 | "log", 464 | "parking_lot", 465 | ] 466 | 467 | [[package]] 468 | name = "smallvec" 469 | version = "1.8.0" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 472 | 473 | [[package]] 474 | name = "syn" 475 | version = "1.0.91" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" 478 | dependencies = [ 479 | "proc-macro2", 480 | "quote", 481 | "unicode-xid", 482 | ] 483 | 484 | [[package]] 485 | name = "thiserror" 486 | version = "1.0.30" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 489 | dependencies = [ 490 | "thiserror-impl", 491 | ] 492 | 493 | [[package]] 494 | name = "thiserror-impl" 495 | version = "1.0.30" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 498 | dependencies = [ 499 | "proc-macro2", 500 | "quote", 501 | "syn", 502 | ] 503 | 504 | [[package]] 505 | name = "thread_local" 506 | version = "1.1.4" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" 509 | dependencies = [ 510 | "once_cell", 511 | ] 512 | 513 | [[package]] 514 | name = "time" 515 | version = "0.1.44" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" 518 | dependencies = [ 519 | "libc", 520 | "wasi", 521 | "winapi", 522 | ] 523 | 524 | [[package]] 525 | name = "tracing" 526 | version = "0.1.33" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "80b9fa4360528139bc96100c160b7ae879f5567f49f1782b0b02035b0358ebf3" 529 | dependencies = [ 530 | "cfg-if", 531 | "pin-project-lite", 532 | "tracing-attributes", 533 | "tracing-core", 534 | ] 535 | 536 | [[package]] 537 | name = "tracing-attributes" 538 | version = "0.1.20" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" 541 | dependencies = [ 542 | "proc-macro2", 543 | "quote", 544 | "syn", 545 | ] 546 | 547 | [[package]] 548 | name = "tracing-core" 549 | version = "0.1.24" 550 | source = "registry+https://github.com/rust-lang/crates.io-index" 551 | checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee" 552 | dependencies = [ 553 | "lazy_static", 554 | "valuable", 555 | ] 556 | 557 | [[package]] 558 | name = "tracing-log" 559 | version = "0.1.2" 560 | source = "registry+https://github.com/rust-lang/crates.io-index" 561 | checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" 562 | dependencies = [ 563 | "lazy_static", 564 | "log", 565 | "tracing-core", 566 | ] 567 | 568 | [[package]] 569 | name = "tracing-serde" 570 | version = "0.1.3" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" 573 | dependencies = [ 574 | "serde", 575 | "tracing-core", 576 | ] 577 | 578 | [[package]] 579 | name = "tracing-subscriber" 580 | version = "0.2.25" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" 583 | dependencies = [ 584 | "ansi_term", 585 | "chrono", 586 | "lazy_static", 587 | "matchers", 588 | "regex", 589 | "serde", 590 | "serde_json", 591 | "sharded-slab", 592 | "smallvec", 593 | "thread_local", 594 | "tracing", 595 | "tracing-core", 596 | "tracing-log", 597 | "tracing-serde", 598 | ] 599 | 600 | [[package]] 601 | name = "unicode-xid" 602 | version = "0.2.2" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 605 | 606 | [[package]] 607 | name = "valuable" 608 | version = "0.1.0" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 611 | 612 | [[package]] 613 | name = "wasi" 614 | version = "0.10.0+wasi-snapshot-preview1" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 617 | 618 | [[package]] 619 | name = "winapi" 620 | version = "0.3.9" 621 | source = "registry+https://github.com/rust-lang/crates.io-index" 622 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 623 | dependencies = [ 624 | "winapi-i686-pc-windows-gnu", 625 | "winapi-x86_64-pc-windows-gnu", 626 | ] 627 | 628 | [[package]] 629 | name = "winapi-i686-pc-windows-gnu" 630 | version = "0.4.0" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 633 | 634 | [[package]] 635 | name = "winapi-x86_64-pc-windows-gnu" 636 | version = "0.4.0" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 639 | -------------------------------------------------------------------------------- /blockchain_rust_part_5/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ansi_term" 7 | version = "0.12.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 10 | dependencies = [ 11 | "winapi", 12 | ] 13 | 14 | [[package]] 15 | name = "anyhow" 16 | version = "1.0.56" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.1.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 25 | 26 | [[package]] 27 | name = "bigint" 28 | version = "4.4.3" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "c0e8c8a600052b52482eff2cf4d810e462fdff1f656ac1ecb6232132a1ed7def" 31 | dependencies = [ 32 | "byteorder", 33 | "crunchy", 34 | ] 35 | 36 | [[package]] 37 | name = "bincode" 38 | version = "1.3.3" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 41 | dependencies = [ 42 | "serde", 43 | ] 44 | 45 | [[package]] 46 | name = "bitflags" 47 | version = "1.3.2" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 50 | 51 | [[package]] 52 | name = "blockchain_rust_part_5" 53 | version = "0.1.0" 54 | dependencies = [ 55 | "anyhow", 56 | "bigint", 57 | "bincode", 58 | "bs58", 59 | "chrono", 60 | "ring", 61 | "rust-crypto", 62 | "rustc-serialize", 63 | "serde", 64 | "sled", 65 | "thiserror", 66 | "tracing", 67 | "tracing-subscriber", 68 | ] 69 | 70 | [[package]] 71 | name = "bs58" 72 | version = "0.4.0" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" 75 | 76 | [[package]] 77 | name = "bumpalo" 78 | version = "3.9.1" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" 81 | 82 | [[package]] 83 | name = "byteorder" 84 | version = "1.4.3" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 87 | 88 | [[package]] 89 | name = "cc" 90 | version = "1.0.73" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 93 | 94 | [[package]] 95 | name = "cfg-if" 96 | version = "1.0.0" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 99 | 100 | [[package]] 101 | name = "chrono" 102 | version = "0.4.19" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" 105 | dependencies = [ 106 | "libc", 107 | "num-integer", 108 | "num-traits", 109 | "time", 110 | "winapi", 111 | ] 112 | 113 | [[package]] 114 | name = "crc32fast" 115 | version = "1.3.2" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 118 | dependencies = [ 119 | "cfg-if", 120 | ] 121 | 122 | [[package]] 123 | name = "crossbeam-epoch" 124 | version = "0.9.8" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" 127 | dependencies = [ 128 | "autocfg", 129 | "cfg-if", 130 | "crossbeam-utils", 131 | "lazy_static", 132 | "memoffset", 133 | "scopeguard", 134 | ] 135 | 136 | [[package]] 137 | name = "crossbeam-utils" 138 | version = "0.8.8" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" 141 | dependencies = [ 142 | "cfg-if", 143 | "lazy_static", 144 | ] 145 | 146 | [[package]] 147 | name = "crunchy" 148 | version = "0.1.6" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" 151 | 152 | [[package]] 153 | name = "fs2" 154 | version = "0.4.3" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" 157 | dependencies = [ 158 | "libc", 159 | "winapi", 160 | ] 161 | 162 | [[package]] 163 | name = "fuchsia-cprng" 164 | version = "0.1.1" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 167 | 168 | [[package]] 169 | name = "fxhash" 170 | version = "0.2.1" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 173 | dependencies = [ 174 | "byteorder", 175 | ] 176 | 177 | [[package]] 178 | name = "gcc" 179 | version = "0.3.55" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" 182 | 183 | [[package]] 184 | name = "instant" 185 | version = "0.1.12" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 188 | dependencies = [ 189 | "cfg-if", 190 | ] 191 | 192 | [[package]] 193 | name = "itoa" 194 | version = "1.0.1" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 197 | 198 | [[package]] 199 | name = "js-sys" 200 | version = "0.3.57" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" 203 | dependencies = [ 204 | "wasm-bindgen", 205 | ] 206 | 207 | [[package]] 208 | name = "lazy_static" 209 | version = "1.4.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 212 | 213 | [[package]] 214 | name = "libc" 215 | version = "0.2.122" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" 218 | 219 | [[package]] 220 | name = "lock_api" 221 | version = "0.4.7" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" 224 | dependencies = [ 225 | "autocfg", 226 | "scopeguard", 227 | ] 228 | 229 | [[package]] 230 | name = "log" 231 | version = "0.4.16" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" 234 | dependencies = [ 235 | "cfg-if", 236 | ] 237 | 238 | [[package]] 239 | name = "matchers" 240 | version = "0.0.1" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" 243 | dependencies = [ 244 | "regex-automata", 245 | ] 246 | 247 | [[package]] 248 | name = "memoffset" 249 | version = "0.6.5" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 252 | dependencies = [ 253 | "autocfg", 254 | ] 255 | 256 | [[package]] 257 | name = "num-integer" 258 | version = "0.1.44" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 261 | dependencies = [ 262 | "autocfg", 263 | "num-traits", 264 | ] 265 | 266 | [[package]] 267 | name = "num-traits" 268 | version = "0.2.14" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 271 | dependencies = [ 272 | "autocfg", 273 | ] 274 | 275 | [[package]] 276 | name = "once_cell" 277 | version = "1.10.0" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 280 | 281 | [[package]] 282 | name = "parking_lot" 283 | version = "0.11.2" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 286 | dependencies = [ 287 | "instant", 288 | "lock_api", 289 | "parking_lot_core", 290 | ] 291 | 292 | [[package]] 293 | name = "parking_lot_core" 294 | version = "0.8.5" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" 297 | dependencies = [ 298 | "cfg-if", 299 | "instant", 300 | "libc", 301 | "redox_syscall", 302 | "smallvec", 303 | "winapi", 304 | ] 305 | 306 | [[package]] 307 | name = "pin-project-lite" 308 | version = "0.2.8" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" 311 | 312 | [[package]] 313 | name = "proc-macro2" 314 | version = "1.0.37" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" 317 | dependencies = [ 318 | "unicode-xid", 319 | ] 320 | 321 | [[package]] 322 | name = "quote" 323 | version = "1.0.18" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" 326 | dependencies = [ 327 | "proc-macro2", 328 | ] 329 | 330 | [[package]] 331 | name = "rand" 332 | version = "0.3.23" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" 335 | dependencies = [ 336 | "libc", 337 | "rand 0.4.6", 338 | ] 339 | 340 | [[package]] 341 | name = "rand" 342 | version = "0.4.6" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 345 | dependencies = [ 346 | "fuchsia-cprng", 347 | "libc", 348 | "rand_core 0.3.1", 349 | "rdrand", 350 | "winapi", 351 | ] 352 | 353 | [[package]] 354 | name = "rand_core" 355 | version = "0.3.1" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 358 | dependencies = [ 359 | "rand_core 0.4.2", 360 | ] 361 | 362 | [[package]] 363 | name = "rand_core" 364 | version = "0.4.2" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 367 | 368 | [[package]] 369 | name = "rdrand" 370 | version = "0.4.0" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 373 | dependencies = [ 374 | "rand_core 0.3.1", 375 | ] 376 | 377 | [[package]] 378 | name = "redox_syscall" 379 | version = "0.2.13" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" 382 | dependencies = [ 383 | "bitflags", 384 | ] 385 | 386 | [[package]] 387 | name = "regex" 388 | version = "1.5.5" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 391 | dependencies = [ 392 | "regex-syntax", 393 | ] 394 | 395 | [[package]] 396 | name = "regex-automata" 397 | version = "0.1.10" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 400 | dependencies = [ 401 | "regex-syntax", 402 | ] 403 | 404 | [[package]] 405 | name = "regex-syntax" 406 | version = "0.6.25" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 409 | 410 | [[package]] 411 | name = "ring" 412 | version = "0.16.20" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 415 | dependencies = [ 416 | "cc", 417 | "libc", 418 | "once_cell", 419 | "spin", 420 | "untrusted", 421 | "web-sys", 422 | "winapi", 423 | ] 424 | 425 | [[package]] 426 | name = "rust-crypto" 427 | version = "0.2.36" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" 430 | dependencies = [ 431 | "gcc", 432 | "libc", 433 | "rand 0.3.23", 434 | "rustc-serialize", 435 | "time", 436 | ] 437 | 438 | [[package]] 439 | name = "rustc-serialize" 440 | version = "0.3.24" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" 443 | 444 | [[package]] 445 | name = "ryu" 446 | version = "1.0.9" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 449 | 450 | [[package]] 451 | name = "scopeguard" 452 | version = "1.1.0" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 455 | 456 | [[package]] 457 | name = "serde" 458 | version = "1.0.136" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 461 | dependencies = [ 462 | "serde_derive", 463 | ] 464 | 465 | [[package]] 466 | name = "serde_derive" 467 | version = "1.0.136" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" 470 | dependencies = [ 471 | "proc-macro2", 472 | "quote", 473 | "syn", 474 | ] 475 | 476 | [[package]] 477 | name = "serde_json" 478 | version = "1.0.79" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" 481 | dependencies = [ 482 | "itoa", 483 | "ryu", 484 | "serde", 485 | ] 486 | 487 | [[package]] 488 | name = "sharded-slab" 489 | version = "0.1.4" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 492 | dependencies = [ 493 | "lazy_static", 494 | ] 495 | 496 | [[package]] 497 | name = "sled" 498 | version = "0.34.7" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" 501 | dependencies = [ 502 | "crc32fast", 503 | "crossbeam-epoch", 504 | "crossbeam-utils", 505 | "fs2", 506 | "fxhash", 507 | "libc", 508 | "log", 509 | "parking_lot", 510 | ] 511 | 512 | [[package]] 513 | name = "smallvec" 514 | version = "1.8.0" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 517 | 518 | [[package]] 519 | name = "spin" 520 | version = "0.5.2" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 523 | 524 | [[package]] 525 | name = "syn" 526 | version = "1.0.91" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" 529 | dependencies = [ 530 | "proc-macro2", 531 | "quote", 532 | "unicode-xid", 533 | ] 534 | 535 | [[package]] 536 | name = "thiserror" 537 | version = "1.0.30" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 540 | dependencies = [ 541 | "thiserror-impl", 542 | ] 543 | 544 | [[package]] 545 | name = "thiserror-impl" 546 | version = "1.0.30" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 549 | dependencies = [ 550 | "proc-macro2", 551 | "quote", 552 | "syn", 553 | ] 554 | 555 | [[package]] 556 | name = "thread_local" 557 | version = "1.1.4" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" 560 | dependencies = [ 561 | "once_cell", 562 | ] 563 | 564 | [[package]] 565 | name = "time" 566 | version = "0.1.44" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" 569 | dependencies = [ 570 | "libc", 571 | "wasi", 572 | "winapi", 573 | ] 574 | 575 | [[package]] 576 | name = "tracing" 577 | version = "0.1.33" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "80b9fa4360528139bc96100c160b7ae879f5567f49f1782b0b02035b0358ebf3" 580 | dependencies = [ 581 | "cfg-if", 582 | "pin-project-lite", 583 | "tracing-attributes", 584 | "tracing-core", 585 | ] 586 | 587 | [[package]] 588 | name = "tracing-attributes" 589 | version = "0.1.20" 590 | source = "registry+https://github.com/rust-lang/crates.io-index" 591 | checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" 592 | dependencies = [ 593 | "proc-macro2", 594 | "quote", 595 | "syn", 596 | ] 597 | 598 | [[package]] 599 | name = "tracing-core" 600 | version = "0.1.24" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee" 603 | dependencies = [ 604 | "lazy_static", 605 | "valuable", 606 | ] 607 | 608 | [[package]] 609 | name = "tracing-log" 610 | version = "0.1.2" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" 613 | dependencies = [ 614 | "lazy_static", 615 | "log", 616 | "tracing-core", 617 | ] 618 | 619 | [[package]] 620 | name = "tracing-serde" 621 | version = "0.1.3" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" 624 | dependencies = [ 625 | "serde", 626 | "tracing-core", 627 | ] 628 | 629 | [[package]] 630 | name = "tracing-subscriber" 631 | version = "0.2.25" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" 634 | dependencies = [ 635 | "ansi_term", 636 | "chrono", 637 | "lazy_static", 638 | "matchers", 639 | "regex", 640 | "serde", 641 | "serde_json", 642 | "sharded-slab", 643 | "smallvec", 644 | "thread_local", 645 | "tracing", 646 | "tracing-core", 647 | "tracing-log", 648 | "tracing-serde", 649 | ] 650 | 651 | [[package]] 652 | name = "unicode-xid" 653 | version = "0.2.2" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 656 | 657 | [[package]] 658 | name = "untrusted" 659 | version = "0.7.1" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 662 | 663 | [[package]] 664 | name = "valuable" 665 | version = "0.1.0" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 668 | 669 | [[package]] 670 | name = "wasi" 671 | version = "0.10.0+wasi-snapshot-preview1" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 674 | 675 | [[package]] 676 | name = "wasm-bindgen" 677 | version = "0.2.80" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" 680 | dependencies = [ 681 | "cfg-if", 682 | "wasm-bindgen-macro", 683 | ] 684 | 685 | [[package]] 686 | name = "wasm-bindgen-backend" 687 | version = "0.2.80" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" 690 | dependencies = [ 691 | "bumpalo", 692 | "lazy_static", 693 | "log", 694 | "proc-macro2", 695 | "quote", 696 | "syn", 697 | "wasm-bindgen-shared", 698 | ] 699 | 700 | [[package]] 701 | name = "wasm-bindgen-macro" 702 | version = "0.2.80" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" 705 | dependencies = [ 706 | "quote", 707 | "wasm-bindgen-macro-support", 708 | ] 709 | 710 | [[package]] 711 | name = "wasm-bindgen-macro-support" 712 | version = "0.2.80" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" 715 | dependencies = [ 716 | "proc-macro2", 717 | "quote", 718 | "syn", 719 | "wasm-bindgen-backend", 720 | "wasm-bindgen-shared", 721 | ] 722 | 723 | [[package]] 724 | name = "wasm-bindgen-shared" 725 | version = "0.2.80" 726 | source = "registry+https://github.com/rust-lang/crates.io-index" 727 | checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" 728 | 729 | [[package]] 730 | name = "web-sys" 731 | version = "0.3.57" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" 734 | dependencies = [ 735 | "js-sys", 736 | "wasm-bindgen", 737 | ] 738 | 739 | [[package]] 740 | name = "winapi" 741 | version = "0.3.9" 742 | source = "registry+https://github.com/rust-lang/crates.io-index" 743 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 744 | dependencies = [ 745 | "winapi-i686-pc-windows-gnu", 746 | "winapi-x86_64-pc-windows-gnu", 747 | ] 748 | 749 | [[package]] 750 | name = "winapi-i686-pc-windows-gnu" 751 | version = "0.4.0" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 754 | 755 | [[package]] 756 | name = "winapi-x86_64-pc-windows-gnu" 757 | version = "0.4.0" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 760 | --------------------------------------------------------------------------------