Flutter 到区块链:分层架构与交互全流程

本文从移动端工程视角,说明 Flutter + 原生 + 密码学库(如 Trust Wallet Core)+ 节点 RPC + 区块链 在用户完成一笔链上交易时的典型分工与数据流。适用于自托管钱包、DEX 集成等场景的架构理解(具体产品实现可能有网关、风控等差异)。

1. 先厘清三件事

  1. 区块链节点不会直接和你的手机 App「长连接握手」完成业务;App 通常通过 HTTPS 上的 JSON-RPC(或 REST)远程节点通信。
  2. Trust Wallet Core 一类库,主体多为 C++,负责 地址派生、交易构造、数字签名、按链协议序列化不负责替你选公共节点或发起 HTTP(由宿主 App 实现)。
  3. Flutter 负责 UI 与业务状态;涉及 私钥、签名 时,常见做法是放到 iOS/Android 原生(Keychain / Keystore + JNI),再通过 MethodChannel 与 Dart 通信。

2. 分层总览:谁做什么

层级 典型技术 职责
表现层 Flutter Widget 表单、确认弹窗、加载态、结果页
业务 / 状态 Bloc / Riverpod / Provider 等 参数校验、组装请求模型、调用 Channel
跨端桥 MethodChannel / Pigeon / FFI Dart ↔ 原生类型与异步传递
原生 Kotlin / Swift 安全存储、调 TWC 绑定、HTTP 客户端、证书策略
密码学 / 链协议 Trust Wallet Core(C++ .so / xcframework) 未签名交易 → 签名 → 原始交易字节 / hex
网络 OkHttp / URLSession / Dio RPC:读 nonce、余额、estimateGas;写 eth_sendRawTransaction
公链节点集群 验证交易、广播、mempool、出块

核心结论:「上链」在工程上 = 库内完成签名 + 网络层把已签名交易发给节点


3. 架构图:从界面到链

flowchart TB
  subgraph UI["表现层"]
    F["Flutter Widget\n按钮、金额、链选择、确认弹窗"]
  end

  subgraph VM["业务层"]
    B["Flutter 业务逻辑\n校验、状态机、组装 DTO"]
  end

  subgraph Bridge["跨端桥"]
    C["MethodChannel / Pigeon"]
  end

  subgraph Native["原生层"]
    N1["Kotlin / Swift\nKeychain / Keystore、权限"]
    N2["Trust Wallet Core\n(C++ 动态库)\n交易体 + 签名"]
  end

  subgraph Net["网络层"]
    H["HTTP 客户端"]
    RPC["节点 RPC\nJSON-RPC / REST"]
  end

  subgraph Chain["区块链"]
    BC["共识与出块"]
  end

  F --> B --> C --> N1 --> N2
  N2 -->|"signed tx"| N1
  N1 --> H --> RPC --> BC

4. 主流程时序图:用户点击「确认」之后

以下为 签名在原生、RPC 也由原生(或统一网络层)发起 的常见形态,便于统一钉证书与审计日志。

sequenceDiagram
  autonumber
  participant U as 用户
  participant W as Flutter UI
  participant B as Flutter 业务层
  participant CH as MethodChannel
  participant N as 原生
  participant TWC as Trust Wallet Core
  participant RPC as 节点 RPC
  participant BC as 区块链

  U->>W: 点击确认交易
  W->>B: 提交 to / amount / chainId 等
  B->>B: 校验与组装参数

  B->>CH: invokeMethod(signAndSend / buildTx, args)
  CH->>N: 传递到原生

  N->>N: 解锁密钥材料(生物识别 / PIN)
  N->>RPC: 读链:nonce、fee、余额等
  RPC-->>N: 返回值

  N->>TWC: 构造未签名交易并签名
  TWC-->>N: 已签名交易 hex / bytes

  N->>RPC: 写链:eth_sendRawTransaction 等
  RPC->>BC: 广播
  BC-->>RPC: 返回 tx hash
  RPC-->>N: tx hash

  N-->>CH: { txHash, error? }
  CH-->>B: Future 完成
  B-->>W: 更新 UI
  W-->>U: 展示哈希 / 区块浏览器

步骤解读(与上图序号对应)

  1. 用户操作:仅在 UI 层。
  2. 业务层:做产品规则校验(限额、格式),不碰私钥明文。
  3. Channel:把「意图」和「非敏感参数」交给原生;不要把私钥字符串在 Dart 里传来传去
  4. 原生:从安全存储取密钥或触发系统认证。
  5. 读链 RPC:例如 EVM 链上需要先拿 nonce、估算 gas;这些请求 与签名无关,走 HTTP 即可。
  6. TWC:输入链类型、账户、目标交易内容,输出 签名后的原始交易
  7. 写链 RPC:将 已签名交易 发给节点;节点再进入 mempool。
  8. :矿工/验证者打包,产生确认数。

5. 变体:原生只签名,Flutter 发 RPC

部分团队会让 Dart 层用 Dio 直接调 Infura / Alchemy / 自建节点,原生 MethodChannel 只返回 signedHex

sequenceDiagram
  participant B as Flutter
  participant CH as MethodChannel
  participant N as 原生
  participant TWC as Trust Wallet Core
  participant RPC as 节点

  B->>CH: signOnly(unsignedTxParams)
  CH->>N: 
  N->>TWC: 签名
  TWC-->>N: signed hex
  N-->>CH: 
  CH-->>B: signed hex

  B->>RPC: eth_sendRawTransaction(signedHex)
  RPC-->>B: tx hash

注意:私钥仍应只在原生 + TWC 边界内使用;Dart 侧只拿 已签名 的十六进制串,不要把助记词传到 Flutter。


6. 数据流简图:字节往哪走

flowchart LR
  subgraph in["输入"]
    A1["用户输入\n地址、金额"]
    A2["链与合约参数\nchainId、ABI、nonce"]
  end

  subgraph twc["Trust Wallet Core"]
    S["编码 + 签名\n→ raw transaction"]
  end

  subgraph out["对外"]
    H["0x… 已签名交易"]
    TX["交易哈希"]
  end

  A1 --> S
  A2 --> S
  S --> H
  H -->|"HTTPS JSON-RPC"| RPC["节点"]
  RPC --> TX

7. Trust Wallet Core 与「和链交互」的关系

  • 开发语言:核心为 C++;Android 为 libTrustWalletCore.so,iOS 为 xcframework;通过 Kotlin / Swift 绑定 调用,而非在 App 内用 JS 实现核心链逻辑。
  • 和链的交互方式
    • 库内部:密码学、交易结构、签名算法、各链差异。
    • 库外部:你的 App 用 RPCsigned transaction只读请求(余额、nonce)发到节点;协议多为 JSON-RPC(如以太坊系)。

因此:「与区块链交互」在实现上 = RPC 上的读写TWC 负责产生可被链接受的那串字节


8. 安全与工程要点(简历与面试可提)

  • 私钥与助记词:优先 Keychain / Keystore / 硬件模块;Dart 内存尽量不出现明文。
  • Channel 传参:传 交易参数、链 ID、签名结果,不传私钥。
  • RPC 端点:生产环境常配合 证书钉扎、代理、自有网关,防止中间人篡改 sendRawTransaction 的返回。
  • 重放与链切换:正确设置 chainId(EIP-155),避免跨链重放。

9. 与「交易所托管」模式的对比(扩展)

若业务是 CEX 托管钱包,时序里往往在 用户确认 之后增加 你们服务端:风控、限额、内部记账,再由服务端或专用签名机与链交互。此时上图中的 RPC 可能变为 先调业务 API,与纯 自托管 + TWC 的图不同。理解分层后,可按实际产品替换「RPC 前」的一跳。


10. 小结

问题 答案
Flutter 怎么「上链」? 多数情况下 不直接上链,而是 调原生签名 + HTTP 调节点 RPC
TWC 做什么? 交易构造与签名(C++ 库)。
链从哪里来? 远程节点返回区块与收据;广播即节点接受你的 sendRawTransaction
JS 是不是核心? 不是;可选 WASM/TS 绑定,核心仍是 C++。

文档为通用架构说明,便于学习与简历技术表述;具体 App 的网关、风控、多签等需以实际系统为准。