如果你听说过比特币但一直没搞懂它到底是怎么运作的,这篇文章就是为你写的。我们不谈炒币、不谈行情,只聊技术——区块链最底层的两块基石:密码学和数据结构。
区块链的核心组件是加密哈希函数(Cryptographic Hash Function)。比特币用的是 SHA-256(Secure Hash Algorithm,256位输出)。
一个合格的加密哈希函数需要满足三个性质:
输入可以是任意长度的任意数据,输出永远是固定长度(SHA-256 输出 256 位)。理论上,输入空间无穷大而输出空间有限(2^256 种可能),碰撞必然存在。但关键在于——你找不到它。
以当前算力,暴力搜索一个 SHA-256 碰撞需要的时间比宇宙年龄还长。所以实际上,H(x) = H(y) 意味着 x = y,哈希值就是数据的"指纹"。
给定哈希值 H(x),无法反推出 x。这有一个经典应用场景——数字承诺(Digital Commitment):
你想预测一场比赛结果,但不能提前公开(怕影响选手)。你可以先把"预测结果 + 一段随机数"的哈希值公开。比赛结束后,你再公布原文,大家一验哈希就知道你没有偷偷改过预测。
那如果输入空间很小(比如"正面/反面"只有2种可能),别人可以穷举所有输入算出所有哈希,然后反查。解决办法很简单——拼接一个随机数,把输入空间"撑大"。
这是比特币特别需要的性质:即使你知道目标,除了暴力搜索,没有捷径。
挖矿的本质是找一个随机数 nonce——它是区块头(Block Header)中的一个 32 位字段。矿工把 nonce 和其他区块头字段拼在一起做 SHA-256:
H(version || prev_hash || merkle_root || timestamp || target || nonce) ≤ target
其中 || 表示字节拼接,target 是难度目标(值越小难度越大)。矿工从 0 开始不断递增 nonce 做哈希,看结果是否 ≤ target。如果 32 位 nonce(约 43 亿种可能)全试完还没找到,就调整 merkle_root(修改 coinbase 交易或交易列表),重新来一轮。
SHA-256 的输出完全不可预测——你改一个比特的输入,输出就面目全非。所以没有任何取巧的办法,只能一个一个试。寻找 nonce 极其困难,验证却只需一次哈希——这就是工作量证明(Proof of Work)的核心。
比特币网络每 2016 个区块(约两周)自动调整一次 target,使全网平均出块时间稳定在 10 分钟。
传统银行开户,你得带着身份证去柜台。比特币的世界里,你只需要在本地生成一对密钥——公钥和私钥。
这是非对称加密的核心思想:
别人用你的公钥加密一条消息,只有你的私钥能解开——这解决了对称加密中"如何安全传递密钥"的难题。
但还有一个问题:怎么证明这条消息确实是你发的? 这就要用到数字签名:
别人可以验证签名的有效性,但无法伪造你的签名。比特币的每一笔转账,本质上就是用你的私钥对交易内容签名,全网节点用你的公钥验证。
关键细节:比特币生成私钥时,必须使用密码学安全的随机源(比如基于物理噪声的硬件随机数生成器,或混合系统熵+键盘输入时间等),否则私钥可能被他人推测出来。
密码学提供了"不可伪造"和"不可抵赖",数据结构提供了"不可篡改"和"可验证"。
普通指针存储的是内存地址。哈希指针存储的是数据的哈希值——它不仅指向数据的位置,还能验证数据是否被篡改。
区块链就是由哈希指针串起来的链表:
[区块0] ← [区块1] ← [区块2] ← [区块3] ← ...
↑ ↑ ↑ ↑
创世区块 prev_hash prev_hash prev_hash
指向区块0 指向区块1 指向区块2
每个区块的头部存着前一个区块的哈希值(称为 prev_hash)。如果有人篡改了区块2的内容,区块2的哈希就变了,区块3里存的 prev_hash 就对不上了。要掩盖这个篡改,就得同时修改区块3、区块4……一直改到最新区块。这在算力上是不可行的。
第一个区块叫创世区块(Genesis Block),它没有前驱,"prev_hash" 是一个约定值(比特币是全是0)。
如果区块链只是一个链表,那要验证某笔交易是否在一个区块里,就得把整个区块的几百笔交易全部下载下来——这对手机钱包这种轻节点来说不可接受。
Merkle 树解决了这个问题。它和二叉树的区别在于:用哈希指针代替了普通指针。
结构如下:
Root Hash (存在区块头里)
/ \
Hash(A,B) Hash(C,D)
/ \ / \
Hash(A) Hash(B) Hash(C) Hash(D)
| | | |
TxA TxB TxC TxD
注意:比特币的 Merkle 树不是严格的二叉树——如果某一层节点数为奇数,会复制最后一个节点来凑成偶数。
**Merkle Proof(默克尔证明)**是 Merkle 树的杀手锏。假设你要验证 TxB 确实在某区块中:
你只需要 O(log n) 个哈希值(而不是整个区块的所有交易),就能验证一笔交易。这就是为什么轻节点(只存区块头,不存交易列表)也能独立验证支付。
每个区块分成两部分:
| 部分 | 内容 | 存在哪里 |
|---|---|---|
| 区块头(Block Header) | 版本号、prev_hash、Merkle Root、时间戳、难度目标、nonce | 全节点和轻节点都有 |
| 区块体(Block Body) | 交易列表 | 只有全节点存 |
这引出了两种节点:
理论上,哈希指针可以构造任何无环的数据结构——链表、树、DAG 都行。但绝对不能用于有环结构,因为会产生循环依赖:A 的哈希依赖 B,B 的哈希又依赖 A,死锁。
这一篇我们讲了区块链的"材料":
下一篇我们把这些零件组装起来,看看比特币这条"链"到底是怎么跑起来的——交易脚本、共识协议、以及 PoW 挖矿的完整流程。
本文整理自个人学习笔记,力求用通俗语言讲清核心概念。如有疏漏,欢迎指正。