2900万,没了!——虚拟币世界的真实战斗
1月3日,比特币价格再创新高,最高超过3.4万美元。比特币的涨跌风云让虚拟币家喻户晓,由于使用了区块链技术,包括比特币等虚拟币展现了它们的安全性。但是,虚拟币交易背后仍暗藏危机,即算力超过51%情况下的“双花”攻击。本文源于一个真实案例,AE虚拟币交易中发生一场关乎2900万元的战斗——一名“矿工”发动了“双花”攻击,价值2900万的AE币消失了!
另一方管理员围追堵截,紧急补救,残酷的战斗后最终结局如何?到底什么是“双花”攻击?作者将从电子货币的基础概念讲起,帮读者厘清虚拟币背后的运作原理,并通过对这次交易的复盘讲述虚拟世界中的战斗始末。现实中的云淡风轻,与虚拟世界的腥风血雨形成了鲜明对比。
我们生活在网络时代,虚拟的网络和现实世界相互交互:读书、买票、购物......当然,还有钱:真实的钞票(人民币)和虚拟的货币(虚拟币)。
说到虚拟币,人人都知道比特币。但除比特币外,还有很多种虚拟币,AE就是其中的一种。刘洋是一个虚拟币项目的观察员。他创立的AEknow,是AE币对应的维护平台,专门对AE及其与其他货币的交易进行记录,以便各个网上交易所或者交易者查询,也便于监察交易和技术异常。不错,刘洋就是AEknow的司令官。他平时的工作,就是看看平台是否正常、市场是否稳定。因为绝大多数的工作都是计算机自动执行的,他平时很闲。
12月7日中午,刘洋像往常一样在网上瞎逛。中午的太阳暖洋洋的,论坛里也是云淡风轻,刘洋正在跟人吹水。突然,大事不好!有人发动了一次“双花攻击”,从AE币的交易所偷走了2900万元!2900万!没了!谁偷了这2900万元?他是怎么干的?交易所能把钱追回来吗?在虚拟币的世界里,真正的战斗开始了。
为了弄清战斗过程,让我们从基本的概念讲起。1电子货币与双花攻击电子货币并不是新概念。
上了年纪的人应该都记得磁卡电话,磁卡上记了充值的钱数,就代表一种电子货币。当你用磁卡打完电话,通信系统会扣除通信费,再将剩余的钱数写回磁卡。虽然磁卡本身不是货币,但是,磁卡被使用的过程,就跟花真的钱是一样的。那么,跟真钱相比,磁卡会有什么特别的问题呢?那就是当系统有漏洞时,一份钱可以当两份钱花!因为花了两次,所以叫“双花”(double spending)。
最早的卡式公用电话(用电话卡打电话)就出现过导致双花的漏洞。通过拷贝电话卡磁条上的信息,不法人员就可以造一张假卡。而假卡上的金额信息,就像是卡上的钱没有被使用过一样;实际上,这笔钱已经在真卡上被扣除过了。更有甚者,真卡只是用来拷贝,假卡则无数次被满额使用——这已经不是双花,而是无限花了。数字世界的最大问题,就是信息可以被拷贝而不失真。电子货币的记录,只是数字世界的一种信息而已。
这样就面临一个重大问题:可以造假钱!一旦成功,就可以双花,真爽!所以,货币电子化的过程,一直都要解决双花问题。
2数字签名要解决“双花”,第一步,是实现数字签名。什么是数字签名?它是一种对数据进行加密的技术手段。在数字世界里,加密和解密都是对字符串进行运算变化。加密就是把要传送的信息(明文)和加密密钥(也是一串字符)一起进行某种运算,变成密文。
显然,解密密钥就是能把密文变回明文的运算所需要的字符串。加密密钥和解密密钥可以相同,这就是对称加密;也可以不同,这就是非对称加密。非对称的加密系统通常不是用来保密,而是用来保证数据的真实性、完整性和不可抵赖性——数字签名就是干这个用的。它是通过加密运算获得的、比较短的一串字符,通常附缀在一段文件数据信息的后面。
数字签名的真实性,将确保数据的发出者就是签名者本人;其完整性,则保证数据没被改动过;不可抵赖性,则保证如果发出者本人在事后改动数据,就会反映到数字签名中,使其更改行为露馅。
3虚拟币2000年开始,由于互联网游戏的急速发展,各个网游公司都开始发行自家的虚拟的游戏币。这些游戏币往往需要玩家充值,用真金白银来买;同时玩家们也可以通过私下交易,获得虚拟的游戏币,并用虚拟游戏币来买游戏中的道具,升级打怪。
这些游戏公司之间的游戏币就像真实世界的货币一样,出现了彼此间的交易结算价格;出于挣钱需要,有的游戏公司加大了游戏币发行数量,结果还出现了通胀。因此,就有学者和IT从业者开始研究,是否可以真的“发行”一种虚拟的网络电子货币,除了能抵御双花攻击,还没有发行中心控制,这样就能合理抵御货币通胀。
这种没有中心控制的机制,叫“去中心”,就是货币发行和交易都不依赖于某个权威的第三方(比如银行),而是由平台上的交易人和“铸币”人共同维护和交易。2007年,有位化名“中本聪”的人(或者集团)发了一篇网文,结合一系列学者的设想,设计了一种去中心的网络电子货币,就是我们现在称的虚拟币的最早一种——比特币。并且,从设计开始,就要求整个系统有抵御双花攻击的功能。
4防止虚拟币“双花”显然,如果这个数字货币的每次交易不能由一个权威的部门来保证交易的权威性,仅依靠货币上的记录,就不能防止某个卖家用两份或多份相同的拷贝去进行交易,即进行“双花”。即使在事后这些交易被发现,往往也太迟了。因此,中本聪提出了一个的补充方案,实现对交易的控制。4.1去中心的时间戳首先,要给货币的每次交易过程,盖上时间戳。也就是说,在每次交易中,记录正确交易的时刻。
这样,如果出现双花的话,我们可以追溯到双花发生前的最后一笔交易,并去掉错误的交易。但是,这个方法需要第三方系统来产生和认可时间戳,所以它不是去中心的,不好。于是,中本聪搞了个“基于对等基础的分布式时间戳服务”,采用了“工作量证明”(POW,proof-of-work)的方法。名字听起来很可怕,其实方法很简单:只要在网络上准备了一堆记账人就行了。
每当有新的交易产生,那么交易人就在网络上广播交易信息;记账人如果发现交易合法,而不是双花信息,就会把好几条不同记录合在一起打在一个大包里,确认有关信息,并盖上时间戳。接下来是困难的部分了:如何确认这个交易记录?所有的记账人,都会按照某种开始就定好的要求,来计算交易记录块的大包的哈希值。
按照中本聪的设想,记账人的机器运行的程序,会产生一个随机数,然后记账人根据交易记录块和这个随机数,并按照由程序自动设定的难度,求取一个满足要求的哈希值。比如,一种叫SHA-256的哈希运算就要求,在这个哈希值开始运算的时候,要代入若干个0bit来计算。随0bit的数量增长,这个哈希运算的运算量会指数级上升。
对计算机而言,这种哈希运算,需要耗费大量的运算时间和电力,加上一点运气,才能求到一个满足要求的哈希值。最先求出哈希值的记账人,把他的结果在网络上向所有人广播。别的记账人会通过计算来认证并记录这个结果,并等待下一次交易的到来。
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到底发生了什么根据刘洋的复盘,事情的经过是这样的:7.1攻击者的攻击测试2020-12-02 08:35:47在351373高度(这是行话,指的是区块链长度为351373),攻击者(具体是谁并不清楚)先测试了一下,成功出块,挖出了虚拟币。也就是说,生成了一个初始的虚拟币(一般行话叫token)的区块。
买入token2020-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高度,此后没有新的出块。
8总结在虚拟币发展的历史上,这不是第一次发生分叉。这次攻击又一次证明,当遭遇算力强大的对手时,中本聪关于防止51%攻击的方法是无法达成目标的。虚拟币的设计和产生是随网络发展而逐步形成的,并不是某个天才的机灵劲儿上来的结果。在其发展中,各种实践背后,都有斗智斗勇的过程,有些场面是相当血腥的。
比如这一次,2900万元就突然消失了。虚拟世界的天空,仍然是云淡风轻,仿佛一切都没有发生过似的。只有刘洋才知道,这虚拟币世界里,战斗,真实又残酷。12月7日,那是个温暖的日子,桌上的猫,睡得正香,地里的韭菜,也正值壮年。