Skip to content

Commit

Permalink
Merge pull request #65 from hlongvu/master
Browse files Browse the repository at this point in the history
Add version number to block
  • Loading branch information
alexdovzhanyn authored Nov 11, 2018
2 parents 17ca0a7 + 1134cb0 commit 2b87c9d
Show file tree
Hide file tree
Showing 5 changed files with 368 additions and 314 deletions.
49 changes: 32 additions & 17 deletions lib/block.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule Elixium.Blockchain.Block do

defstruct index: nil,
hash: nil,
version: 1,
previous_hash: nil,
difficulty: nil,
nonce: 0,
Expand All @@ -31,9 +32,9 @@ defmodule Elixium.Blockchain.Block do
"""
@spec initialize :: Block
def initialize do
%Block{
block = %Block{
index: 0,
hash: "79644A8F062F1BA9F7A32AF2242C04711A634D42F0628ADA6B985B3D21296EEA",
hash: "",
difficulty: 5.0,
timestamp: DateTime.utc_now() |> DateTime.to_string(),
transactions: [
Expand All @@ -50,6 +51,9 @@ defmodule Elixium.Blockchain.Block do
}
]
}

%{block | hash: calculate_block_hash(block)}

end

@doc """
Expand All @@ -60,12 +64,35 @@ defmodule Elixium.Blockchain.Block do
def initialize(%{index: index, hash: previous_hash}) do
%Block{
index: index + 1,
version: 1,
previous_hash: previous_hash,
difficulty: 4.0,
timestamp: DateTime.utc_now() |> DateTime.to_string()
}
end


@spec calculate_block_hash(Block) :: String.t()
def calculate_block_hash(block) do
%{
index: index,
version: version,
previous_hash: previous_hash,
timestamp: timestamp,
nonce: nonce,
merkle_root: merkle_root
} = block

Utilities.sha3_base16([
Integer.to_string(index),
Integer.to_string(version),
previous_hash,
timestamp,
Integer.to_string(nonce),
merkle_root
])
end

@doc """
The process of mining consists of hashing the index of the block, the hash
of the previous block (thus linking the current and previous block), the
Expand All @@ -77,22 +104,9 @@ defmodule Elixium.Blockchain.Block do
"""
@spec mine(Block) :: Block
def mine(block) do
%{
index: index,
previous_hash: previous_hash,
timestamp: timestamp,
nonce: nonce,
merkle_root: merkle_root
} = block
%{nonce: nonce } = block

block =
Map.put(block, :hash, Utilities.sha3_base16([
Integer.to_string(index),
previous_hash,
timestamp,
Integer.to_string(nonce),
merkle_root
]))
block = Map.put(block, :hash, calculate_block_hash(block))

if hash_beat_target?(block) do
block
Expand All @@ -109,6 +123,7 @@ defmodule Elixium.Blockchain.Block do
%{
hash: block.hash,
index: block.index,
version: block.version,
previous_hash: block.previous_hash,
merkle_root: block.merkle_root,
nonce: block.nonce,
Expand Down
8 changes: 4 additions & 4 deletions lib/validator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ defmodule Elixium.Validator do

@spec valid_hash?(Block, number) :: :ok | {:error, {:wrong_hash, {:too_high, String.t(), number}}}
defp valid_hash?(b, difficulty) do
with :ok <- compare_hash({b.index, b.previous_hash, b.timestamp, b.nonce, b.merkle_root}, b.hash),
with :ok <- compare_hash({b.index, b.version, b.previous_hash, b.timestamp, b.nonce, b.merkle_root}, b.hash),
:ok <- beat_target?(b.hash, b.difficulty)
do
:ok
Expand All @@ -55,11 +55,11 @@ defmodule Elixium.Validator do
end
end

@spec compare_hash({number, String.t(), String.t(), number, String.t()}, String.t()) ::
@spec compare_hash({number, number, String.t(), String.t(), number, String.t()}, String.t()) ::
:ok | {:error, {:wrong_hash, {:doesnt_match_provided, String.t(), String.t()}}}
defp compare_hash({index, previous_hash, timestamp, nonce, merkle_root}, hash) do
defp compare_hash({index, version, previous_hash, timestamp, nonce, merkle_root}, hash) do
computed =
[Integer.to_string(index), previous_hash, timestamp, Integer.to_string(nonce), merkle_root]
[Integer.to_string(index), Integer.to_string(version), previous_hash, timestamp, Integer.to_string(nonce), merkle_root]
|> Utilities.sha3_base16()

if computed == hash do
Expand Down
5 changes: 4 additions & 1 deletion test/block_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ defmodule BlockTest do
genesis = Block.initialize()

assert genesis.index == 0
assert genesis.hash == "79644A8F062F1BA9F7A32AF2242C04711A634D42F0628ADA6B985B3D21296EEA"
assert genesis.hash == Block.calculate_block_hash(genesis)
assert genesis.version == 1
end

test "can create a new empty block" do
Expand All @@ -20,8 +21,10 @@ defmodule BlockTest do

assert block.index == genesis.index + 1
assert block.previous_hash == genesis.hash
assert block.version == 1
end


test "can mine a block" do
genesis = Block.initialize()

Expand Down
9 changes: 9 additions & 0 deletions test/blockchain_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,13 @@ defmodule BlockchainTest do

assert Blockchain.recalculate_difficulty() == 0
end

test "chain.exs contains valid block hash" do
{chain, _} = Code.eval_file("test/fixtures/chain.exs")
ok = chain
|> Enum.map(& &1.hash == Block.calculate_block_hash(&1))
|> Enum.all?()
assert ok
end

end
Loading

0 comments on commit 2b87c9d

Please sign in to comment.