Flutter for OpenHarmony 构建简易区块链:从交易到挖矿的完整模拟

区块链技术常被描述为“去中心化的账本”,但其核心原理——哈希链、工作量证明(PoW)、不可篡改性——对初学者而言仍显抽象。本文将通过一段完整的 Flutter 代码,带你亲手构建一个可视化、可交互的简易区块链系统。它虽不具备真实网络能力,却精准还原了比特币等公链的核心机制:创建交易、打包区块、挖矿验证、完整性校验。这不仅是一次编程实践,更是一场深入区块链底层逻辑的沉浸式学习。

🌐 加入社区 欢迎加入 开源鸿蒙跨平台开发者社区,获取最新资源与技术支持: 👉 开源鸿蒙跨平台开发者社区


完整效果
在这里插入图片描述
在这里插入图片描述

一、整体架构:三层数据模型

整个应用围绕三个核心类展开,形成清晰的数据流:

职责 关键字段
Transaction 单笔交易记录 发送方、接收方、金额、时间戳
Block 区块容器 交易列表、前一区块哈希、自身哈希、随机数(nonce)
_BlockchainScreenState 链状态管理 区块链(_chain)、待处理交易池(_pendingTransactions

💡 设计哲学:每个区块都包含指向前一个区块的哈希,形成不可逆的链式结构——这是区块链防篡改的基石。


二、核心机制实现详解

1. 交易创建:简单而严谨

class Transaction {
  final String sender, recipient;
  final double amount;
  final String timestamp; // 使用毫秒时间戳确保唯一性

  String get data => '$sender$recipient$amount$timestamp'; // 用于哈希计算
}

在这里插入图片描述

  • 时间戳唯一性:使用 millisecondsSinceEpoch 避免相同交易产生相同哈希;
  • 数据序列化data 属性将交易转为字符串,作为哈希输入。

2. 区块哈希:SHA-256 的力量

static String _calculateHash(int index, String timestamp, List<Transaction> transactions, String previousHash, int nonce) {
  final String data = '$index$timestamp${transactions.map((t) => t.data).join()}$previousHash$nonce';
  return sha256.convert(utf8.encode(data)).toString();
}

在这里插入图片描述

  • 输入要素:区块索引、时间戳、所有交易、前一哈希、随机数;
  • 加密保障:使用 crypto 包的 sha256 算法,确保微小改动导致哈希剧变。

3. 工作量证明(PoW):挖矿的本质

factory Block.mineBlock(...) {
  int nonce = 0;
  while (!hash.startsWith('000')) { // 目标:哈希以 "000" 开头
    hash = _calculateHash(..., nonce);
    nonce++;
    
    // 安全机制:超时降级难度
    if (nonce % 100000 == 0 && elapsed.inSeconds > 5) {
      if (hash.startsWith('00')) break; // 改为 "00" 即可
    }
  }
  return Block(..., nonce: nonce, hash: hash);
}

在这里插入图片描述

  • 难度设定:寻找以 000 开头的哈希(演示用,真实比特币需 19 个 0);
  • 防卡死设计:若 5 秒未找到,自动降低难度至 00,保证用户体验;
  • Nonce 的作用:通过不断尝试随机数,使哈希满足目标条件——这就是“挖矿”的计算过程。

4. 创世区块:链的起点

final genesisBlock = Block(
  index: 0,
  previousHash: '0', // 创世区块无前驱
  hash: '816534932c2b7154836da6afc367695e6337db8a9218237d46b02a5584afcc18', // 预设有效哈希
  transactions: [Transaction('System', 'Miner_Alice', 50.0)], // 初始奖励
);
  • 固定哈希:预设一个符合 000 开头的哈希值,避免启动时挖矿;
  • 初始奖励:模拟比特币的区块奖励机制。

三、用户交互:从交易到验证

1. 创建交易

  • UI 提供三个输入框(发送方、接收方、金额);
  • 点击“添加”后,交易进入 _pendingTransactions 池;
  • 注意:当前代码存在 Bug(见下文分析),但逻辑意图清晰。

2. 挖矿打包

  • 点击“挖掘新区块”触发挖矿流程;
  • 显示加载对话框,模拟计算耗时;
  • 成功后:
    • 新区块加入 _chain
    • 清空待处理交易;
    • 弹出 SnackBar 提示成功。

3. 区块链验证

  • 点击 AppBar 的 ✅ 图标,执行 _isValidChain()
  • 双重校验
    1. 检查 block[i].previousHash == block[i-1].hash
    2. 重新计算每个区块哈希,与存储值比对;
  • 若任一校验失败,提示“区块链数据已损坏”。

四、UI/UX 设计亮点

1. 信息分层展示

  • 控制区:交易输入 + 挖矿按钮;
  • 状态栏:实时显示待处理交易数与链长度;
  • 区块链浏览器
    • 最新区块置顶(reverse: true);
    • 创世区块高亮(灰色背景);
    • 每个区块可展开查看内部交易详情。

2. 可视化哈希摘要

title: Text('区块 #${block.index} | 🔗 ${block.hash.substring(0, 8)}...')
  • 仅显示哈希前 8 位,避免界面杂乱;
  • 保留足够信息用于识别区块。

3. 难度指示

subtitle: Text('... | 难度: ${block.hash.startsWith('000') ? "000" : "低"}')
  • 直观反映该区块是否满足原始难度要求。

五、代码问题与改进建议

⚠️ 关键 Bug:交易输入失效

// 错误写法:每次创建新 TextEditingController,无法获取用户输入
onPressed: () {
  final sender = TextEditingController(text: 'User').text; // 始终是 'User'
}

修复方案

// 在 State 中声明控制器
final _senderCtrl = TextEditingController(text: 'User');
final _recipientCtrl = TextEditingController(text: 'Bob');
final _amountCtrl = TextEditingController(text: '10');

// 在 build 中绑定
TextField(controller: _senderCtrl, ...)

// 在 onPressed 中读取
final sender = _senderCtrl.text;

其他优化方向:

  1. 余额检查:防止发送方透支(需维护账户余额映射);
  2. 交易签名:加入数字签名验证发送方身份;
  3. P2P 网络:多节点同步(需引入网络库);
  4. Merkle 树:高效验证交易存在性;
  5. 动态难度调整:根据出块时间自动调节目标哈希前缀。

六、教育价值:理解区块链本质

这个 Demo 虽小,却完整体现了区块链的三大特性:

特性 实现方式
去中心化 无中心服务器,所有数据本地存储
不可篡改 任一区块数据修改 → 哈希变化 → 后续所有区块失效
透明可验证 所有交易公开,任何人都可运行 _isValidChain() 验证

正如中本聪在比特币白皮书中所言:“我们需要一个基于密码学证明而非信任的电子支付系统。” 本应用正是这一思想的微型体现。


结语:从模拟走向真实

通过这个 Flutter 应用,你不仅编写了一个有趣的工具,更亲手触摸到了区块链的“心跳”——那个不断寻找合适 nonce 的挖矿循环,那条由哈希紧密链接的不可逆链条。虽然它运行在单机之上,但其逻辑与比特币、以太坊等公链一脉相承。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐