├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md └── src ├── main.rs └── models ├── block.rs ├── blockchain.rs └── mod.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 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 = "autocfg" 7 | version = "1.0.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 10 | 11 | [[package]] 12 | name = "block-buffer" 13 | version = "0.10.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" 16 | dependencies = [ 17 | "generic-array", 18 | ] 19 | 20 | [[package]] 21 | name = "cfg-if" 22 | version = "1.0.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 25 | 26 | [[package]] 27 | name = "chrono" 28 | version = "0.4.19" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" 31 | dependencies = [ 32 | "libc", 33 | "num-integer", 34 | "num-traits", 35 | "time", 36 | "winapi", 37 | ] 38 | 39 | [[package]] 40 | name = "cpufeatures" 41 | version = "0.2.1" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" 44 | dependencies = [ 45 | "libc", 46 | ] 47 | 48 | [[package]] 49 | name = "crypto-common" 50 | version = "0.1.1" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" 53 | dependencies = [ 54 | "generic-array", 55 | ] 56 | 57 | [[package]] 58 | name = "digest" 59 | version = "0.10.1" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" 62 | dependencies = [ 63 | "block-buffer", 64 | "crypto-common", 65 | "generic-array", 66 | ] 67 | 68 | [[package]] 69 | name = "generic-array" 70 | version = "0.14.4" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" 73 | dependencies = [ 74 | "typenum", 75 | "version_check", 76 | ] 77 | 78 | [[package]] 79 | name = "itoa" 80 | version = "1.0.1" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 83 | 84 | [[package]] 85 | name = "libc" 86 | version = "0.2.112" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" 89 | 90 | [[package]] 91 | name = "num-integer" 92 | version = "0.1.44" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 95 | dependencies = [ 96 | "autocfg", 97 | "num-traits", 98 | ] 99 | 100 | [[package]] 101 | name = "num-traits" 102 | version = "0.2.14" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 105 | dependencies = [ 106 | "autocfg", 107 | ] 108 | 109 | [[package]] 110 | name = "pow-blockchain" 111 | version = "0.1.0" 112 | dependencies = [ 113 | "chrono", 114 | "serde", 115 | "serde_json", 116 | "sha2", 117 | ] 118 | 119 | [[package]] 120 | name = "proc-macro2" 121 | version = "1.0.36" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" 124 | dependencies = [ 125 | "unicode-xid", 126 | ] 127 | 128 | [[package]] 129 | name = "quote" 130 | version = "1.0.14" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" 133 | dependencies = [ 134 | "proc-macro2", 135 | ] 136 | 137 | [[package]] 138 | name = "ryu" 139 | version = "1.0.9" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 142 | 143 | [[package]] 144 | name = "serde" 145 | version = "1.0.132" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" 148 | dependencies = [ 149 | "serde_derive", 150 | ] 151 | 152 | [[package]] 153 | name = "serde_derive" 154 | version = "1.0.132" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" 157 | dependencies = [ 158 | "proc-macro2", 159 | "quote", 160 | "syn", 161 | ] 162 | 163 | [[package]] 164 | name = "serde_json" 165 | version = "1.0.73" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" 168 | dependencies = [ 169 | "itoa", 170 | "ryu", 171 | "serde", 172 | ] 173 | 174 | [[package]] 175 | name = "sha2" 176 | version = "0.10.0" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "900d964dd36bb15bcf2f2b35694c072feab74969a54f2bbeec7a2d725d2bdcb6" 179 | dependencies = [ 180 | "cfg-if", 181 | "cpufeatures", 182 | "digest", 183 | ] 184 | 185 | [[package]] 186 | name = "syn" 187 | version = "1.0.84" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b" 190 | dependencies = [ 191 | "proc-macro2", 192 | "quote", 193 | "unicode-xid", 194 | ] 195 | 196 | [[package]] 197 | name = "time" 198 | version = "0.1.44" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" 201 | dependencies = [ 202 | "libc", 203 | "wasi", 204 | "winapi", 205 | ] 206 | 207 | [[package]] 208 | name = "typenum" 209 | version = "1.15.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 212 | 213 | [[package]] 214 | name = "unicode-xid" 215 | version = "0.2.2" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 218 | 219 | [[package]] 220 | name = "version_check" 221 | version = "0.9.4" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 224 | 225 | [[package]] 226 | name = "wasi" 227 | version = "0.10.0+wasi-snapshot-preview1" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 230 | 231 | [[package]] 232 | name = "winapi" 233 | version = "0.3.9" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 236 | dependencies = [ 237 | "winapi-i686-pc-windows-gnu", 238 | "winapi-x86_64-pc-windows-gnu", 239 | ] 240 | 241 | [[package]] 242 | name = "winapi-i686-pc-windows-gnu" 243 | version = "0.4.0" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 246 | 247 | [[package]] 248 | name = "winapi-x86_64-pc-windows-gnu" 249 | version = "0.4.0" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 252 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pow-blockchain" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | chrono = "0.4" 10 | serde = { version = "1.0.106", features = ["derive"] } 11 | serde_json = "1.0" 12 | sha2 = "0.10.0" 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust-blockchain 2 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod models; 2 | fn main() { 3 | let difficulty = 1; 4 | let mut blockchain = models::blockchain::Blockchain::new(difficulty); 5 | 6 | models::blockchain::Blockchain::add_block(&mut blockchain); 7 | } 8 | -------------------------------------------------------------------------------- /src/models/block.rs: -------------------------------------------------------------------------------- 1 | use super::blockchain::Blockchain; 2 | use chrono::prelude::*; 3 | use sha2::{Sha256, Digest}; 4 | use serde::{Deserialize, Serialize}; 5 | 6 | // `Block`, A struct that represents a block in a Blockchain. 7 | #[derive(Debug, Clone, Serialize, Deserialize)] 8 | pub struct Block { 9 | // The index in which the current block is stored. 10 | pub index: u64, 11 | // The time the current block is created. 12 | pub timestamp: u64, 13 | // The block's proof of work. 14 | pub proof_of_work: u64, 15 | // The previous block hash. 16 | pub previous_hash: String, 17 | // The current block hash. 18 | pub hash: String 19 | } 20 | 21 | impl Block { 22 | // Create a new block. The hash will be calculated and set automatically. 23 | pub fn new ( 24 | index: u64, 25 | previous_hash: String, 26 | ) -> Self { 27 | // Current block to be created. 28 | let block = Block { 29 | index, 30 | timestamp: Utc::now().timestamp_millis() as u64, 31 | proof_of_work: u64::default(), 32 | previous_hash, 33 | hash: String::default(), 34 | }; 35 | 36 | block 37 | } 38 | 39 | // Mine block hash. 40 | pub fn mine (&mut self, blockchain: Blockchain) { 41 | loop { 42 | if !self.hash.starts_with(&"0".repeat(blockchain.difficulty)) { 43 | self.proof_of_work += 1; 44 | self.hash = self.generate_block_hash(); 45 | } else { 46 | break 47 | } 48 | } 49 | } 50 | 51 | // Calculate block hash. 52 | pub fn generate_block_hash(&self) -> String { 53 | let mut block_data = self.clone(); 54 | block_data.hash = String::default(); 55 | // Convert block to JSON format. 56 | let serialized_block_data = serde_json::to_string(&block_data).unwrap(); 57 | 58 | // Calculate and return SHA-256 hash value. 59 | let mut hasher = Sha256::new(); 60 | hasher.update(serialized_block_data); 61 | 62 | let result = hasher.finalize(); 63 | 64 | format!("{:x}", result) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/models/blockchain.rs: -------------------------------------------------------------------------------- 1 | use super::block::Block; 2 | use chrono::prelude::*; 3 | 4 | type Blocks = Vec; 5 | 6 | // `Blockchain` A struct that represents the blockchain. 7 | #[derive(Debug, Clone)] 8 | pub struct Blockchain { 9 | // The first block to be added to the chain. 10 | pub genesis_block: Block, 11 | // The storage for blocks. 12 | pub chain: Blocks, 13 | // Minimum amount of work required to mine a block. 14 | pub difficulty: usize, 15 | } 16 | 17 | impl Blockchain { 18 | pub fn new(difficulty: usize) -> Self { 19 | // First block in the chain. 20 | let genesis_block = Block { 21 | index: 0, 22 | timestamp: Utc::now().timestamp_millis() as u64, 23 | proof_of_work: u64::default(), 24 | previous_hash: String::default(), 25 | hash: String::default(), 26 | }; 27 | 28 | // Create chain starting from the genesis chain. 29 | let mut chain = Vec::new(); 30 | chain.push(genesis_block.clone()); 31 | 32 | // Create a blockchain Instance. 33 | let blockchain = Blockchain { 34 | genesis_block, 35 | chain, 36 | difficulty, 37 | }; 38 | 39 | blockchain 40 | } 41 | 42 | pub fn add_block(&mut self) { 43 | let mut new_block = Block::new( 44 | self.chain.len() as u64, 45 | self.chain[&self.chain.len() - 1].hash.clone(), 46 | ); 47 | 48 | new_block.mine(self.clone()); 49 | self.chain.push(new_block.clone()); 50 | println!("New block added to chain -> {:?}", new_block); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod block; 2 | pub mod blockchain; --------------------------------------------------------------------------------