你从未听过的区块链骗局:一个隐藏在隐私币BTCP代码深处的阴谋
在区块链行业,各种欺诈事件层出不穷,但 Coin Metrics 最近发现的一起欺诈行为,却从去年三月份一直潜藏至今,该项目打着隐私技术与 zk-SNARKs 零知识证明协议的幌子,却利用这些技术在代码深处埋藏了一个极大的阴谋。
若非Coin Metrics 使用技术手段层层验证,这一骗局恐怕至今仍无人能看破。那么,这个骗局究竟在以怎样的手段来利用最新的这些区块链技术呢?这样的骗局为什么能瞒过这么多区块链领域的技术行家呢?
接下来,请看本文的深度解析:
BitcoinPrivate(BTCP)项目是比特币和 ZClassic(ZCL)的“分叉合并”,旨在为比特币增加 ZClassic 基于 zk-SNARKs 的零知识证明技术的隐私和安全特性。其中,ZClassic 又分叉自 ZCash,由矿工所支持,类似于比特现金(BCH)。
根据 BitcoinPrivate 的官方说明,它的初始代币总量基于当时已发行的比特币(1650 万)、ZClassic(340 万) 以及用于挖矿项目的少量代币(62500)而确定出来,为 2040 万。另外,加上一部分用于挖矿奖励的递减分配代币,跟比特币的总供应量一样,BTCP 的总供应量也限定为 2100 万。
然而,在导入比特币 UTXO(未花费交易输出)数据的过程中,一件诡异的事情发生了:BitcoinPrivate 屏蔽池中神秘地多出了 204 万 BTCP,令初始代币总量高达 2260 万,这与官方白皮书和 BitcoinPrivate 团队所公布的数据完全矛盾。
在这过程中,屏蔽池中有一批代币已经被秘密预挖出来:其中有 30 万 BTCP 似乎正在从屏蔽池转移到交易所,这就相当于为当前流通的 BTCP 额外空投 10% 的代币;除此之外,屏蔽池中还有大约 180 万被预挖出来的 BTCP。
尽管 BitcoinPrivate 名义上是融合 ZClassic 与比特币状态的一次“分叉合并”,但其分叉的基础是 ZClassic 账本数据,而非比特币。
BTCP 的区块链不是一条完全从零挖矿出来的链,而是直接生成了事先协商一致的数千个区块。BitcoinPrivate 从 ZClassic 区块链高度为 272992 的区块处开始分叉,将比特币的 UTXO 数据直接导入到父链 ZClassic 内。导入结束时,基于“矿工自愿贡献计划”,又额外生成了 62500 BTCP。至此,BitcoinPrivate 自己的公链才正式启动。
相应的统计信息如下:
因此,BTCP 的代币数据如下:
这与 BitcoinPrivate 白皮书上的官方数据还是吻合的:
“在分叉完成时,总量为 2100 万的 BTCP 代币中,大约会直接生成 2040 万个。”
此外,分叉后每个区块的挖矿奖励为 1.5625 BTCP,且每挖 21 万个区块奖励均会减半。截止撰稿时,BitcoinPrivate 公链的区块高度为 446997。由于分叉发生在 278458 区块处,因此有 141542 个区块的挖矿奖励为 1.5635 BTCP,另外 26996 个区块的挖矿奖励为 0.78125 BTCP。
据此,我们算出当前 BTCP 的供应总量:
而根据 CoinMarketCap 的统计,BTCP 的循环供应量为 20.525M,这似乎是等于“初始供应量-矿工自愿贡献计划- 初始 ZCL 屏蔽池的 62.5K BTCP”所得出的数值。
为了验证这些数据,我们亲自运行了一个版本号为 1.0.12-1 的 BitcoinPrivate 节点,并使用 RPC 方法 "gettxoutsetinfo" 来调取其公链上的数据,所得结果如下:
在撰写本文时,我们的完整节点所给出的 BTCP 的总供应量为 20.841 M。这就奇了怪了, CoinMarketCap 所统计的数据以及我们根据官方公开数据所计算的结果都不是这个数。到底是哪里出了问题?
为了解释这里的矛盾,我们不得不去一一推敲以下这些可能出问题的地方:
我们的节点没有运行在正确的 BitcoinPrivate 区块链上,有人以某种方式干扰了我们实验节点的数据;
gettxoutsetinfo 代码内存在 bug;
白皮书发布后,挖矿奖励发生了变化,致使我们最初的估算出现错误;
zk-SNARKs 零知识证明协议被黑客破解,使得有人可以在屏蔽池内创建额外的 BTCP 代币;
BitcoinPrivate 项目存在一个隐藏的预挖矿设计
接下来,让我们一一分析,到底那种解释更合理:
我们的节点没有运行在正确的链上?
446997 区块在 BTCP 官方区块链浏览器 btcprivate.org 上的哈希值与我们完全相同,有图有真相:
https://archive.fo/8MTW5
可以排除此项。
gettxoutsetinfo 代码内有 bug?
自 BitcoinPrivate 分叉以来,调取区块链数据的主要函数 GetStats() 从未修改过。
https://github.com/BTCPrivate/BitcoinPrivate/commits/b27c72274922eec86f301c2d1a7078dc038cfad6/src/txdb.cpp
如果这里存在 bug,它必然也会影响到比特币以及衍生自比特币的各种山寨币项目,但我们所运行的比特币节点的数据是与预期相符的。
所以,这一项也可以排除。
挖矿奖励发生变化?
挖矿奖励的执行有着固定的时间表,经过查证,它确实从未进行过修改。
这一项也可以排除。
零知识证明协议(zk-SNARKs)已经被攻破?
如果 Zk-snarks 技术确实被攻破,黑客一定会优先攻击 ZCash,而非 BitcoinPrivate。毕竟,ZCash 相对要值钱多了。
这一项也可以排除。
那么,Bitcoin Private 项目确实存在一个隐藏的预挖矿设计?
是的。
我们的分析如下:
从高度 272992 到高度 278457 的所有 BTCP 区块,都用于导入比特币的 UTXO 数据,攻击有 59188317 个比特币的未花费输出,其总价值为 16891665 BTC。而高度为 278458 的 BTCP 区块则包含有“矿工自愿贡献计划”的 62500 个 BTCP(注:这一项不是隐藏的预挖代币,而是事先公开的开发专用基金)。
上述区块中,每一个区块均含有 1000 个输出,每个输出又对应一个比特币的 UTXO。(也就是说,这 6000 上下的区块声明了将比特币状态导入 ZClassic 所需的 6000 万左右的输出。)这是官方数据所预期的结果。
但奇怪的是,这些 BTCP 区块内还有一些含有 10400 个输出的特殊区快,其中这 400 个额外输出,每一个都价值 50 BTC,而这样的异常区块总共有 102 个。
我们可以用如下的图表直观描述一下:其中橙色线条表示的是将比特币的 UTXO 数据导入到 BTCP 区块链的预期过程,而蓝色线条所表示的则是实际发生的事情。
这样,在导入过程中,我们看到了 102 个超大型区块,其中除了 10000 个预期中的输出之外,每个区块还藏有 400 个额外的输出,且每个额外的输出都价值 50 BTC,这就产生了额外的 102 × 400 × 50 = 2040000 BTCP。
下面这张图清晰地标示出了 BTCP 区块链上的异常区块(请注意:由于 UTXO 大小各异,所导入的每个比特币的区块大小并不相同):
按 UTXO 数量进行对比时,异常区块则呈现出均匀分布:
将上图 274590 到 275017 间的数据放大,便得到下图:
这额外的 2040 万 BTCP,既未在白皮书中声明,又未出现在比特币的 UTXO 数据中,但仍旧被 BTCP 的区块链凭空创造了出来。
目前,屏蔽池内有 1807549 BTCP,而已释放的 UTXO 数据内有 20841921BTCP,使得 BTCP 的代币总数达到22649470,而非官方所公布的20631984。
那么,BTCP 开发团队会承认这事吗?
简单来说,不会。
该团队一再声明: Bitcoin Private 项目不存在任何预挖代币或开发者税。
Bitcoin Private 与 ZClassic 基本上是同一批开发者搞出来,而 ZClassic 之所以要从 ZCash 分叉出来,就是要取消 ZCash 所固有的 20% 创始人奖励。Bitcoin Private 的出发点自然也是想取消创始人税,同时将 BTCP 的发行总量直接空投到比特币 UTXO 数据上。
Bitcoin Private、Bitcoin、Bitcoin Cash 与 Bitcoin Gold 对比图
FAQ:
BTCP 的贡献团队是谁?(链接)
是否会预挖代币或预设创始人奖励?不会
当然,Bitcoin Private 在自己官方的区块链浏览器上肯定不会统计 BTCP 区块链上预挖出来的代币,所以我们称之为隐藏的预挖行为。
这难道就是用 BTCP 创始人口中所说的 “社区从未见过的大型区块链欺诈” 事件?
https://archive.li/2Gw22#selection-439.0-439.69
此外,还存在一个问题,就是我们的节点只找出了官方数据之外的 20 万 BTCP,而非导入数据中所分析出来的全部 204 万 BTCP。
那么,我们尚未发现的 BTCP 又藏到了哪里?
预挖 BTCP 到底是个怎样的事件?
由于 ZClassic 是 ZCash的一个分叉,隐私性相对来说会更好。这就是说,ZClassic 可以把其中一些地址屏蔽掉,让人们无法确定具体的交易地址或交易金额。
但是,当屏蔽池和非屏蔽池交互时,人们就能看到屏蔽池中流入和流出的资金。
在 ZClassic 分叉时,屏蔽池中就只有区区 17K ZCL。而撰写本文时,屏蔽池中则有 180.7 万 BTCP。将屏蔽池和未屏蔽部分相加,可得出:
1.8M(屏蔽池)+ 20.8M(未屏蔽代币总数)= 22.6M BTCP
20.35M(导入自比特币与 ZClassic)+ 2.04M(预挖矿)+ 0.25M(自分叉以来新挖的代币)= 22.6M
从上图可以看出,2018 年 4 月 29 日,隐藏的预挖代币被送到屏蔽地址。7 月 11 日至 8 月 18 日期间,大约有 30 万 BTCP 从屏蔽池内流出,当时,BTCP 的价格在 10 美元到 3 美元之间。如果这些代币在市场上公开交易,就会获得 100 万到 300 万美元的利润。
你能找出下图中 BTCP 被送屏蔽池的那个时间点吗?
从上图可以看出,2018 年 7 月到 8 月,这个地址接收了屏蔽池输送过来的 1360 万 BTCP。在预挖矿之前,更多的 Bitcoin Private 被送入屏蔽池中,并且有太多的 Bitcoin Private 有待于矿工挖矿(挖 Bitcoin Private 必须经过屏蔽池)。
因此,这极有可能来自于预挖矿。有趣的是,大多数预挖出来的 BTCP 并没参与交易,而是存储在屏蔽池内。
关于此次分叉,另一条比较有趣的线索就是其效率:在 BTCP 区块链上,只有 15% 的代币被“激活”。这就意味着,这笔预挖出来的 BTCP,最终将占据其供应总量的很大一部分。
自分叉以后,Bitcoin Private 声称链上只有 2.55M ZCL 与 572K BTC,也就是非预挖的代币总量仅为 3.12M BTCP。而目前从屏蔽池内流出的预挖 BTCP 数量则有 30 万左右,占分叉后 BTCP 总量的 9.5%。
换句话说,在分叉后的钱包中,每 10 个 BTCP 里面就有 0.95 个来自于预挖。
这么大的事竟无人能察觉?
Bitcoin Private 的主网于 2018 年 3 月上线,这就是说 2100 万货币总量的说法应当在数月前就已经破产了。因为,只要写出一些共识算法,检查一下导入过程中不能该存在的代币数据,肯定有人能发现其中有鬼。
但为什么这么大的问题,始终却无人察觉出来呢?
里面可能有两个原因:首先,很多人并不熟悉验证比特币UTXO导入过程,且验证力度也弱;其次,Bitcoin Private 继承了比特币的供应量检查(supply checks),这是一个用于审查比特币公司代币输出的方法——但并没有察觉欺诈行为,因为 BTCP 的挖矿方法采用的是 UTXO 数据导入。
不合理代币总量检查
鉴于 Bitcoin Private 代币来自各个不同的地方,在这里使用比特币代币供应-验证模型不太合适。在比特币中,代币总数是以每个区块为基础进行审查的,根据比特币处于预定于减半计划中所处的位置,新挖掘的代币数量(比特币公司的代币输出)不超过50/25/12.5/6.25。在比特币协议中,并没有内置用于验证模型中的自上而下的代币供应量审计。挖掘代币的难度、保证减半计划顺利进行的难度以及每个区块coinbase审查,都要考虑到这一点。
在 Bitcoin Private 中,大部分代币并不是来自于挖矿,而是来自于比特币 UTXO 导入和现有的 ZClassic UTXO 数据。由于比特币 UTXO 导入检查工具力度较弱,Bitcoin Private 也缺乏一个真正的代币供应审核方法。
为了捕捉诈骗行为,我们可以通过观察代币的实际流动踪迹来实现。Bitcoin Private 不得不相信 UTXO 导入和挖矿过程都是按照开发人员的说法完成的。根据 Peter Todd 的建议,我们运行一个完全验证,并删除了检查点,但是额外的代币发行超出了节点执行验证检查的范围,因此,对于节点运行者来说,结果并不是太明显。由于代币发行是在协议范围外完成的,因此,完全验证节点也不能轻松的捕捉到这些额外的发行。这就需要提取数据,然后运行代币供应量检查。
弱化 UTXO 导入验证
Bitcoin Private 团队发布了一组用于审核导入区块的文件,除此之外,还发布了一组用于重新创建这些文件的工具。每个文件都包含了单个导入区块的内容(10000 个交易,每个交易都需要导入一个比特币 UTXO)。由于发布的文件表示了正确的 UTXO 数据转储,人们审核这些文件并确保共识代码不会发现任何问题。对于每个导入区块,共识代码检查该区块包含的 10000 个交易,并且,每个交易的第一个输出要与预期的比特币值和脚本相匹配。但是,它并没有检查区块中是否有其他额外的输出,这样一来,这些额外的代币就无法进行完整性检查。
https://github.com/BTCPrivate/BitcoinPrivate/pull/27
添加这些检查的拉推请求尽管包含了很多共识代码,但并没有收到任何评论。除此之外,拉推请求的名字并没有反映提议变更的重要性。
只有导入区块位于最后一个已知检查点之后(或完全禁用检查点),这些检查才可以运行。由于导入过程的检查点在分叉 3 天后就添加了,因此它们只能在导入过程中或导入之后,由运行完整节点的开发人员或禁用检查点的开发人员来运行(默认情况下,检查点是运行的)。
这一案例研究可以说明:通过运行完全验证节点,并审核由这些节点所生成的数据,我们就可以检查代币总数是不是跟官方说法一致,而非一味地信任开发团队的官方数据,或是一些所谓的计算公式。
原文:
https://coinmetrics.io/bitcoin-private/