Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
792 changes: 498 additions & 294 deletions Cargo.lock

Large diffs are not rendered by default.

28 changes: 15 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "blockchain-demo"
version = "0.1.0"
authors = ["yunwei37 <1067852565@qq.com>"]
description = "A simplified blockchain implementation in rust for leaning"
edition = "2018"
edition = "2021"
readme = "README.md"
homepage = "https://github.com/yunwei37/blockchain-rust"
repository = "https://github.com/yunwei37/blockchain-rust"
Expand All @@ -13,16 +13,18 @@ keywords = ["blockchain", "demo"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

sha2 = "0.9"
rust-crypto = "^0.2"
bincode = "1.3"
failure = "0.1"
sled = "0.34"
serde = {version ="1.0", features =["derive"]}
log = "0.4"
env_logger = "0.7.1"
clap = "~2.33"
anyhow = "1.0.82"
bincode = "2.0.0-rc.3"
bitcoincash-addr = "0.5.2"
rand = "0.4.6"
merkle-cbt = "0.2.2"
clap = { version = "4.5.4", features = ["derive"] }
ed25519-dalek = "2.1.1"
env_logger = "0.11.3"
hex = "0.4.3"
log = "0.4.21"
merkle-cbt = "0.3.1"
rand = "0.8.5"
ripemd = "0.1.3"
serde = { version = "1.0.197", features = ["derive"] }
sha2 = "0.10.8"
sled = "0.34.7"
thiserror = "1.0.59"
25 changes: 11 additions & 14 deletions src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@

use super::*;
use crate::transaction::Transaction;
use bincode::serialize;
use crypto::digest::Digest;
use crypto::sha2::Sha256;
use bincode::{self, config};
use merkle_cbt::merkle_tree::Merge;
use merkle_cbt::merkle_tree::CBMT;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use std::time::SystemTime;

const TARGET_HEXS: usize = 4;

/// Block keeps block headers
#[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone, bincode::Encode, bincode::Decode)]
pub struct Block {
timestamp: u128,
transactions: Vec<Transaction>,
Expand Down Expand Up @@ -74,8 +73,8 @@ impl Block {
}
let data = self.prepare_hash_data()?;
let mut hasher = Sha256::new();
hasher.input(&data[..]);
self.hash = hasher.result_str();
hasher.update(&data[..]);
self.hash = hex::encode(hasher.finalize());
Ok(())
}

Expand All @@ -85,7 +84,7 @@ impl Block {
for tx in &self.transactions {
transactions.push(tx.hash()?.as_bytes().to_owned());
}
let tree = CBMT::<Vec<u8>, MergeVu8>::build_merkle_tree(transactions);
let tree = CBMT::<Vec<u8>, MergeVu8>::build_merkle_tree(&transactions);

Ok(tree.root())
}
Expand All @@ -98,18 +97,18 @@ impl Block {
TARGET_HEXS,
self.nonce,
);
let bytes = serialize(&content)?;
let bytes = bincode::encode_to_vec(&content, config::standard())?;
Ok(bytes)
}

/// Validate validates block's PoW
fn validate(&self) -> Result<bool> {
let data = self.prepare_hash_data()?;
let mut hasher = Sha256::new();
hasher.input(&data[..]);
hasher.update(&data[..]);
let mut vec1: Vec<u8> = Vec::new();
vec1.resize(TARGET_HEXS, '0' as u8);
Ok(&hasher.result_str()[0..TARGET_HEXS] == String::from_utf8(vec1)?)
Ok(&hex::encode(hasher.finalize())[0..TARGET_HEXS] == String::from_utf8(vec1)?)
}
}

Expand All @@ -121,9 +120,7 @@ impl Merge for MergeVu8 {
let mut hasher = Sha256::new();
let mut data: Vec<u8> = left.clone();
data.append(&mut right.clone());
hasher.input(&data);
let mut re: [u8; 32] = [0; 32];
hasher.result(&mut re);
re.to_vec()
hasher.update(&data);
hasher.finalize().to_vec()
}
}
26 changes: 16 additions & 10 deletions src/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
use super::*;
use crate::block::*;
use crate::transaction::*;
use bincode::{deserialize, serialize};
use failure::format_err;
use bincode::config;
use sled;
use std::collections::HashMap;

Expand Down Expand Up @@ -52,7 +51,10 @@ impl Blockchain {
debug!("Creating new block database");
let cbtx = Transaction::new_coinbase(address, String::from(GENESIS_COINBASE_DATA))?;
let genesis: Block = Block::new_genesis_block(cbtx);
db.insert(genesis.get_hash(), serialize(&genesis)?)?;
db.insert(
genesis.get_hash(),
bincode::encode_to_vec(&genesis, config::standard())?,
)?;
db.insert("LAST", genesis.get_hash().as_bytes())?;
let bc = Blockchain {
tip: genesis.get_hash(),
Expand All @@ -68,7 +70,7 @@ impl Blockchain {

for tx in &transactions {
if !self.verify_transacton(tx)? {
return Err(format_err!("ERROR: Invalid transaction"));
return Err(anyhow::anyhow!("ERROR: Invalid transaction"));
}
}

Expand All @@ -79,7 +81,10 @@ impl Blockchain {
String::from_utf8(lasthash.to_vec())?,
self.get_best_height()? + 1,
)?;
self.db.insert(newblock.get_hash(), serialize(&newblock)?)?;
self.db.insert(
newblock.get_hash(),
bincode::encode_to_vec(&newblock, config::standard())?,
)?;
self.db.insert("LAST", newblock.get_hash().as_bytes())?;
self.db.flush()?;

Expand Down Expand Up @@ -151,7 +156,7 @@ impl Blockchain {
}
}
}
Err(format_err!("Transaction is not found"))
Err(anyhow::anyhow!("Transaction is not found"))
}

fn get_prev_TXs(&self, tx: &Transaction) -> Result<HashMap<String, Transaction>> {
Expand Down Expand Up @@ -181,7 +186,7 @@ impl Blockchain {

/// AddBlock saves the block into the blockchain
pub fn add_block(&mut self, block: Block) -> Result<()> {
let data = serialize(&block)?;
let data = bincode::encode_to_vec(&block, config::standard())?;
if let Some(_) = self.db.get(block.get_hash())? {
return Ok(());
}
Expand All @@ -199,7 +204,7 @@ impl Blockchain {
// GetBlock finds a block by its hash and returns it
pub fn get_block(&self, block_hash: &str) -> Result<Block> {
let data = self.db.get(block_hash)?.unwrap();
let block = deserialize(&data.to_vec())?;
let (block, _) = bincode::decode_from_slice(&data, config::standard())?;
Ok(block)
}

Expand All @@ -211,7 +216,8 @@ impl Blockchain {
return Ok(-1);
};
let last_data = self.db.get(lasthash)?.unwrap();
let last_block: Block = deserialize(&last_data.to_vec())?;
let (last_block, _): (Block, _) =
bincode::decode_from_slice(&last_data, config::standard())?;
Ok(last_block.get_height())
}

Expand All @@ -232,7 +238,7 @@ impl<'a> Iterator for BlockchainIterator<'a> {
if let Ok(encoded_block) = self.bc.db.get(&self.current_hash) {
return match encoded_block {
Some(b) => {
if let Ok(block) = deserialize::<Block>(&b) {
if let Ok((block, _)) = bincode::decode_from_slice::<Block, _>(&b, config::standard()) {
self.current_hash = block.get_prev_hash();
Some(block)
} else {
Expand Down
Loading