I'm a programmer with a C++ and Python background who recently stumbled upon Julia, and I really like what it has to offer. In order to become more familiar with both blockchain implementation and Julia at the same time, I'm being a little ambitious and am trying to create a basic implementation of a blockchain in Julia by converting the Python implementation posted by Hackernoon (The author explains what each method is supposed to do better than I ever could).
However, I'm running into issues when creating the actual Blockchain
struct. In order to create the genesis block, Hackernoon suggests I call the member function new_block
in the constructor. So far, I haven't been able to figure out how to best replicate this in Julia. Here's what I have so far:
import JSON
import SHA
mutable struct Blockchain
chain::Array{Dict{String, Any}}
current_transactions::Array{String}
block::Dict{String, Any}
new_block::Function
function Blockchain(chain::Array{Dict{String, Any}}, current::Array{String})
new(chain, current, new_block(previous_hash=1, proof=100))
# ^issue calling function within the constructor here
end
end
When I try to run my code, I get the following error:
invalid redefinition of constant Blockchain
.
Here's the new_block
function:
function new_block(proof::String, previous_hash::String=nothing)
block = Dict(
"index" => length(chain) + 1,
"timestamp" => time(),
"transactions" => current_transactions,
"proof" => proof,
"previous_hash" => previous_hash | hash(chain[end]),
)
current_transactions = []
append!(chain, block)
return block
end
Here are the rest of the functions I currently have:
function new_transaction(this::Blockchain, sender::String, recipient::String, amount::Int)
transaction = Dict(
"sender"=> sender,
"recipient"=> recipient,
"amount"=> amount,
)
append!(this.current_transactions, transaction)
return length(this.chain) + 1
end
function hash(block::Blockchain)
block_string = JSON.dumps(block, sort_keys=true).encode()
return sha256(block_string).hexdigest()
end
I might have some misconceptions about how types/structs work in Julia; most of my information was obtained from third party websites along with the official documentation. Here are some of the sources I've been relying on:
- https://scls.gitbooks.io/ljthw/content/_chapters/06-ex3.html
- https://thenewphalls.wordpress.com/2014/02/19/understanding-object-oriented-programming-in-julia-part-1/
- https://juliabyexample.helpmanual.io/
Smarter/more efficient ways of trying to accomplish what I am would be immensely appreciated.
Edit:
Here are some of the changes I've made, based on given suggestions:
struct Blockchain
chain::Array{Dict{String, Any}}
current_transactions::Array{String}
function Blockchain(chain::Array{Dict{String, Any}}, current::Array{String})
new(chain, current)
end
end
function new_block!(this::Blockchain, proof::Int, previous_hash::Int=nothing)
block = Dict(
"index" => length(this.chain) + 1,
"timestamp" => time(),
"transactions" => this.current_transactions,
"proof" => proof,
)
if previous_hash == nothing
block["previous_hash"] = hash(this.chain[end])
else
block["previous_hash"] = previous_hash
end
this.current_transactions = []
append!(this.chain, block)
return this
end
I realized that the block
attribute was useless, as it only existed to be added to the chain
, so I removed it.
Additionally, here is an alternate Blockchain
definition without the inner constructor:
struct Blockchain
chain::Array{Dict{String, Any}}
current_transactions::Array{String}
Blockchain(x::Array{Dict{String, Any}}, y::Array{String}) = new(x, y)
end
invalid redefinition of constant Blockchain
isn't related to yournew_block
function stuff at all. It's just that you can't redefine a type (struct) in Julia. Once it's defined you can't change it anymore. – carstenbauerBlockchain(chain, current)
isERROR: UndefVarError: new_block not defined
which makes perfect sense. I'd suggest to not put thenew_block
function into the struct at all. Typically in Julia you put "attributes" into the struct and functions separately. – carstenbauernew_block
should simply take aBlockchain
object as first argument. You can than access and modify fields of thisBlockchain
. – carstenbauerstruct
along withnew_block
? – victor-alvesstruct
definition. however, inner constructors will have another effect on your code, i.e., no default constructor will be generated by Julia's compiler. Basically, your original problem has nothing to do with your constructor, nornew_block
. You cannot redefine the type, as the error already suggests. Then, when you solve that problem, you will face another one because you are trying to call part of an object which is to be created (not yet done) – Arda Aytekin