本文作者:咔咔

最小可行区块链

最小可行区块链摘要: 这个MVB将具备区块链最核心的特性:区块结构:能打包交易,链式结构:每个区块都指向前一个区块,形成链条,工作量证明:通过计算来保证网络安全,防止篡改,共识:网络中所有节点对“哪条是...

这个MVB将具备区块链最核心的特性:

  1. 区块结构:能打包交易。
  2. 链式结构:每个区块都指向前一个区块,形成链条。
  3. 工作量证明:通过计算来保证网络安全,防止篡改。
  4. 共识:网络中所有节点对“哪条是主链”达成一致。

为了保持“最小化”,我们将省略一些高级特性,

最小可行区块链
(图片来源网络,侵删)
  • P2P网络:我们假设所有节点都在一个中心化的列表中,并知道彼此的地址。
  • 交易池:交易会直接被打包进下一个区块,而不是先进入一个等待池。
  • 高级共识机制:仅使用最基础的PoW。
  • 脚本和智能合约:交易仅包含简单的转账信息。
  • 钱包和账户系统:我们用公钥地址来代表用户。

最小可行区块链 的设计与实现

我们将用 Python 来实现这个MVB,因为它语法清晰,易于理解。

核心数据结构

我们需要定义区块链和区块的基本结构。

区块: 一个区块包含三部分核心信息:

  • 索引:它在链中的位置。
  • 时间戳:区块创建的时间。
  • 交易列表:本区块包含的所有交易数据。
  • 前一个区块的哈希:指向前一个区块的“指纹”,这是形成链式结构的关键。
  • Nonce:一个随机数,用于工作量证明的计算。

交易: 为了简化,我们的交易就是一个简单的字典,包含发送方、接收方和金额。

最小可行区块链
(图片来源网络,侵删)

区块链: 一个简单的列表,其中每个元素都是一个区块,第一个区块被称为“创世块”(Genesis Block)。

工作量证明

PoW的核心思想是:找到一个nonce值,使得区块头的哈希值满足特定条件(哈希值的前N位都是0),这个过程需要大量的计算,但验证结果却非常快。

  • 难度:我们通过控制需要满足的前导零的数量来调整挖矿难度。
  • 目标:找到一个nonce,使得 hash(block_data + nonce) 以多个零开头。

共识机制

在我们的MVB中,共识规则非常简单:

  • 最长的链是有效的链,如果网络中出现多个分叉,节点会选择并同步其中最长的那一条链。

Python 代码实现

下面是完整的、可运行的MVB代码。

最小可行区块链
(图片来源网络,侵删)
import hashlib
import json
import time
from typing import List, Dict
# 1. 定义交易结构
class Transaction:
    def __init__(self, sender: str, recipient: str, amount: int):
        self.sender = sender
        self.recipient = recipient
        self.amount = amount
    def to_dict(self) -> Dict:
        return {
            "sender": self.sender,
            "recipient": self.recipient,
            "amount": self.amount
        }
    def __str__(self):
        return json.dumps(self.to_dict())
# 2. 定义区块结构
class Block:
    def __init__(self, index: int, transactions: List[Transaction], timestamp: float, previous_hash: str):
        self.index = index
        self.transactions = transactions
        self.timestamp = timestamp
        self.previous_hash = previous_hash
        self.nonce = 0  # 用于工作量证明的随机数
    def compute_hash(self) -> str:
        """
        计算区块的哈希值。
        注意:为了确保哈希的唯一性和可变性,我们将区块的所有属性(包括nonce)都进行序列化后计算。
        """
        block_dict = {
            "index": self.index,
            "transactions": [tx.to_dict() for tx in self.transactions],
            "timestamp": self.timestamp,
            "previous_hash": self.previous_hash,
            "nonce": self.nonce
        }
        block_string = json.dumps(block_dict, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()
    def __str__(self):
        return f"Block #{self.index}"
# 3. 定义区块链结构
class Blockchain:
    def __init__(self, difficulty: int = 2):
        self.chain = []
        self.difficulty = difficulty  # 哈希值前导零的数量,越大越难
        self.pending_transactions = [] # 待打包的交易池
        self.create_genesis_block()
    def create_genesis_block(self):
        """
        创建创世块,它是链的第一个区块。
        """
        genesis_block = Block(
            index=0,
            transactions=[], # 创世块没有交易
            timestamp=time.time(),
            previous_hash="0"
        )
        # 挖矿创世块
        self.proof_of_work(genesis_block)
        self.chain.append(genesis_block)
        print(f"创世块已创建并添加到链中,哈希: {genesis_block.compute_hash()}")
    def get_last_block(self) -> Block:
        return self.chain[-1]
    def proof_of_work(self, block: Block) -> Block:
        """
        工作量证明算法。
        通过不断尝试nonce,直到找到一个哈希值满足前difficulty位都是0。
        """
        computed_hash = block.compute_hash()
        while not computed_hash.startswith('0' * self.difficulty):
            block.nonce += 1
            computed_hash = block.compute_hash()
        print(f"区块 #{block.index} 已被挖出,Nonce: {block.nonce}, 哈希: {computed_hash}")
        return block
    def add_transaction(self, transaction: Transaction):
        """
        将一个新交易添加到待处理列表中。
        """
        self.pending_transactions.append(transaction)
    def mine_pending_transactions(self, mining_reward_address: str):
        """
        挖矿:打包所有待处理交易,创建新区块并添加到链中。
        挖矿者会获得一笔奖励交易。
        """
        # 创建奖励交易
        reward_transaction = Transaction("SYSTEM", mining_reward_address, 10)
        transactions_to_mine = self.pending_transactions + [reward_transaction]
        new_block = Block(
            index=len(self.chain),
            transactions=transactions_to_mine,
            timestamp=time.time(),
            previous_hash=self.get_last_block().compute_hash()
        )
        # 挖矿
        new_block = self.proof_of_work(new_block)
        # 将新区块添加到链中
        self.chain.append(new_block)
        print(f"区块 #{new_block.index} 已被成功添加到链中!")
        # 清空待处理交易列表
        self.pending_transactions = []
        print(f"矿工 {mining_reward_address} 获得了 10 个奖励币。")
    def is_chain_valid(self) -> bool:
        """
        验证整个区块链的有效性。
        1. 检查每个区块的previous_hash是否正确指向前一个区块。
        2. 检查每个区块的哈希值是否是通过有效的工作量证明计算得出的。
        """
        for i in range(1, len(self.chain)):
            current_block = self.chain[i]
            previous_block = self.chain[i - 1]
            # 检查1: 前一个区块的哈希是否正确
            if current_block.previous_hash != previous_block.compute_hash():
                print(f"无效的链:区块 #{current_block.index} 的 previous_hash 不匹配。")
                return False
            # 检查2: 工作量证明是否有效
            computed_hash = current_block.compute_hash()
            if not computed_hash.startswith('0' * self.difficulty):
                print(f"无效的链:区块 #{current_block.index} 的哈希值未满足PoW要求。")
                return False
        return True
    def get_balance(self, address: str) -> int:
        """
        计算一个地址的余额。
        """
        balance = 0
        for block in self.chain:
            for tx in block.transactions:
                if tx.recipient == address:
                    balance += tx.amount
                if tx.sender == address:
                    balance -= tx.amount
        return balance
# --- 主程序:演示MVB的运行 ---
if __name__ == "__main__":
    # 1. 创建一个新的区块链实例
    my_coin = Blockchain(difficulty=2) # 设置难度为2,意味着哈希需要以 "00" 开头
    # 2. 创建一些用户和交易
    alice = "Alice"
    bob = "Bob"
    charlie = "Charlie"
    # 3. 添加一些交易到待处理列表
    # 注意:在真实场景中,这些交易由不同的人发起,但在这里我们简化了流程
    my_coin.add_transaction(Transaction(sender=alice, recipient=bob, amount=50))
    my_coin.add_transaction(Transaction(sender=bob, recipient=charlie, amount=30))
    # 4. 挖矿
    # 假设 "Miner-A" 进行了第一次挖矿
    print("\n--- 开始第一次挖矿 ---")
    my_coin.mine_pending_transactions("Miner-A")
    # 查看Alice的余额
    print(f"\n当前余额:")
    print(f"Alice: {my_coin.get_balance(alice)}")
    print(f"Bob: {my_coin.get_balance(bob)}")
    print(f"Charlie: {my_coin.get_balance(charlie)}")
    print(f"Miner-A: {my_coin.get_balance('Miner-A')}")
    # 5. 添加更多交易并进行第二次挖矿
    print("\n--- 添加更多交易 ---")
    my_coin.add_transaction(Transaction(sender=charlie, recipient=alice, amount=20))
    my_coin.add_transaction(Transaction(sender=alice, recipient=bob, amount=10))
    print("\n--- 开始第二次挖矿 ---")
    my_coin.mine_pending_transactions("Miner-B")
    # 6. 查看最终余额
    print(f"\n最终余额:")
    print(f"Alice: {my_coin.get_balance(alice)}")
    print(f"Bob: {my_coin.get_balance(bob)}")
    print(f"Charlie: {my_coin.get_balance(charlie)}")
    print(f"Miner-A: {my_coin.get_balance('Miner-A')}")
    print(f"Miner-B: {my_coin.get_balance('Miner-B')}")
    # 7. 打印完整的区块链
    print("\n--- 完整的区块链 ---")
    for i, block in enumerate(my_coin.chain):
        print(f"\n--- Block #{block.index} ---")
        print(f"Timestamp: {block.timestamp}")
        print(f"Previous Hash: {block.previous_hash}")
        print(f"Nonce: {block.nonce}")
        print(f"Transactions:")
        for tx in block.transactions:
            print(f"  - From: {tx.sender}, To: {tx.recipient}, Amount: {tx.amount}")
        print(f"Hash: {block.compute_hash()}")
    # 8. 验证链的完整性
    print("\n--- 验证区块链 ---")
    if my_coin.is_chain_valid():
        print("✅ 区块链有效!")
    else:
        print("❌ 区块链无效!")
    # 9. 演示篡改
    print("\n--- 演示篡改 ---")
    # 尝试篡改第一个区块中的交易
    if len(my_coin.chain) > 1:
        my_coin.chain[1].transactions[0].amount = 999999 
        print("已篡改区块 #1 中的第一笔交易金额。")
        # 再次验证链
        if my_coin.is_chain_valid():
            print("✅ 区块链有效!") # 这行代码不应该执行
        else:
            print("❌ 区块链无效!篡改被检测到。")

如何运行和理解代码

  1. 保存代码:将上面的代码保存为一个Python文件,minimal_blockchain.py
  2. 运行:在终端中执行 python minimal_blockchain.py
  3. 观察输出
    • 你会看到创世块的创建。
    • 然后是第一次挖矿的过程,程序会尝试不同的nonce值,直到找到一个满足条件的哈希。
    • 之后会显示各用户的余额。
    • 接着是第二次挖矿。
    • 它会打印出完整的区块链信息,并进行验证。
    • 在演示篡改部分,你会看到一旦我们修改了历史区块中的一个交易,整个链的验证就会失败,这完美地展示了区块链的不可篡改性。

这个MVB的局限性(如何进一步发展)

这个MVB虽然核心功能完备,但距离真正的区块链(如比特币或以太坊)还有很长的路要走,要让它变得更“可行”,可以添加以下功能:

  1. P2P网络层:使用像 socketlibp2p 这样的库,让节点能够发现彼此、广播新区块和交易,而不是在一个中心化的列表里。
  2. 更复杂的交易脚本:允许交易包含脚本,用于实现更复杂的逻辑,例如多重签名、时间锁等。
  3. UTXO 模型 vs. 账本模型:我们的例子使用的是简单的账本模型(记录每个地址的余额),比特币使用的是UTXO(Unspent Transaction Output)模型,这更复杂但也更灵活和安全。
  4. 完整节点和轻量级节点:引入不同类型的节点,轻量级节点(如SPV客户端)不需要下载整个区块链,可以通过“简化支付验证”来确认交易。
  5. 激励机制和更安全的共识:除了PoW,还可以研究PoS(权益证明)、DPoS(委托权益证明)等其他共识机制,它们更节能。
  6. 钱包集成:实现私钥/公钥对的管理、签名和交易广播功能。

这个“最小可行区块链”是一个绝佳的学习起点,它清晰地展示了区块链最底层的运作原理。

文章版权及转载声明

作者:咔咔本文地址:https://jits.cn/content/25751.html发布于 02-08
文章转载或复制请以超链接形式并注明出处杰思科技・AI 股讯

阅读
分享

发表评论

快捷回复:

评论列表 (暂无评论,1人围观)参与讨论

还没有评论,来说两句吧...