比特币是一个只能添加而不能删除的记录。它是一种可以不断添加新的数据,但是数据一旦被添加上去,就变得不可修改并且永久保存的数据结构。因此,通过比特币,我们可以获得一个时间顺序:判断一个数据是在另一个数据之前还是之后被写进了记录的。这个次序是由区块之间的哈希函数指针,而不是区块上的时间戳所决定的,因为时间戳可以作假,或者是由于矿工更改时间戳的值使其变得更小(更早),或者是矿工的计算机时钟没有同步,更或者是由于网络延时产生的差异。话虽如此,如果一个区块的时间戳延迟了好几个小时,它就会被其他的矿工们拒绝。所以时间戳还是相对准确的。通过下面的示例,我们可以看到,这些特性是有实际用途的。
安全时间戳
比特币这种只能被添加的记录特性可以被用来建立一个安全时间戳(secure timestamping)系统。假如,想要证明在时间T我们就知道了x的值,但并不想披露它的具体值。只有在未来很长时间后,当有可能需要证明我们确实知道这个值的时候,才有可能需要去披露它(当然,如果我们在时间T知道x的值,我们在T之后的时间还是知道这个x的值)。而且我们一旦证明了这一点,就需要使这个证据具备永久性。
在第1章中我们看到,可以用哈希函数来锁定数据x。我们不需要公布x值本身,取而代之地,只需要在区块链里公布这个数据值的哈希函数H(x),即可以来证明我们知道这个X值。这个哈希函数的特性,保证了我们不可能再找到另外一个数据y,其哈希函数结果与x的哈希函数结果一致,也就是说,当y≠x时,H(x)=H(y)是不存在的。我们还可以依赖哈希函数另外一个常用的特性:只要x本身具备比较高的最小信息熵分布特性(distribution with high min-entropy),也就是说,x是不可预测的,那么x的哈希函数结果不会透露关于x的任何信息。如果x本身没有这种不可预测的特性,就像我们在第1章中探讨的,我们可以选择一个有较高的最小信息熵分布的随机数r和x组合签名,然后用H(r|x)作为对外公布的一个数值约定。
这个设想的核心就是,我们在时间点T只向外公布哈希函数H(r|x),然后在之后的某个时间点来公布r和x。任何人看到这个只能做增量的记录,都会相信在我们发表H(r|x)的时候我们一定知道x,因为没有除此之外的其他方法可以让我们产生那些数据。
时间戳的应用
这个安全时间戳到底有什么用途呢?一个可能的应用就是可以用来证明创意的优先性。假设我们想证明,申请专利的一些创意点子早就在我们头脑里存在。我们可以在产生创意的第一时间,就将设计文档或者示意图草稿在区块链里用哈希函数发表出来,但不会向任何人泄露这个创意的具体内容。之后,当我们提交专利申请或是公布这个想法的时候,我们可以将最初的设计文档和相关信息发表出来,任何人都可以查证这些文件的函数时间戳,来证实我们在这之前,也就是我们发布设计文档的哈希函数约定的时候,就已经有了这个创意(证明我们对这个创意的时间上优先所有权)。
我们还可以用同样的方法来证明,其他人收到过我们发给他们的信息。假设爱丽丝雇用鲍勃去做一个编程的工作——他们之间的合同规定,鲍勃必须在一定的时间内将他所做的工作内容提交给爱丽丝。双方都想要获得一个保证,如果将来对相关工作内容有争议,比如鲍勃是否按时提交程序或者他提交的内容是否满足合同要求,双方都希望可以有相关的事实去证明。为了确保这一点,他们可以互相协商,将鲍勃提交的工作内容共同签名后,再在区块链上发表它的哈希函数。任何一方如果对提交的时间或者内容撒谎,另一方可以通过披露哈希函数的输入来重现当时发表的内容,来证明对方是错的(比如在法庭上)。
安全时间戳功能还有许多其他有意思的应用。有一种完全公钥签名方案,被称为盖伊·福克斯签名方案(Guy Fawkes signature scheme),相比较通常的公钥签名,只是利用了哈希函数和只能做增量记录的记录特性,而不需要任何重量级的加密算法。
对未来预测证明的攻击
我们目前无法仅仅用时间戳就证明对未来的准确预测,能对未来进行预测(clairooyance),当然非常好。而且从表面上看,这好像可以做到。在一个事件发生之前(比如一个体育比赛或是选举)发表一个对结果的预言,然后在事件发生之后,再证明在之前就已经预测到了。但这个方法是否真正可行?
在2014年下半年的世界杯决赛阶段,有人想用这个办法来“证明”世界杯的组织方国际足联(Federation Internationale de Football Association,简称FIFA)在搞腐败。当时有个推特账号,由于在一些重要比赛之前就可以准确地预测到这些比赛的结果,因而被广受关注。比如,该账号准确地预测到德国队会在加时赛取胜并且马里奥·格策(Mario Götze)会进球。这看起来可以证明,要么是微博主人有预知未来的能力,要么是比赛被操纵了。然而事实上,这个博主只是在比赛前发布了所有可能发生的事件,比如,对于所有的参赛球员,都有一条关于他会进球的微博,以及对于每一种可能的最终比分,都有一条相关的微博等(见图9.1),然后在比赛结束之前,博主删除了所有那些不准确的预测,只留下那些准确的“预测”。
图9.1 试图对未来进行预测
注:这就是那个虚假的试图通过预测比赛结果来“证明”世界杯决赛圈的比赛被操控了的推特账号。其中第一个和第四个在赛后被证明是正确的,其他不准的预测就被删掉了。
可以用同样基础的攻击方法攻破任何安全时间戳系统。你只需要在事先预埋下所有的结果,然后最终只披露那个正确的结果。这就意味着如果你想证明你有预测能力,就必须去证明你做且只做了一个预测结果,而不是多个预测。但如果你想基于哈希函数揭示结果,是很难实现的,尤其是在比特币的区块链上,因为安全时间戳系统并不将承诺与任何个人身份识别相关联。如果你不揭示它们,就会很容易公布很多种承诺,而那些你从未揭示的承诺很难轻易追溯到你。
过时的安全时间戳
这里介绍一个简单的低科技含量的安全时间戳方案:通过刊登广告,你可以在一份报纸或者其他媒体上登出你预测结果的哈希函数值,相关的旧报纸杂志会被保存在图书馆里或者在线备份。这种方法可以提供较高程度的保证,证明你在报纸发出的当天就已经知道这个结果了。以后,当你想要披露你预测的结果时,你可以在同一个报纸上刊登第二份公告。
比特币里的安全时间戳
如果我们想用比特币而不是报纸来实现时间戳的功能,我们应该在哪里放置约定的哈希值?是在交易中的某个环节,还是直接在一个区块里?
人们想出来的第一个也是最简单的解决办法是,直接把钱打到数据的哈希函数值,而不是公共钥匙的函数值。由于你不知道对应地址的私钥,这样做会“消耗”这些币,让它们销毁掉,并且永不能被利用。为了降低成本,你可能需要发送微量的币值,比如1聪(satoshi,0.0000001个比特币,这是比特币的最小交易额)。
这个方法虽然很简单,但消耗比特币的做法不讨人喜欢(即使和交易费相比,这种被消耗的比特币量级可以忽略不计)。更大的问题是,因为比特币矿工不知道这些交易开支是永远不可用的,他们会永远地追踪下去。因此整个比特币社区对这个方法都不太感冒。
另一个较为先进的被称为承诺币(CommitCoin)的方法,是将你的数据编码进私钥里。第1章中曾经提到过:“使用ECDSA时,确保随机性良好来源至关重要,因为不良来源将可能导致密钥信息的泄露。这一点不难理解,如果你使用了不良随机源来生成密钥,那么该密钥就可能不安全。但是ECDSA的古怪就在于,即使你仅仅只是在生成签名时使用了不良随机源,而你使用的密钥完美无缺,你的个人密钥还是可能会被泄露。”
承诺币利用了这个特性。我们生成一个新的私钥把我们的数据约定进行编码,并对应地生成一个公钥。然后我们会发送一个微小金额的交易(比如2 000聪)到那个地址,随后再发送两笔每次1 000聪的交易回来。最重要的是,当发送回来的时候,我们会用同样的随机源来对两次交易进行签名。这样,任何人在区块链里计算包含被封装的数据约定的私钥时,必须使用两个签名。
比起把数据约定编码到公钥的方法,承诺币避免了消耗额外的比特币,而且矿工不再会一直追踪一个永久不能再被使用的支出。不过这个方法十分复杂。
不能被再次使用的输出
一直到2015年,比特币实行时间戳的办法是用一个OP_RETURN的交易,这个交易的输出可以被证明,但不能被二次使用(见图9.2)。这个OP_RETURN指令会立刻返回一个错误代码让这个脚本永远不能成功地执行,这样一来,所封装的数据就被忽略了。就像我们在第3章看到的,这既可以用做消耗证明,也可以用来编码任意数据。到2015年,OP_RETURN允许输出80个字节的数据,这对哈希函数来说是足够了(SHA-256需要32个字节)。
图9.2 用OP_RETURN指令的时间戳
注:这是一个“不能被再次使用”的交易输出脚本,中间封装了一个数据约定。
这个方法“挤出了”在没有被使用过交易支出里的“水分”,因为矿工会精简OP_RETURN里的支出。这个数据约定的花费其实就是一个交易费。在整个2015年,一个典型的交易费通常小于1美分。这个交易费可以分摊在针对多个数据的一个约定上,从而使得成本更低。在2015年年末,已经有几个网站在做这些服务。它们收集不同用户的一组数据,把这些数据封装到一个梅克尔树中,然后发布一个包含了这个梅克尔树树根数据中不能被再次使用的交易支出。这种做法就好比,把当天需要实行时间戳的所有用户数据封装到了一个数据约定里。
非法内容
区块链随意封装数据的特性也有不好的地方,可能会被某些人恶意使用。在大多数国家,有些内容,尤其如儿童色情,它的制作和传播都是非法的,并且会伴随非常严厉的处罚。著作权法也严格规定了某些内容的传播。
当然,不少人已经尝试这样做去“危害”或者扰乱比特币社区。比如,有报道称有部分色情链接被公布在比特币的区块链上。这些害群之马的目的,就是让下载比特币区块链到个人硬盘并且运行完全有效节点的行为变得很危险,这也意味着你有可能存储和传播了这些非法的信息。
然而,截至目前,还没有好的办法来阻止这种写入任意数据到比特币区块链的行为,即使我们用P2SH(支付给脚本的哈希值)来防止恶意攻击行为,也只不过是使交易多花些费用而已,无法完全阻止这种行为。
好在法律不是计算机算法,尝试用技术的手段对法律进行“黑客攻击”虽然很诱人,但并不容易。法律是需要人类来解释的,并融合了其他因素,比如我们的意图。以美国联邦法案2252号为例,其中在描述有关拥有、分发传播和接收儿童色情制品的非法行为时,使用的措辞就用了“明知故犯”这样包含了意图的关键词。
另外一个值得注意的是,根据上面我们讨论过的字节大小的限制,图片数据(除非是非常小的图片)不能直接被写在区块链的数据块中,这些数据要么被存放在只在区块链中保存相应链接的外部数据库中,要么是用一种冗长的办法封装在多个交易之中。最终的结果就是,大多数比特币用户都没有能力在交易中直接解码并查看数据,更不用说解码并查看跨越多个交易的数据了。
依附在比特币上的附着币
从好的一方面来说,因为我们可以把任何数据都写进比特币的区块,从而在比特币的系统之上建立起一个全新的货币系统,而不需要开发一个新的共识机制。我们只需要简单地把比特币用作一个只能被添加的记录,然后把我们开发新币所需要的所有数据写进比特币的区块链。我们称这种方法为一个依附在比特币上的“附着币”(overlay currencies)。比特币成为一个底层基础架构,所有附着币的数据,通过以不可消费的交易支出的方式写进比特币的区块链。
当然,比特币的矿工不会验证你写进区块链的数据,因为他们不知道也并不关心这些数据在你所定义的新的货币体系里是否正当有效。只要你肯付交易费,任何人都可以写任何东西。不同的是,你必须自己开发更加复杂的逻辑来验证新货币体系里的交易,然后在每个收发这种新币的客户端(也就是钱包软件)都必须有这套逻辑。
举例来说,一个附着币的矿工不能再拒绝双重支付的交易。相反,每个附着币的用户必须检查区块链里的历史记录。如果有人尝试重复支付这个币(已经被用过一次了),那样第二次的交易就应该被直接忽略。因为这个缘故,在附着币里没有一个轻量级的SPV客户端。
合约币(Counterparty)是其中一种比较优秀的附着币,所有合约币的交易都被写入比特币的区块链,在2014年,大约有0.5%~1%的比特币交易携带了合约币的数据。同时它支持的功能也比比特币更多、更丰富,因为合约币不需要开发新的共识机制,而比特币的矿工也不需要了解合约币的规则,合约币的开发者可以集中精力开发一些有趣的功能,比如智能合约、用户自定义货币等。合约币的API也比比特币的API丰富很多,因为比特币的矿工不需要理解或者是批准这些API的开发。
不需要开发新的共识机制就可以创造一个新的数字货币,这种可能性是十分诱人的。你甚至不需要去鼓励新矿工们来加入你的系统,也不需要去改变比特币就可以增加新的功能特性。但是,这种系统还是依赖于比特币的,比如,这些附着币的交易费规则就受制于比特币。另外,由于附着币上的节点可能需要处理大量的数据,而比特币不会帮你去过滤这种交易,这种方法也有可能是低效率的。