2900万,没了!——虚拟币世界的真实战斗

1月3日,比特币价格再创新高,最高超过3.4万美元。比特币的涨跌风云让虚拟币家喻户晓,由于使用了区块链技术,包括比特币等虚拟币展现了它们的安全性。但是,虚拟币交易背后仍暗藏危机,即算力超过51%情况下的“双花”攻击。本文源于一个真实案例,AE虚拟币交易中发生一场关乎2900万元的战斗—— 一名“矿工”发动了“双花”攻击,价值2900万的AE币消失了!另一方管理员围追堵截,紧急补救,残酷的战斗后最终结局如何?到底什么是“双花”攻击?作者将从电子货币的基础概念讲起,帮读者厘清虚拟币背后的运作原理,并通过对这次交易的复盘讲述虚拟世界中的战斗始末。现实中的云淡风轻,与虚拟世界的腥风血雨形成了鲜明对比。

撰文 | 徐晓

我们生活在网络时代,虚拟的网络和现实世界相互交互:读书、买票、购物......当然,还有钱:真实的钞票(人民币)和虚拟的货币(虚拟币)。

说到虚拟币,人人都知道比特币。但除比特币外,还有很多种虚拟币,AE就是其中的一种。

刘洋是一个虚拟币项目的观察员。他创立的AEknow,是AE币对应的维护平台,专门对AE及其与其他货币的交易进行记录,以便各个网上交易所或者交易者查询,也便于监察交易和技术异常。

不错,刘洋就是AEknow的司令官。

他平时的工作,就是看看平台是否正常、市场是否稳定。因为绝大多数的工作都是计算机自动执行的,他平时很闲。

12月7日中午,刘洋像往常一样在网上瞎逛。中午的太阳暖洋洋的,论坛里也是云淡风轻,刘洋正在跟人吹水。

突然,大事不好!有人发动了一次“双花攻击”,从AE币的交易所偷走了2900万元!

2900万!没了!

谁偷了这2900万元?他是怎么干的?交易所能把钱追回来吗?

在虚拟币的世界里,真正的战斗开始了。

为了弄清战斗过程,让我们从基本的概念讲起。

1电子货币与双花攻击

电子货币并不是新概念。上了年纪的人应该都记得磁卡电话,磁卡上记了充值的钱数,就代表一种电子货币。当你用磁卡打完电话,通信系统会扣除通信费,再将剩余的钱数写回磁卡。虽然磁卡本身不是货币,但是,磁卡被使用的过程,就跟花真的钱是一样的。

那么,跟真钱相比,磁卡会有什么特别的问题呢?那就是当系统有漏洞时,一份钱可以当两份钱花!因为花了两次,所以叫“双花”(double spending)。

最早的卡式公用电话(用电话卡打电话)就出现过导致双花的漏洞。[1]通过拷贝电话卡磁条上的信息,不法人员就可以造一张假卡。而假卡上的金额信息,就像是卡上的钱没有被使用过一样;实际上,这笔钱已经在真卡上被扣除过了。更有甚者,真卡只是用来拷贝,假卡则无数次被满额使用——这已经不是双花,而是无限花了。

数字世界的最大问题,就是信息可以被拷贝而不失真。电子货币的记录,只是数字世界的一种信息而已。这样就面临一个重大问题:可以造假钱!一旦成功,就可以双花,真爽!

所以,货币电子化的过程,一直都要解决双花问题。

2数字签名

要解决“双花”,第一步,是实现数字签名。

什么是数字签名?它是一种对数据进行加密的技术手段。

在数字世界里,加密和解密都是对字符串进行运算变化。加密就是把要传送的信息(明文)和加密密钥(也是一串字符)一起进行某种运算,变成密文。显然,解密密钥就是能把密文变回明文的运算所需要的字符串。

加密密钥和解密密钥可以相同,这就是对称加密;也可以不同,这就是非对称加密。非对称的加密系统通常不是用来保密,而是用来保证数据的真实性、完整性和不可抵赖性——数字签名就是干这个用的。它是通过加密运算获得的、比较短的一串字符,通常附缀在一段文件数据信息的后面。

数字签名的真实性,将确保数据的发出者就是签名者本人;其完整性,则保证数据没被改动过;不可抵赖性,则保证如果发出者本人在事后改动数据,就会反映到数字签名中,使其更改行为露馅。

数字签名如何保证这三个性质呢?

信息的发出者将解密密钥公之于众(“公钥”),而将加密密钥自己保留(“私钥”)。因为除了信息发布者谁也没有加密密钥,别人根据他发出的数字签名和公钥,只要解密出规范的符合其文件的结果,就说明这个数据肯定来自于他,且未被别人更改过。容易理解,这就保证了数据的真实性和完整性。

如何保证数据没有被信息发布者本人改过呢?这是因为他并不能控制数字签名的具体结果。数字签名依赖于一类特殊的数学运算——散列函数映射,也就是币圈的人一天到晚讲的“哈希”。哈希运算把加密密钥和你传送的数据一起加密产生一个新的字串,叫做哈希字串,简称“哈希”或者“哈希值”。哈希值的特点是,只要文件数据稍微改一点点,哈希值就会出现剧烈变化。这个特点非常重要,使得数据发布者本人也没法自己改动而不认账。

那么实现了数字签名,使用电子货币的每一次消费就可以有不同的数字签名产生,这样看来是可以有一定办法对付“双花”了。

3虚拟币

2000年开始,由于互联网游戏的急速发展,各个网游公司都开始发行自家的虚拟的游戏币。这些游戏币往往需要玩家充值,用真金白银来买;同时玩家们也可以通过私下交易,获得虚拟的游戏币,并用虚拟游戏币来买游戏中的道具,升级打怪。这些游戏公司之间的游戏币就像真实世界的货币一样,出现了彼此间的交易结算价格;出于挣钱需要,有的游戏公司加大了游戏币发行数量,结果还出现了通胀。

因此,就有学者和IT从业者开始研究,是否可以真的“发行”一种虚拟的网络电子货币,除了能抵御双花攻击,还没有发行中心控制,这样就能合理抵御货币通胀。这种没有中心控制的机制,叫“去中心”,就是货币发行和交易都不依赖于某个权威的第三方(比如银行),而是由平台上的交易人和“铸币”人共同维护和交易。

2007年,有位化名“中本聪”的人(或者集团)发了一篇网文,结合一系列学者的设想,设计了一种去中心的网络电子货币,就是我们现在称的虚拟币的最早一种——比特币。[2]并且,从设计开始,就要求整个系统有抵御双花攻击的功能。

数字货币的交易如图一所示。一个交易(transaction)记录包括了买者的公钥(Public Key),和一个数字签名(Signature)。这个数字签名是通过上一次记录加上买者公钥的信息,以卖者的私钥为基础进行哈希运算得到的。一个数字货币从发行开始,会将每次交易记录在记录表中。历次交易的信息都是可以验证(verify)的:根据表中上一次交易的公钥,可以计算验证紧接着的一次交易的数字签名是否正确。

这一次次的数字签名,对应着一个数字货币的所有交易,构成了一个链。每个交易记录是一个区块(block),而这条链就是区块链(block-chain)。当然,随着设计的变化,这个链变得复杂,但是区块链的基本含义,没有变。

图1 电子货币交易示意(摘自参考文献[3])

4防止虚拟币“双花”

显然,如果这个数字货币的每次交易不能由一个权威的部门来保证交易的权威性,仅依靠货币上的记录,就不能防止某个卖家用两份或多份相同的拷贝去进行交易,即进行“双花”。即使在事后这些交易被发现,往往也太迟了。

因此,中本聪提出了一个的补充方案,实现对交易的控制。

4.1 去中心的时间戳

首先,要给货币的每次交易过程,盖上时间戳。也就是说,在每次交易中,记录正确交易的时刻。这样,如果出现双花的话,我们可以追溯到双花发生前的最后一笔交易,并去掉错误的交易。

但是,这个方法需要第三方系统来产生和认可时间戳,所以它不是去中心的,不好。于是,中本聪搞了个“基于对等基础的分布式时间戳服务”(distributed timestamp server on peer-to-peer basis)[4],采用了“工作量证明”(POW,proof-of-work)的方法。

名字听起来很可怕,其实方法很简单:只要在网络上准备了一堆记账人就行了。每当有新的交易产生,那么交易人就在网络上广播交易信息;记账人如果发现交易合法,而不是双花信息,就会把好几条不同记录合在一起打在一个大包里,确认有关信息,并盖上时间戳。

接下来是困难的部分了:如何确认这个交易记录?所有的记账人,都会按照某种开始就定好的要求,来计算交易记录块的大包的哈希值。按照中本聪的设想,记账人的机器运行的程序,会产生一个随机数,然后记账人根据交易记录块和这个随机数,并按照由程序自动设定的难度,求取一个满足要求的哈希值。比如,一种叫SHA-256的哈希运算就要求,在这个哈希值开始运算的时候,要代入若干个0bit来计算。随0bit的数量增长,这个哈希运算的运算量会指数级上升。对计算机而言,这种哈希运算,需要耗费大量的运算时间和电力,加上一点运气,才能求到一个满足要求的哈希值。最先求出哈希值的记账人,把他的结果在网络上向所有人广播。别的记账人会通过计算来认证并记录这个结果,并等待下一次交易的到来。

需要注意的是,计算得到满足要求的哈希值很难,但是验证某个哈希值是否满足要求却很容易。这样的区块链,每做一次记录,都需要大量的机时,同时还要大量的记账人共同记录并且证明。如果想从某个位置开始改一条新链,就需要大量的机时和记账人重新认可,费时费力,所以这种方式叫“工作量证明”——通过机器的“工作量”证明相应记录及更改。

4.2 选择更长的链

刚才说的这种方式有一些细节问题需要解决。

有时候,两个交易同时出现,都请求记账,那么先记哪一个呢?不同的记账人由于所处位置不同,网络延迟有差别,虽然听到消息的时间相距极近,但还是有先后差别。这个时候,记账人可以记两条链,两个链的先后次序是不同的,一条是甲交易在前,一条是乙交易在前。事后,记账人可以接收下次交易记录时别人公告的记录,并根据别人的记录的长度,而决定采用更长的那条链。因为更长的那条链代表工作量更多,更符合记账人的共识。

如果由于某种原因(网络的某个连接阻塞了,或者记账人关机下线了),有些记账人没听到某次广播,就会出现漏记的情况。当他听到新的广播时,很容易发现自己漏记,如果收到的链比自己的链长,那么他将选用新的长链,并做出调整。

简单地说就是,所有的记账调整,都是更长的链会得到记账人的认可。

4.3 记账人的诚实

链的增长,是跟参与者的众寡相关的。从概率上讲,参与的人越多的那条链,计算出正确结果的速度越快,因此也将得到最长的链。又如何确保他们记账的可靠性?

记账的可靠性,是靠记账人的诚实来保证的。如果,参与的人主要是诚实的,那么诚实的人就会抵御不诚实的人的破坏。为什么他们会自觉地保持诚实?

因为利益。

去中心的货币是没有发行方的。参与创建虚拟币的玩家,从某一台机器随机产生的随机数,按照哈希算法,算出合乎要求的结果,就得到了新的虚拟币,这个过程叫“出块”。虚拟币是玩家们用机时“挖”出来的结果,这个工作跟以前的挖金矿是一样的——这就是“挖矿”和“矿工”的由来。

参与记账的记账人(还是那些“矿工”),会从记账中分得好处。每成功记一次帐,那个成功的矿工,就要从比特币的币值里分一笔交易费,叫“油费”。

在后来很多现实中已经运作体制中,挖矿“出块”和记账权合二为一,只有“出块”的矿工,才有对下一次出块前的所有交易的记账权利,也才拥有这笔油费。

因此,维护这个体系比破坏这个体系,更有利于矿工。所以,最后矿工们就会保持诚实。

5依然存在的双花攻击

整个方案,似乎很完美。

但是真实的系统,总是有漏洞的。

认可更长的链,这个看来非常可行的防御策略,恰恰带来了问题。

比如说,网络由于某个关键节点阻塞而暂时被分为两个部分,这两部分在通信没有恢复时各自记账,就出现了分叉。作为一种补救措施,网络通信恢复之后,两个部分就要比较谁的链长,链更长的记录,将被认可。而那些链不够长的数据,就被覆盖了。而那些被覆盖掉的数据对应的交易,叫“同步”失败了。因为盖时间戳的行为,是表明某个时间点发生的事件,所以叫“同步”,现在这些交易的数据被覆盖了,丢失了,也就意味着“同步”失败。数据覆盖的过程,也称为数据回滚。

也可能会出来一个破坏者,故意制造一个分叉。如果破坏者的力量强大,在他自己控制的网络部分,相比于另外被分隔的那一部分制造了更长的链;那么他就可以在网络通信恢复以后,用自己的长链打败另一部分的短链;这样,破坏者就成功实施了一次攻击。

攻击需要长链,所以,破坏者的算力必须比另一边更强大。换句话说,攻击方的“矿工”的人数至少要超过一半以上(至少是51%)。所以,这种攻击就叫51%攻击。

有了足够的算力,就可以实施51%攻击,再经过巧妙的组合,就可以发动双花攻击。

攻击者先对网络关键连接进行阻塞——比如说,用大量无效的数据使关键连接由于负担过重而瘫痪——制造一次网络分叉;然后分别在分叉的两个部分发起不同的交易。在自己算力强大的部分,可以让虚拟币转个整圈,重新回到自己手上,或者只是参与记账或正常产生“出块”,不让自己虚拟币参与交易;而在分叉的另一部分,攻击者则将自己的虚拟币卖出,转换成其他的虚拟货币,或者是真的现实世界中的货币。

等一切准备就绪以后,攻击者停止对网络的阻塞,分叉的两部分就又合并在一起。因为攻击者的算力强大,所以他算出来的链更长,就可以替换另一部分的链——成功实现51%攻击。另一部分的数据被覆盖,发生数据回滚,它记录的交易数据丢失,同步失败。此前进行的虚拟币交易的记录被抹去,攻击者以前的虚拟币卖出记录消失,因此他就可以把他的虚拟币再卖一次了——这就是双花。

6贼来了

让我们回到12月7日中午,AEknow的司令官刘洋正在各个论坛瞎逛。

如果你还记得那天的天气,那天中午的温度是摄氏24度,在12月真是个暖和日子,猫在显示器后面打着瞌睡,地里的韭菜也长势良好,一切看起来都非常nice。

但是,电脑里的数据记录居然正在回滚!一条长链悄然而至,如同黑云,把正常的数据覆盖了!刘洋赶紧发出通报:

上面就是刘洋发出的预警:12月7日12: 57分,他检查了自己平台的数据库,发现有旧的记录丢失,像是发生了数据回滚,有更长的链来覆盖就数据。因此,他向论坛及交易所发出预警,说是发生了分叉,极有可能是51%攻击。

到了2点17分,刘洋检查了各个交易所的记录,发现这个账号囤积了约2700万元的token,大约相当2700万元人民币,其中的150万已经完成了双花攻击。(事后清点,预计攻击者囤积的AE币大约为2900万元。)

AE币的世界,战斗打响了。

7到底发生了什么

根据刘洋的复盘[5],事情的经过是这样的:

7.1 攻击者的攻击

测试

2020-12-02 08:35:47 在351373高度(这是行话,指的是区块链长度为351373),攻击者(具体是谁并不清楚)先测试了一下,成功出块,挖出了虚拟币。也就是说,生成了一个初始的虚拟币(一般行话叫token)的区块。

买入token

2020-12-03 22:34:34 从352135高度开始,攻击者开始在O交易所逐渐购买用于攻击的token,持续到353153高度(2020-12-06 02:06:50),累计收集价值大约是2900万元的token,准备用于攻击。

挖矿测试

2020-12-06 02:46:56 在353170高度,攻击者已经收集了足够多的token,启动了挖矿测试,开始频繁地正常出块到353187(2020-12-06 03:04:56)。

网络分叉

2020-12-06 04:26:26 估计从353224高度开始,攻击者搞了个网络分叉,把自己挖矿的网络独立出来。他在自己的网络中,挖出了一条未公开的私链,并在2020-12-06 04:26:26挖到353255高度;而公开链在2020-12-06 04:38:38出块。这条私链一直挖到353838高度(2020-12-07 10:16:33)。

私链上的准备

2020-12-06 04:32:50 在私链353230高度,攻击者往自己钱包转账2750万元的token,在353634高度(2020-12-07 00:30:06)转账80万元的token;在353634高度(2020-12-07 00:30:06)转账70万元的token;合计约2900万元的token。

公链上的准备

2020-12-06 04:45:15 在公开链353227高度,攻击者开始往O交易所逐渐充值2750万元的token,将这些token屯在交易所,用于寻找卖家脱手,直到353622高度(2020-12-07 01:15:30),时间跨度为20小时。在353643高度(2020-12-07 02:29:54),另外两个账号分别充值了70万元和80万元的token到交易所。总之,合计大约2900万元的token在交易所内操作,其中一部分被转出到其他交易所。

双花攻击

2020-12-07 10:16:33 在2020-12-07上午10点15分左右,攻击者去掉网络阻塞,广播了自己更长的私链,以353838的高度覆盖了较短的公开链353803高度(2020-12-07 10:10:14);初步完成双花攻击。其所有网络节点的算力仍没有立刻撤去,而是继续参与挖矿。

攻击结束

2020-12-08 03:08:13 攻击者的算力挖出354116高度,此后没有新的出块。

7.2 交易所和平台的反应

回顾

2020-12-07 10:16:33 攻击者广播了自己更长的私链,以353838的高度覆盖了较短的公开链353803高度(2020-12-07 10:10:14);初步完成双花攻击。

此后的进展

2020-12-07 11:00 H交易所检测到区块的数据回滚,关闭充提(也就是说,停止各种交易)。

2020-12-07 11:30 AE社区彭坤发出H交易所暂停提币的消息,宣布钱包维护,暂停AE钱包的充值和提款;AEBox、AEKnow、WeTure几个维护平台初步认为H交易可能遭遇节点的数据无法同步,即交易无法正确记账的问题(根据H交易后期公告,他们发现区块回滚情况)。

2020-12-07 12:30 AE社区马良再次在群聊提出,由于数据回滚,AEBox曾经成功的交易失效;我们开始深入讨论,币赢、Beepool也表示发现区块同步问题。

2020-12-07 12:57 AEKnow对比区块记录数据库和链上数据后,确认交易的正常数据遭遇数据回滚而丢失,Beepool确认交易丢失,区块丢失,并提出极可能遭遇了51%攻击;维护团队开始整理数据,为遭遇51%攻击寻找证据。

2020-12-07 14:02 Beepool、AEBox、AEKnow和Wetrue经过一个小时左右的分析讨论,基本确定被攻击情况,并初步确定嫌疑账号ak_2n9ixHr4m6KvyyVxx47QPX3zNy9AgMtgc8bnsSpmTyqV3qmAjb(ak_2VgB6KRVkpG1UwHcZufnhcFKMEwVJwBc75U6VWKko8c5GrbU1i),可疑矿工ak_cfCSt13PW2Fwsft2CVY1BMmt7XhXW3aoSH49L1xSNW8DpJDC7,以及其攻击开始的高度353225;初步确定关联资金2700万元的token,其中确定双花成功150万token;Weture和AEBox对账号做了转账标记。

2020-12-07 14:30 AE社区通知各大交易所,并在全球电报群通告了51%攻击的初步情况。交易所基本迅速应对,关闭充提。

7.3 虚拟币的流向

攻击者在攻击准备工作中,在O交易所持续收集了约2900万元的token,放到了自己的钱包;攻击发生后,成功双花的约2900万元的token全部进入O交易所。在攻击期间,约2680万元的token从O交易所提出,账面主要流入5个交易所。

攻击结束后,攻击期间的交易被交易所及维护团队全部取消,并将正确数据重新打包恢复。所以攻击者只有部分成功交易,有约1687万元的token通过最长链成功转入各交易所。具体情况如下表所示:

由于各交易所风控差异,攻击者在到账后操作空间不同,带来损失有所差异;但具体情况没有相关的数据。

7.4 现状

发动攻击的矿工已经被定位(已经在网络世界里确定了嫌疑人的账号和矿工的信息,但是无法确定现实世界里的肉身),其交易的token也做了标记;双花的钱只有很少的一部分真的“花”出去了,大部分仍然被困在他自己手上。交易所当然也有损失,但是因为发现得及时,形势还不算太坏。

整个局势仍在演变。各交易所除了自掏腰包弥补亏空,也有限制被标记的token的交易等等手段来继续围困对手。未来如何发展,还有待观察。

8总 结

在虚拟币发展的历史上,这不是第一次发生分叉。这次攻击又一次证明,当遭遇算力强大的对手时,中本聪关于防止51%攻击的方法是无法达成目标的。

虚拟币的设计和产生是随网络发展而逐步形成的,并不是某个天才的机灵劲儿上来的结果。在其发展中,各种实践背后,都有斗智斗勇的过程,有些场面是相当血腥的。

比如这一次,2900万元就突然消失了。虚拟世界的天空,仍然是云淡风轻,仿佛一切都没有发生过似的。

只有刘洋才知道,这虚拟币世界里,战斗,真实又残酷。

12月7日,那是个温暖的日子,桌上的猫,睡得正香,地里的韭菜,也正值壮年。

9致 谢

本文经过姬扬的整体调整和删改;技术细节由刘洋提供;文章在张艺琼的坚持下改了名,题目中没有了我所喜欢的“双花”。特此致谢!

韭菜和剪刀是刘洋家的,出来摆拍的猫也是刘洋家的。所以谢谢刘洋家的韭菜、剪刀和猫!

在群中讨论有关韭菜和猫的照片时,群众在群主曾泳春的带领下,直接就跑偏了。先是纺织学家曾泳春讨论了韭菜的做法,语言学家张艺琼说要上楼摘韭菜,农业专家刘占宇就直接介绍韭菜的肥料,然后物理学家刘艳红和化工专家李学宽就一个劲儿推荐自家的猫......一片混乱中,姬扬就把群名改为:“只有猫知道”。

Anyway,谢谢各位!

参考文献

[1] https://bbs.tianya.cn/post-free-41169-1.shtml

[2] https://wenku.baidu.com/view/2e3f91bb1a37f111f1855b50.html

[3] https://www.oklink.com/academy/zh/bitcoin-white-paper-cn

[4] A. Back, "Hashcash - a denial of service counter-measure," https://www.hashcash.org/papers/hashcash.pdf, 2002.

[5] https://blog.sciencenet.cn/blog-1750-1262277.html