一、 MetaMask 的后端是用 Postgres 吗?
首先要明确:MetaMask 本身是一个“非托管钱包”(Client-side)。这意味着你的私钥和大部分核心逻辑运行在浏览器插件或手机 App 里。
但是,MetaMask 背后的支撑基础设施(Infrastructure),比如其母公司 Consensys 运行的 Infura(MetaMask 默认的 RPC 节点服务)以及 MetaMask Portfolio(资产看板),大规模使用了 PostgreSQL。
- Infura 的元数据管理:Infura 每天处理数千亿次请求,它需要记录用户的 API Key 权限、流量配额、节点状态等。这些高度关联、对准确性要求极高的管理数据,主要存储在 Postgres 中。
- 资产看板与索引器(Indexer):当你打开 MetaMask 看到所有链的历史交易记录时,这些数据不是现从区块链上查的(那太慢了),而是由后端索引器抓取并存入数据库的。在这些索引器的后端架构中,Postgres 几乎是标配。
- Consensys 的官方推荐:作为 MetaMask 的开发者,Consensys 在其多个开源项目和内部教程中,都将 Go + Postgres 作为推荐的 Web3 后端技术栈。
二、 JSONB 到底是不是选用 Postgres 的最有力理由?
是的,JSONB 确实是 Web3 后端转向 Postgres 的“杀手锏”理由。
在 Web3 场景下,JSONB 解决了两个极端矛盾的问题:区块链数据的“极其杂乱”与金融业务对“极其严谨”的要求。
1. 为什么 JSONB 在 Web3 里这么香?
区块链上的数据(比如 Transaction Receipt 交易回执)结构非常深且不固定:
- 有的交易有 2 条日志(Logs),有的有 50 条。
- 不同的智能合约返回的
Metadata格式五花八门。
如果是传统 SQL:你得为每一种可能的字段建表,这简直是噩梦。 如果是 NoSQL (MongoDB):存起来爽,但如果你想跨表查“某个用户在 A 链的所有转账”,或者想做复杂的财务报表,查询性能和数据一致性会让你抓狂。
Postgres 的 JSONB 方案:
你可以在一张结构化的 transactions 表里,留一个 raw_data 字段为 JSONB。
- 你可以直接用 SQL 语句查询 JSON 里的内容:
SELECT * FROM transactions WHERE raw_data->>'status' = 'success'; - 你甚至可以给 JSON 里的某个 key(比如
from_address)创建索引。 - 结论:它让你在享受 SQL 严谨性的同时,拥有了 NoSQL 的扩展性。
三、 除了 JSONB,Postgres 还有哪些让 Web3 开发者无法拒绝的理由?
如果说 JSONB 是“最吸引人”的理由,那么下面这几点则是保证系统“不出错”的底线:
1. 解决“双花”与“重复处理”的终极武器
作为后端中继器(Relayer),最怕的是同一笔跨链交易处理了两次(给用户发了两次钱)。
- Postgres 的解决方案:唯一索引 (Unique Index)。
- 你可以设置
UNIQUE(chain_id, tx_hash, log_index)。 - 哪怕你的 Go 程序因为高并发或网络抖动,有两个协程同时试图处理同一笔交易,Postgres 也会在数据库层锁死,只有一个人能写进去。这是分布式系统里最简单也最可靠的“锁”。
2. 与 Go 语言的“原生感”
Go 语言的 struct 标签和 Postgres 的字段映射非常完美。使用 pgx 驱动,你可以直接把一个 Go 的 Map 或 Struct 塞进 JSONB 字段,取出来时又能自动反序列化。这种开发体验极大地减少了后端代码的 Bug。
3. 应对海量“地址”的索引能力
区块链地址是长字符串(0x...)。Postgres 针对长字符串的 B-tree 索引 优化得极其出色。当你有几千万个地址的往来记录时,Postgres 的查询响应速度通常比 MongoDB 更快且更稳定。
4. 时序数据的平滑过渡
Web3 经常需要展示代币价格走势图。
- 如果你用 MongoDB,你可能需要再引入一个 InfluxDB。
- 如果你用 Postgres,你只需安装 TimescaleDB 插件。同一个数据库,既存账户余额,又存价格 K 线。
总结笔记
JSONB 是最显性的理由:它解决了 Web3 数据结构不确定的痛点,让 Go 开发者可以灵活地存储和检索区块链原始数据。
ACID 事务是潜意识里的理由:它保证了在处理“钱”的业务时,不会因为程序意外中止而产生坏账。
对 Go 后端开发者的启示: 如果你正在写 MetaMask 的后端或跨链桥:
- 用 Postgres 做主库(存余额、存交易、存地址映射)。
- 用 JSONB 存那些从链上抓下来的、结构不固定的
Receipt和Logs。 - 用 Redis 做缓存(存当前的 Gas 费、代币即时价格)。
- 用 Go (pgx 驱动) 作为粘合剂,把这一切连接起来。
这个组合是目前 Web3 后端领域里最稳健、最不容易出错的“黄金搭档”。