- Published on
Building a Simple Blockchain in Elixir
- Authors
- Name
- Ben Glasser
- @benglasser

Introduction
Blockchains are pretty interesting from a technical perspective, and while the production ones like Bitcoin are super complex, the core ideas are actually pretty simple. This is ExBlock - a basic blockchain I built in Elixir to understand how the fundamental pieces work. It's nothing fancy, just a clean implementation of the essential concepts in about 200 lines of code.
What ExBlock Does
This is a simple blockchain that covers the basics:
- Cryptographic Hashing: SHA256 to validate blocks
- Chain Integrity: Blocks link to each other through hashes
- Genesis Blocks: The first block that starts the chain
- Data Storage: You can put arbitrary data in blocks
- Validation: Check if a blockchain is valid or corrupted
- Functional Design: Clean Elixir code that's easy to test
The project has four main modules:
Block
- Individual block structure and validationCrypto
- Cryptographic hashing functionsBlockchain
- Chain operations and validationExBlock
- Main application module
Technical Implementation
Block Structure
Every blockchain needs blocks. Here's what our blocks look like:
defmodule Block do
defstruct [:data, :timestamp, :prev_hash, :hash]
def new(data, prev_hash) do
%Block{
data: data,
timestamp: NaiveDateTime.utc_now(),
prev_hash: prev_hash,
hash: nil
}
end
def zero do
%Block{
data: "ZERO_DATA",
timestamp: NaiveDateTime.utc_now(),
prev_hash: "ZERO_HASH",
hash: nil
}
end
end
Each block has:
- Data: Whatever you want to store
- Timestamp: When it was created
- Previous Hash: Links to the previous block
- Hash: The block's own cryptographic fingerprint
Hashing
The Crypto
module handles all the hashing with SHA256:
defmodule Crypto do
@hash_fields [:data, :timestamp, :prev_hash]
def hash(%Block{} = block) do
block
|> Map.take(@hash_fields)
|> Poison.encode!
|> sha256
end
def put_hash(%{} = block) do
%{block | hash: hash(block)}
end
defp sha256(binary) do
:crypto.hash(:sha256, binary) |> Base.encode16
end
end
Key points:
- Only data, timestamp, and prev_hash go into the hash calculation
- Uses standard SHA256 with uppercase hex output
Blockchain Operations
The Blockchain
module manages the actual chain:
defmodule Blockchain do
def new do
genesis = Block.zero() |> Crypto.put_hash()
[genesis]
end
def insert(blockchain, data) do
prev_block = List.first(blockchain)
new_block =
Block.new(data, prev_block.hash)
|> Crypto.put_hash()
[new_block | blockchain]
end
def valid?(blockchain) do
blockchain
|> Enum.reverse()
|> validate_chain()
end
end
The blockchain is just a list with the newest block at the front - works well with Elixir's list structure.
Why Elixir Works Well
A few things that made this easier in Elixir:
Immutability
Since everything is immutable by default, blockchain operations naturally return new chains rather than modifying existing ones.
Pattern Matching
The recursive validation logic is clean:
defp validate_chain([]), do: false
defp validate_chain([genesis_block]), do: Block.valid?(genesis_block)
defp validate_chain([prev_block | [current_block | _] = rest]) do
Block.valid?(prev_block) &&
Block.valid?(current_block, prev_block) &&
validate_chain(rest)
end
What's Missing
This is obviously a toy implementation. Real blockchains need:
- Consensus mechanisms (Proof of Work, etc.)
- Network communication
- Persistent storage
- Transaction handling
- Digital signatures
- Performance optimizations
Testing
The project has 43 tests covering the basics:
- Block creation and validation
- Hash consistency
- Chain operations
- Edge cases and corruption detection
Here's what it looks like running:
=== Simple Blockchain Test ===
1. Creating a new blockchain...
2. Inserting 'MESSAGE 1'...
3. Inserting 'MESSAGE 2' and 'MESSAGE 3'...
4. Validating the blockchain...
Blockchain is valid: true
5. Block details:
Block 0: ZERO_DATA (Hash: 9518E2175D869460...)
Block 1: MESSAGE 1 (Hash: 221FCFA6F4C72D12...)
Block 2: MESSAGE 2 (Hash: 48AAA0712AD7DD5A...)
Block 3: MESSAGE 3 (Hash: 7454D00D96F4FB1D...)
What I Learned
Keep It Simple
Starting with the basics and building up worked well. Each piece was easy to understand and test.
Tests Help
The comprehensive test suite caught bugs immediately and showed exactly what the expected behavior should be.
Debug Systematically
When everything broke, writing debug scripts to isolate issues was much faster than guessing.
Functional Programming Fits
Elixir's approach of immutable data and pure functions feels natural for blockchain concepts.
Try It Yourself
If you want to play around with it:
# Clone and run
git clone https://github.com/BenGlasser/exblock.git
cd exblock
mix deps.get
mix test
mix run test_blockchain.exs
# Interactive mode
iex -S mix
Conclusion
ExBlock is a basic blockchain that demonstrates the core concepts in a clean way. It's about 200 lines of Elixir that cover:
- Cryptographic hashing
- Block linkage
- Chain validation
- Simple data storage
The functional programming approach worked well for this kind of system, and Elixir's pattern matching made the validation logic pretty readable.
It's definitely just an academic exercise, but it helped me understand how the fundamental pieces fit together. If you're curious about blockchain internals or want to see how functional programming applies to this kind of problem, the code is straightforward to follow.