Engee 文档
Notebook

用Julia语言实现一个简单的区块链

在这个例子中,我们实现了一个简化的区块链算法,加密货币基础技术,分布式分类账和数据安全。

导言

区块链是由相互连接的块组成的分布式数据库。 每个块都包含前一个块的数据、时间戳和加密哈希。 这使得结构免受假货和变化的影响:如果有人试图改变其中一个块中的数据,他们将改变其散列,这将影响所有后续块。

在这个例子中,我们实现:
-块结构,
-区块哈希生成,
-建立区块链,
-检查链条的完整性。

这是区块链的简化版本,但它显示了其操作的关键原则。

主要部分

安装和连接必要的软件包

安装计算哈希所需的SHA包

In [ ]:
import Pkg; Pkg.add("SHA")
   Resolving package versions...
    Updating `~/.project/Project.toml`
  [ea8e919c] + SHA v0.7.0
    Updating `~/.project/Manifest.toml`
  [ea8e919c] + SHA v0.7.0

连接SHA包,它允许您计算SHA-256哈希

In [ ]:
using SHA

定义块结构

数据结构 Block 它代表区块链中的单个区块。
包含:

  • index:链中的区块编号
  • timestamp:区块创建时间
  • data:存储在块中的数据
  • previous_hash:前一个区块的哈希值
  • hash:自定义区块哈希
In [ ]:
struct Block
    index::Int
    timestamp::Float64
    data::String
    previous_hash::String
    hash::String
end
Out[0]:
Block

用于生成块哈希的函数

功能 calculate_hash 根据块数据生成SHA-256哈希。
参数:

  • index:区块编号
  • timestamp:创建时间
  • data:区块内容
  • previous_hash:前一个区块的哈希值
In [ ]:
function calculate_hash(index, timestamp, data, previous_hash)
    # Комбинируем данные блока в одну строку
    block_data = string(index, timestamp, data, previous_hash)
    # Вычисляем и возвращаем хэш SHA-256
    return bytes2hex(sha256(block_data))
end
Out[0]:
calculate_hash

第一个(零)区块的生成-创世区块

功能 create_genesis_block 创建链中的第一个块-"创世块"。
它没有以前的散列,所以我们使用空字符串。

In [ ]:
function create_genesis_block()
    index = 0
    timestamp = time() # текущее время
    data = "Genesis Block"
    previous_hash = "0" # нет предыдущего блока

    hash = calculate_hash(index, timestamp, data, previous_hash)
    return Block(index, timestamp, data, previous_hash, hash)
end
Out[0]:
create_genesis_block

创建新块

功能 create_next_block 基于前一个块创建一个新块。
参数:

  • previous_block:链中的前一个区块
  • data:新区块的数据
In [ ]:
function create_next_block(previous_block, data)
    index = previous_block.index + 1
    timestamp = time()
    previous_hash = previous_block.hash

    hash = calculate_hash(index, timestamp, data, previous_hash)
    return Block(index, timestamp, data, previous_hash, hash)
end
Out[0]:
create_next_block

链条完整性检查

功能 is_chain_valid 检查区块链的完整性是否受到侵犯。
为了这个:

  1. 检查每个哈希是否与其数据匹配。
  2. 检查是否指定了正确的地址 previous_hash 对于每个块。
In [ ]:
function is_chain_valid(chain::Vector{Block})
    for i in 2:length(chain)
        current_block = chain[i]
        previous_block = chain[i-1]

        # Проверяем, соответствует ли хэш блока пересчитанному значению
        expected_hash = calculate_hash(
            current_block.index,
            current_block.timestamp,
            current_block.data,
            current_block.previous_hash
        )

        if current_block.hash != expected_hash
            println("Нарушена целостность: хэш блока $(current_block.index) не совпадает")
            return false
        end

        # Проверяем, правильно ли указан previous_hash
        if current_block.previous_hash != previous_block.hash
            println("Нарушена последовательность: предыдущий хэш блока $(current_block.index) не совпадает")
            return false
        end
    end
    return true
end
Out[0]:
is_chain_valid

区块链创建和测试

创建块链

In [ ]:
blockchain = Vector{Block}()
Out[0]:
Block[]

添加创世块

In [ ]:
push!(blockchain, create_genesis_block())
Out[0]:
1-element Vector{Block}:
 Block(0, 1.757418165732052e9, "Genesis Block", "0", "89e9605fd77a7c1580679c91026c7c522e4ca2543a54d8b68ae9099769648fe5")

添加几个块

In [ ]:
push!(blockchain, create_next_block(blockchain[end], "Первая транзакция"))
push!(blockchain, create_next_block(blockchain[end], "Вторая транзакция"))
push!(blockchain, create_next_block(blockchain[end], "Третья транзакция"))
Out[0]:
4-element Vector{Block}:
 Block(0, 1.757418165732052e9, "Genesis Block", "0", "89e9605fd77a7c1580679c91026c7c522e4ca2543a54d8b68ae9099769648fe5")
 Block(1, 1.757418165985186e9, "Первая транзакция", "89e9605fd77a7c1580679c91026c7c522e4ca2543a54d8b68ae9099769648fe5", "5795b75b3f1c46ff0a77c54f91f84bb8702b0d047e81fdc259e2db71c1a87fcd")
 Block(2, 1.757418165985377e9, "Вторая транзакция", "5795b75b3f1c46ff0a77c54f91f84bb8702b0d047e81fdc259e2db71c1a87fcd", "d3113ceee60fdd38051311f312fb1e5579305cbff648fa81f9d2c11f4c7f7b89")
 Block(3, 1.757418165985547e9, "Третья транзакция", "d3113ceee60fdd38051311f312fb1e5579305cbff648fa81f9d2c11f4c7f7b89", "8d4083d1c8c42de81a7d8be592a77e77faa98ab01db0e838f18415d6afa760c0")

显示有关块的信息

In [ ]:
println("Цепочка блоков:")
for block in blockchain
    println("Индекс: $(block.index), Данные: $(block.data), Хэш: $(block.hash), Предыдущий хэш: $(block.previous_hash)")
end
Цепочка блоков:
Индекс: 0, Данные: Genesis Block, Хэш: 89e9605fd77a7c1580679c91026c7c522e4ca2543a54d8b68ae9099769648fe5, Предыдущий хэш: 0
Индекс: 1, Данные: Первая транзакция, Хэш: 5795b75b3f1c46ff0a77c54f91f84bb8702b0d047e81fdc259e2db71c1a87fcd, Предыдущий хэш: 89e9605fd77a7c1580679c91026c7c522e4ca2543a54d8b68ae9099769648fe5
Индекс: 2, Данные: Вторая транзакция, Хэш: d3113ceee60fdd38051311f312fb1e5579305cbff648fa81f9d2c11f4c7f7b89, Предыдущий хэш: 5795b75b3f1c46ff0a77c54f91f84bb8702b0d047e81fdc259e2db71c1a87fcd
Индекс: 3, Данные: Третья транзакция, Хэш: 8d4083d1c8c42de81a7d8be592a77e77faa98ab01db0e838f18415d6afa760c0, Предыдущий хэш: d3113ceee60fdd38051311f312fb1e5579305cbff648fa81f9d2c11f4c7f7b89

我们检查链条的完整性

In [ ]:
println("\nПроверка целостности цепочки: ", is_chain_valid(blockchain) ? "OK" : "Ошибка")
Проверка целостности цепочки: OK

结论

在这个例子中,我们用Julia语言实现了一个简单的区块链版本。:
-我们已经确定了块结构,
-实现SHA-256哈希的生成,
-创造了创世区块-链的开始,
-我们学会了如何添加新块,
-我们为整个链写了一个完整性检查。

这有助于理解区块链技术的基本原理:数据如何相互关联,为什么保护它免受变化,以及系统如何独立验证其正确性。

这些代码对于学习密码学,分布式系统的基础知识以及准备更复杂的项目(如创建加密货币或智能合约)非常有用。