Hash Functions in Blockchain

Understanding cryptographic hash functions and their role in blockchain security.

Intermediate⏱️ 40 min📚 Prerequisites: 1

Hash Functions in Blockchain

Hash functions are fundamental to blockchain security. They create a unique fingerprint of data that cannot be reversed.

Properties of Hash Functions

  1. Deterministic: Same input always produces same output
  2. Fast to compute: Quick to calculate
  3. One-way: Cannot reverse to get original input
  4. Avalanche effect: Small input change = completely different output
  5. Collision resistant: Hard to find two inputs with same hash

Common Hash Functions

  • SHA-256: Used by Bitcoin
  • Blake2: Fast and secure
  • Keccak-256: Used by Ethereum (SHA-3 variant)

Using Hashes in Rust

Rust has excellent cryptographic libraries:

RUST
use sha2::{Sha256, Digest};

fn hash_data(data: &str) -> String {
    let mut hasher = Sha256::new();
    hasher.update(data.as_bytes());
    format!("{:x}", hasher.finalize())
}

Hash Uses in Blockchain

  1. Block Hashing: Each block's hash includes all its data
  2. Transaction IDs: Each transaction gets a unique hash
  3. Merkle Trees: Efficiently hash multiple transactions
  4. Proof of Work: Mining requires finding specific hashes
  5. Chain Integrity: Previous hash links blocks together

Block Hash Example

RUST
struct Block {
    index: u64,
    data: String,
    previous_hash: String,
    hash: String,  // Hash of (index + data + previous_hash)
}

The block hash ensures that if any data changes, the hash changes, breaking the chain.

Code Examples

Simple Hash Function

A simplified hash demonstration (not cryptographically secure)

RUST
fn simple_hash(input: &str) -> u64 {
    let mut hash: u64 = 0;
    for byte in input.bytes() {
        hash = hash.wrapping_mul(31).wrapping_add(byte as u64);
    }
    hash
}
fn main() {
    let data1 = "Hello, Blockchain!";
    let data2 = "Hello, Blockchain?";
    println!("Hash of '{}': {}", data1, simple_hash(data1));
    println!("Hash of '{}': {}", data2, simple_hash(data2));
}

Explanation:

This demonstrates the avalanche effect - even a tiny change in input produces a completely different hash. Real blockchains use SHA-256 or similar secure hash functions.

Block Hashing

Creating a hash for a block

RUST
fn hash_block(index: u64, data: &str, previous_hash: &str) -> String {
    let combined = format!("{}{}{}", index, data, previous_hash);
    format!("hash_of_{}", combined)
}
struct Block {
    index: u64,
    data: String,
    previous_hash: String,
    hash: String,
}
impl Block {
    fn new(index: u64, data: String, previous_hash: String) -> Self {
        let hash = hash_block(index, &data, &previous_hash);
        Block {
            index,
            data,
            previous_hash,
            hash,
        }
    }
}
fn main() {
    let block = Block::new(
        1,
        String::from("Transaction data"),
        String::from("prev_hash"),
    );
    println!("Block hash: {}", block.hash);
}

Explanation:

Each block's hash is calculated from all its data. If any part changes, the hash changes, making tampering detectable.

Exercises

Calculate Block Hash

Create a function that calculates a block's hash from its components!

Medium

Starter Code:

RUST
struct Block {
    index: u64,
    data: String,
    previous_hash: String,
}
fn main() {
    let block = Block {
        index: 1,
        data: String::from("My transaction"),
        previous_hash: String::from("abc123"),
    };
}