# 比特币为什么需要 6 个区块确认才会被认为难以篡改？

By [Simon 写字的地方](https://paragraph.com/@simon-2) · 2024-09-10

---

一个困扰多年的问题
=========

2016 年，我刚加入区块链行业，当时在 imToken 做钱包就遇到了一个问题：

> ### **_交易为什么需要 6 个区块链确认才会被认为难以篡改？_**

得到的比较笼统的回答一般是，这样做矿工篡改的成本过高。这当然是一个正确的答案，但却过于表面。

最近在重读《精通比特币》第三版，这是去年年底最新修订的版本，看到书中提及了这一内容，所以单独拿出来说说。

6 源于 11
-------

首先我们要明确两个概念：

1.  区块高度：告诉我们在该区块之前有多少个区块；
    
2.  确认：代表区块深度，即在该区块之后已经存在多少区块，表明改变该区块中任何交易的**难度**。
    

![](https://storage.googleapis.com/papyrus_images/02581a7f5aa29e115e3dd21a68fab5f6d5063c8790bd2fe714fb1b7212732ace.png)

我们通过 `getblockhash` 命令，从 bitcoin core 的 API 拉取区块信息的时候会得到如下信息

    {
        "hash": "0000000000002917ed80650c6174aac8dfc46f5fe36480aaef682ff6cd83c3ca",
        "confirmations": 651742,
        "height": 123456,
        "version": 1,
        "versionHex": "00000001",
        "merkleroot": "0e60651a9934e8f0decd1c[...]48fca0cd1c84a21ddfde95033762d86c",
        "time": 1305200806,
        "mediantime": 1305197900,
        "nonce": 2436437219,
        "bits": "1a6a93b3",
        "difficulty": 157416.4018436489,
        "chainwork": "[...]00000000000000000000000000000000000000541788211ac227bc",
        "nTx": 13,
        "previousblockhash": "[...]60bc96a44724fd72daf9b92cf8ad00510b5224c6253ac40095",
        "nextblockhash": "[...]00129f5f02be247070bf7334d3753e4ddee502780c2acaecec6d66",
        "strippedsize": 4179,
        "size": 4179,
        "weight": 16716,
        "tx": [
            "5b75086dafeede555fc8f9a810d8b10df57c46f9f176ccc3dd8d2fa20edd685b",
            "e3d0425ab346dd5b76f44c222a4bb5d16640a4247050ef82462ab17e229c83b4",
            "137d247eca8b99dee58e1e9232014183a5c5a9e338001a0109df32794cdcc92e",
            "5fd167f7b8c417e59106ef5acfe181b09d71b8353a61a55a2f01aa266af5412d",
            "60925f1948b71f429d514ead7ae7391e0edf965bf5a60331398dae24c6964774",
            "d4d5fc1529487527e9873256934dfb1e4cdcb39f4c0509577ca19bfad6c5d28f",
            "7b29d65e5018c56a33652085dbb13f2df39a1a9942bfe1f7e78e97919a6bdea2",
            "0b89e120efd0a4674c127a76ff5f7590ca304e6a064fbc51adffbd7ce3a3deef",
            "603f2044da9656084174cfb5812feaf510f862d3addcf70cacce3dc55dab446e",
            "9a4ed892b43a4df916a7a1213b78e83cd83f5695f635d535c94b2b65ffb144d3",
            "dda726e3dad9504dce5098dfab5064ecd4a7650bfe854bb2606da3152b60e427",
            "e46ea8b4d68719b65ead930f07f1f3804cb3701014f8e6d76c4bdbc390893b94",
            "864a102aeedf53dd9b2baab4eeb898c5083fde6141113e0606b664c41fe15e1f"
        ]
    }
    

这其中有一个 `mediantime` 字段，我们称之为「中位时间」- MTP。该「中位时间」是从（该区块的）之前 11 个区块计算得到的中位时间。

为什么要使用中位数？
----------

中位数具有更好的「抗操纵性」，它是统计学上用于测量数据集中趋势的一个稳健估计值，特别适合处理含有异常值（outliers）的数据。**相比于平均值（容易受到极端值的影响），中位数只关心排序后最中间的值，因此少量极端值（时间戳被操控的区块）不会显著改变结果**。

为什么是 11？
--------

首先如果计算中位数，那么最好选择一个「奇数」，奇数的好处是中位数始终是一个确定的值，因为可以准确地取中间的那个值（比如第 6 个区块），**避免了偶数情况下取两个中间值再平均的复杂性**。

而选择 11 个区块的原因与中位数的特性有关，因为它能很好地处理小样本中的极端值，同时保持计算的简便性。

简单来说就是它**足够小以保持计算效率，同时又足够大确保抗操纵性：**

*   足够大：选择较少的区块（比如 3 个、5 个）可能会使中位数过于容易受到单个矿工的操纵；
    
*   足够小：如果选择更多的区块（比如 21 个、31 个），虽然抗操纵性会更强，但计算复杂度和资源消耗也会增加，效率降低。
    

为什么是 6？
-------

之前我们谈到，中位数是将数据排序后，选择中间位置的那个数值。而在 11 个区块的情况下，中位数是第 6 个区块的时间戳（按照时间戳大小排序后）。

要改变中位数的值，矿工至少需要控制超过一半的区块。因为中位数是基于排序后的位置值决定的，改变排序的多数才能影响最终的中位数。 💡 在 11 个区块的情况下：

*   如果矿工只控制 5 个区块，这些区块的时间戳只能影响排序的前半部分，但无法影响中位数（第 6 个位置）。
    
*   如果矿工控制了 6 个区块，他们就能确保排序后的中位数被自己的区块所决定，从而对整个链的时间戳产生影响。
    

一个例子
----

我们有 11 个区块，假设这些区块的时间戳如下（单位是时间）：

    区块 1: 1628000000
    区块 2: 1628000600
    区块 3: 1628001200
    区块 4: 1628001800
    区块 5: 1628002400
    区块 6: 1628003000
    区块 7: 1628003600
    区块 8: 1628004200
    区块 9: 1628004800
    区块 10: 1628005400
    区块 11: 1628006000
    

现在，我们将这些时间戳从小到大进行排序（这里时间戳已经是按时间顺序递增的）：

    [1628000000, 1628000600, 1628001200, 1628001800, 1628002400, 
     1628003000, 1628003600, 1628004200, 1628004800, 1628005400, 1628006000]
    

在这个排序列表中，第 6 个区块的时间戳是 **1628003000**，这是过去 11 个区块的中位时间，也就是 MTP。

**现在，假设一个矿工控制了一些区块，并试图通过篡改时间戳来影响中位数。**

### **情况 1：矿工控制 5 个区块**

假设矿工控制了 **区块 1、2、3、4、5**，并且他们想通过操控这些区块的时间戳来改变 MTP。为了做到这一点，矿工将这些区块的时间戳篡改为一个非常小的值，假设为 **1627000000**。

篡改后的时间戳如下：

    区块 1: 1627000000
    区块 2: 1627000000
    区块 3: 1627000000
    区块 4: 1627000000
    区块 5: 1627000000
    区块 6: 1628003000
    区块 7: 1628003600
    区块 8: 1628004200
    区块 9: 1628004800
    区块 10: 1628005400
    区块 11: 1628006000
    

排序后的时间戳为：

    [1627000000, 1627000000, 1627000000, 1627000000, 1627000000, 
     1628003000, 1628003600, 1628004200, 1628004800, 1628005400, 1628006000]
    

你可以看到，虽然前 5 个区块的时间戳被篡改得很低，但中位数仍然是 **1628003000**，因为第 6 个区块的时间戳没有被矿工控制。

### **情况 2：矿工控制 6 个区块**

现在，假设矿工控制了 **区块 1、2、3、4、5、6**，并且他们同样篡改这些区块的时间戳为 **1627000000**。篡改后的时间戳如下：

    区块 1: 1627000000
    区块 2: 1627000000
    区块 3: 1627000000
    区块 4: 1627000000
    区块 5: 1627000000
    区块 6: 1627000000
    区块 7: 1628003600
    区块 8: 1628004200
    区块 9: 1628004800
    区块 10: 1628005400
    区块 11: 1628006000
    

排序后的时间戳为：

    [1627000000, 1627000000, 1627000000, 1627000000, 1627000000, 
     1627000000, 1628003600, 1628004200, 1628004800, 1628005400, 1628006000]
    

此时，新的中位数是 **1627000000**（第 6 个位置的时间戳），这是矿工篡改的时间戳。因此，通过控制 6 个区块，矿工成功操纵了 MTP。

所以，如果矿工控制了 6 个区块，他们就能保证至少有 6 个区块的时间戳是他们自己设定的。这样，无论剩余 5 个区块的时间戳如何，矿工控制的区块一定会影响或决定中位数。

总结
==

要想了解为什么需要 6 个区块确认，就要了解为什么选择 11 作为「中位时间」校验。因为 11 相较于其他数字，具有足够的抗操纵性和高效性，这是一个权衡后的神奇数字。而如果想操纵 11 个区块的中位数，则需要满足 6 个确认才可以，这是一个简单的数学问题。

---

*Originally published on [Simon 写字的地方](https://paragraph.com/@simon-2/6)*
