当人们谈论区块链时,常常会问到一个问题:“它到底使用了什么数据库?” 对于像比特币这样相对简单的区块链,答案或许可以简化为一种键值存储,但对于以太坊这个复杂的、可编程的区块链世界来说,答案则要深刻和有趣得多,以太坊并没有使用我们传统意义上理解的、像MySQL或PostgreSQL那样的关系型数据库,它的“数据库”是一个由多种技术精心组合而成的、专为去中心化环境设计的独特状态存储系统。
以太坊的“数据库”核心是一个分布式、持久化的键值存储数据库,但它的巧妙之处在于,这个数据库的数据结构和访问方式是由以太坊虚拟机(EVM)和其共识规则严格定义的。
下面,我们将深入探讨构成以太坊状态存储的几个关键组成部分。
核心概念:状态树(State Tree)
要理解以太坊的存储,首先要理解“状态”是什么,以太坊的状态,指的是在区块链的任何一个给定时间点,整个网络中所有账户的集合及其余额、代码、存储等信息的快照,为了高效地管理和查询这个庞大的状态,以太坊采用了Merkle Patricia Trie(MPT)数据结构,也就是我们常说的状态树。
- 键值对:状态树本质上是一个巨大的键值数据库,这里的“键”是账户地址的哈希值(20字节),而“值”是该账户所有信息的编码(包括余额、nonce、代码根、存储根等)。
- 树形结构:MPT是一种将所有键值对组织成树形结构的数据结构,每个节点代表一部分数据,通过从根节点开始,根据键的路径一步步向下查找,最终可以快速定位到任何一个值。
- Merkle特性:这种树结构最大的特点是,任何微小的数据变动都会导致从该节点到根节点的所有哈希值发生改变,这个根节点的哈希值,也就是状态根(State Root),会被打包进每个区块头中,这使得任何人都可以高效地验证一个区块所记录的状态是否真实可信,是实现轻客户端和状态同步的关键。
以太坊的“数据库”不是一个单一的数据库文件,而是一套以状态树为核心逻辑的数据组织方式。
具体实现:Geth与LevelDB
在以太坊的客户端实现中,最著名的就是Go语言实现的Geth(Go-Ethereum),Geth客户端将上述状态树的逻辑落地到了一个具体的数据库引擎上,这个引擎就是Google的LevelDB。
- 为什么是LevelDB?
- 高性能:LevelDB是一个由Google开发的、快速、轻量级的键值存储库,它为持久化存储提供了非常高的读写性能,这对于需要频繁更新状态和执行交易的区块链网络至关重要。
- 嵌入式:LevelDB是一个嵌入式数据库,它不需要独立的服务器进程,可以直接集成在Geth应用中,非常适合以太坊这种对资源有一定要求的客户端。
- 有序存储:LevelDB会按键的字典序来存储数据,这与MPT树需要按路径遍历的特性非常契合。
在Geth中,状态树、交易树、收据树这三棵核心的MPT树,其底层数据都是持久化存储在LevelDB中的,当你运行一个Geth全节点时,你电脑上的geth/chaindata目录里存放的就是这个LevelDB数据库,它记录了从创世区块至今的所有历史状态。
其他数据存储
除了核心的状态数据,以太坊还需要存储其他类型的信息,这催生了其他类型的“数据库”或存储结构:
-
区块链数据(区块头与 Bodies):
- 这部分数据,包括区块头和包含交易及叔块的区块体,通常存储在更简单的文件系统中,Geth默认将它们存储在

- 这部分数据,包括区块头和包含交易及叔块的区块体,通常存储在更简单的文件系统中,Geth默认将它们存储在