【发布时间】:2018-08-19 09:29:00
【问题描述】:
我是一名具有 C++ 和 Python 背景的程序员,最近偶然发现了 Julia,我真的很喜欢它所提供的功能。为了同时更熟悉区块链实现和 Julia,我有点雄心勃勃,正在尝试通过转换 Hackernoon 发布的 Python 实现在 Julia 中创建区块链的基本实现(作者解释了每种方法应该比我做得更好的地方)。
但是,我在创建实际的 Blockchain 结构时遇到了问题。为了创建创世块,Hackernoon 建议我在构造函数中调用成员函数new_block。到目前为止,我还没有弄清楚如何在 Julia 中最好地复制它。到目前为止,这是我所拥有的:
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
当我尝试运行我的代码时,我收到以下错误:
invalid redefinition of constant Blockchain.
这是new_block 函数:
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
以下是我目前拥有的其他功能:
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
我可能对类型/结构在 Julia 中的工作方式有一些误解;我的大部分信息是从第三方网站以及官方文档中获得的。以下是我一直依赖的一些来源:
- 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/
以更聪明/更有效的方式尝试完成我的工作将不胜感激。
编辑:
以下是我根据给定建议所做的一些更改:
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
我意识到block 属性没有用,因为它只是为了添加到chain 而存在,所以我将其删除。
此外,这里还有一个没有内部构造函数的替代 Blockchain 定义:
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与您的new_block函数完全无关。只是不能在 Julia 中重新定义类型(结构)。一旦它被定义,你就不能再改变它了。 -
调用构造函数
Blockchain(chain, current)时真正得到的错误是ERROR: UndefVarError: new_block not defined,这很有意义。我建议根本不要将new_block函数放入结构中。通常在 Julia 中,您将“属性”分别放入结构和函数中。 -
所以你的
new_block应该简单地将Blockchain对象作为第一个参数。您可以访问和修改此Blockchain的字段。 -
这是有道理的。这是否意味着构造函数应该与
new_block一起超出struct? -
@victor-alves,构造函数可以保持在
struct定义内。但是,inner constructors 将对您的代码产生另一种影响,即,Julia 的编译器不会生成默认构造函数。基本上,您的原始问题与您的构造函数无关,也与new_block无关。正如错误已经暗示的那样,您无法重新定义类型。然后,当您解决该问题时,您将面临另一个问题,因为您正在尝试调用要创建的对象的一部分(尚未完成)
标签: function methods constructor julia blockchain