当前位置: 首页 > ops >正文

从零开始:用代码解析区块链的核心工作原理

 

区块链技术被誉为信任的机器,它正在重塑金融、供应链、数字身份等众多领域。但对于许多开发者来说,它仍然像一个神秘的黑盒子。今天,我们将抛开炒作的泡沫,深入技术本质,用大约100行Python代码构建一个简易的区块链,并逐一解析其核心概念。

 

一、区块链是什么?一个简单的比喻

 

想象一个公共的记账本( Ledger )。这个本子的每一页( Block )都记录着多条交易信息,并且每一页的页眉都包含了前一页的摘要( Hash )。如果有人篡改了某一页的内容,那么这一页的摘要就会改变, subsequently 导致后续所有页的页眉信息都对不上,从而立刻被所有人发现。这个按时间顺序首尾相连的记账本,就是区块链。

 

二、核心概念与代码实现

 

我们将实现一个名为 SimpleBlockchain 的类,它包含以下核心功能:

 

1. 区块结构 (Block Structure)

2. 哈希函数 (Hashing) - 保证数据不可篡改

3. 生成创世区块 (Genesis Block)

4. 工作量证明 (Proof-of-Work) - 保证挖矿难度

5. 链式结构 (Chaining Blocks) - 通过哈希连接

 

让我们开始写代码!

 

1. 导入依赖库

 

我们主要需要两个库:hashlib 用于计算哈希,time 为区块提供时间戳。

 

```python

import hashlib

import time

```

 

2. 定义区块结构

 

每个区块都包含一些关键信息:索引、时间戳、数据、前一个区块的哈希、当前区块的随机数(Nonce)和自身的哈希。

 

```python

class Block:

    def __init__(self, index, timestamp, data, previous_hash):

        self.index = index

        self.timestamp = timestamp

        self.data = data # 在真实区块链中,这通常是交易列表的Merkle根

        self.previous_hash = previous_hash

        self.nonce = 0 # 用于工作量证明的随机数

        self.hash = self.calculate_hash() # 计算当前区块的哈希值

 

    def calculate_hash(self):

        # 将区块的所有信息组合成一个字符串,并计算其SHA-256哈希值

        block_string = f"{self.index}{self.timestamp}{self.data}{self.previous_hash}{self.nonce}".encode()

        return hashlib.sha256(block_string).hexdigest()

```

 

代码解析:

 

· previous_hash:这是链式结构的核心!它指向上一个区块,从而形成了链。任何对旧区块的修改都会导致其哈希变化,进而破坏整个后续链。

· calculate_hash 方法:它接收区块的所有属性(包括 nonce),生成一个唯一的、固定长度的“数字指纹”(哈希值)。SHA-256算法保证了计算的单向性,即极易验证但极难破解。

 

3. 创建区块链类

 

区块链类负责管理链,提供添加新区块的方法。

 

```python

class SimpleBlockchain:

    def __init__(self):

        self.chain = [self.create_genesis_block()] # 初始化链,并创建创世区块

        self.difficulty = 4 # 工作量证明的难度,表示哈希值必须以多少个'0'开头

 

    def create_genesis_block(self):

        # 创世区块是第一个区块,没有前一个区块,所以previous_hash设为0

        return Block(0, time.time(), "Genesis Block", "0")

 

    def get_latest_block(self):

        return self.chain[-1]

```

 

代码解析:

 

· create_genesis_block:区块链的第一个区块是特殊的,它没有前任,必须被硬编码到系统中。

· difficulty:这是一个动态调整的参数,用来控制“挖矿”(生成新区块)的速度。难度值越大,找到有效哈希所需的计算时间就越长。

 

4. 实现工作量证明 (Proof-of-Work)

 

这是区块链(尤其是比特币)的灵魂所在。矿工需要通过大量计算找到一个满足特定条件的 nonce 值。

 

```python

    def proof_of_work(self, block):

        # 目标:找到一个nonce,使得区块的哈希值的前difficulty位是0

        target = '0' * self.difficulty

        while block.hash[:self.difficulty] != target:

            block.nonce += 1 # 不断尝试新的nonce值

            block.hash = block.calculate_hash() # 重新计算哈希

        print(f"Block mined: {block.hash}")

        return block

```

 

代码解析:

 

· 矿工(proof_of_work 函数)不断地改变 nonce 的值,并重新计算区块哈希。

· 只有当计算出的哈希值的前 difficulty 位都是 ‘0’ 时,才算成功。

· 这个过程极其耗时且耗电,但验证却非常容易(只需计算一次哈希并检查前导零)。这就是“工作量证明”的含义——它证明了矿工投入了真实的计算资源。

 

5. 添加新区块

 

现在,我们可以将挖矿成功后的区块添加到链上。

 

```python

    def add_block(self, new_block):

        new_block.previous_hash = self.get_latest_block().hash # 设置新区块的previous_hash

        new_block = self.proof_of_work(new_block) # 执行挖矿!

        self.chain.append(new_block) # 将挖矿后的有效区块添加到链上

 

    def is_chain_valid(self):

        for i in range(1, len(self.chain)):

            current_block = self.chain[i]

            previous_block = self.chain[i-1]

            # 检查1:当前区块存储的哈希值是否真的等于它计算出的哈希值?

            if current_block.hash != current_block.calculate_hash():

                print(f"Data tampered in block {current_block.index}!")

                return False

            # 检查2:当前区块的previous_hash是否等于上一个区块的哈希值?

            if current_block.previous_hash != previous_block.hash:

                print(f"Chain broken between block {previous_block.index} and {current_block.index}!")

                return False

        return True

```

 

代码解析:

 

· add_block:在添加区块前,必须先进行耗时的挖矿过程。这保证了区块不能随意被添加,确保了网络的安全性和一致性。

· is_chain_valid:验证区块链的完整性。它会遍历整个链,检查每个区块的哈希是否正确,以及区块间的链接是否未被破坏。任何微小的篡改都会导致 calculate_hash() 的结果与存储的 hash 不匹配。

 

三、测试我们的迷你区块链

 

让我们运行一下,看看它的效果。

 

```python

# 初始化我们的区块链

my_blockchain = SimpleBlockchain()

 

print("Mining block 1...")

my_blockchain.add_block(Block(1, time.time(), "Alice pays Bob 1 BTC", ""))

 

print("Mining block 2...")

my_blockchain.add_block(Block(2, time.time(), "Bob pays Charlie 0.5 BTC", ""))

 

# 打印所有区块

for block in my_blockchain.chain:

    print(f"Index: {block.index}")

    print(f"Hash: {block.hash}")

    print(f"Previous Hash: {block.previous_hash}")

    print(f"Data: {block.data}")

    print(f"Nonce: {block.nonce}\n")

 

# 验证区块链是否有效

print(f"Is blockchain valid? {my_blockchain.is_chain_valid()}")

 

# 尝试篡改数据!

print("\nAttempting to tamper with data...")

my_blockchain.chain[1].data = "Alice pays Bob 100 BTC" # 修改第一个区块的数据

# 由于数据被修改,它的哈希值变了,但后续区块的previous_hash指向的还是旧的、错误的哈希。

print(f"Is blockchain valid after tampering? {my_blockchain.is_chain_valid()}") # 输出:False

```

 

输出结果示例:

 

```

Mining block 1...

Block mined: 0000a1b2c3d4...(哈希值以4个0开头)

Mining block 2...

Block mined: 0000e5f6g7h8...(哈希值以4个0开头)

 

Index: 0 (Genesis Block)

Hash: 89ab...

Previous Hash: 0

...

 

Index: 1

Hash: 0000a1b2c3d4... # 以0000开头

Previous Hash: 89ab... # 指向创世区块的哈希

Data: Alice pays Bob 1 BTC

Nonce: 68452 # 一个很大的数字,说明矿工尝试了68452次才找到有效的nonce

 

...

 

Is blockchain valid? True

Attempting to tamper with data...

Data tampered in block 1! # 验证函数发现了数据被篡改

Is blockchain valid after tampering? False

```

 

四、总结与展望

 

通过这不到100行的代码,我们实现了一个具备核心功能的区块链:

 

· 不可篡改性:通过哈希函数保证,修改数据会立即使哈希失效。

· 链式结构:通过 previous_hash 将区块按时间顺序链接起来。

· 工作量证明:通过挖矿机制保证网络的安全性和去中心化共识。

 

当然,这只是一个极其简化的模型。一个生产级的区块链(如比特币、以太坊)要复杂得多,它还包括:

 

· 点对点网络:节点如何发现和通信。

· 交易模型:UTXO(比特币)或账户余额(以太坊)。

· ** Merkle 树**:高效地验证大量交易的存在性。

· 共识算法:PoW(工作量证明)之外的PoS(权益证明)等。

· 智能合约:在区块链上运行的自动化代码。

 

 

http://www.xdnf.cn/news/19626.html

相关文章:

  • linux开发板(rk3568,树莓派)自动连接保存好的WIFI
  • 模板商城探秘:DINO-X 定制模板指南(2)
  • Stop-Process : 由于以下错误而无法停止进程“redis-server (26392)”: 拒绝访问。
  • HTTPS如何保证数据传输过程中的安全性?
  • HQX SELinux 权限问题分析与解决
  • 2025 年,这些求职技能利用空闲时间就能学,轻松提升职场竞争力​
  • 亚马逊的领导力原则
  • Photoshop - Ps 处理图层
  • Qt模型/视图编程详解:QStringListModel与多视图数据同步
  • linux 命令 awk的常见用法
  • Zynq中级开发七项必修课-第四课:S_AXI_HP0 高速端口访问 DDR
  • OCR 识别准确率的关键影响因素
  • NAT与内网穿透
  • 【python】python进阶——pip命令
  • 【完整源码+数据集+部署教程】粘土石实例分割系统源码和数据集:改进yolo11-LVMB
  • Qt Demo(3) 之 deepseek 帮我写的关于图像显示的小界面
  • 【Vue2 ✨】Vue2 入门之旅(十):Vuex 入门
  • 精读:《VideoMAE V2: Scaling Video Masked Autoencoders with Dual Masking》
  • 一键换装玩疯了!3个AI魔法提示词让你秒变时尚达人
  • lua脚本在redis中执行是否是原子性?
  • Java反序列化漏洞揭秘:从原理到攻击实战
  • RT-DETR模型训练中断,接着训练的方法
  • 单片机day1
  • DevExpress WPF中文教程:如何将WPF数据网格绑定到本地数据库?
  • MyBatis:让 SQL 与代码和谐共处的持久层框架
  • Windows 和 Linux 服务器 IP 与域名强制绑定方法
  • Python上下文管理器:资源管理的隐形守护者
  • 灵神题单之链表、树
  • k8s的CRD自定义资源类型示例
  • 整体认识K8s之PriorityClass优先级调度/HPA自动扩缩容机制