现在我们已经明白了比特币脚本的工作机制,接下来我们看一下比特币脚本语言的一些强大应用。你立刻就能明白,比特币将指定公钥变成复杂地指定脚本,是有实际意义的。
第三方支付交易
比如,爱丽丝用比特币向鲍勃买东西,爱丽丝想货到付款,而鲍勃想见款发货。该如何处理?一个好的办法是使用第三方支付交易(escrow transaction)。
第三方支付交易可以用“MULTISIG”(多重签名)来轻易实现。爱丽丝并不直接付款给鲍勃,而是发起一个多重签名的交易,并规定:三个人中有两人签名之后,资金才能被支取。这三个人是爱丽丝、鲍勃与第三方仲裁员朱迪(Judy)。朱迪负责调解可能发生的纠纷。因此,爱丽丝发起了一个2/3的多重签名交易来付款,这个交易规定三个人中有两人签名之后,资金才能被支取。这个交易被纳入区块链后,资金被第三方监管,这三个人中的任意两个人可以决定资金的去向。现在,鲍勃觉得可以给爱丽丝发货了,通常情况下,如果爱丽丝和鲍勃都是有诚信的,鲍勃会按照爱丽丝要求发货,爱丽丝收货之后和鲍勃共同签名,把资金转给鲍勃。由于三个人中有两人签名即可完成支付,此时,由于没有任何争议,朱迪根本不需要参与。和爱丽丝直接付款给鲍勃相比,第三方支付交易并不会更复杂,只需在区块链里增加一笔交易即可。
但如果鲍勃其实并未发货,或者货物在路上被弄丢了,又或者鲍勃发的货物并不是爱丽丝想要的,这时会出现什么情况?爱丽丝觉得被骗了,所以不打算付款给鲍勃,而是想把比特币从监管账户要回来。这种情况下,爱丽丝不会签名真正完成付款,而鲍勃肯定也不会承认问题而主动放弃收款,这时,就需要朱迪判定资金到底该转给谁。如果朱迪认为鲍勃欺骗爱丽丝,她就会跟爱丽丝一起签名,把比特币退还给爱丽丝,当然,如果她认为爱丽丝应该付款,那她就会和鲍勃一起签名,完成资金的实际支付;所以,到底该完成支付或是撤销支付,由朱迪决定。当然,这种情况也只有在发生纠纷时才出现。
绿色地址
另外一个很酷的应用叫作绿色地址(green addresses)。假如爱丽丝要转账给鲍勃,而鲍勃不在线(或者鲍勃在线但没有时间),所以他无法通过查看区块链的更新来确认转账是否完成。一般来说,一个交易需要获得6次确认,我们才能确信它已经确实被加到区块链中,但这需要大约一个小时。但是,想象一下,如果爱丽丝只是在鲍勃的店里买一个热狗,这么长时间才确认交易,显然是不可接受的;或者,如果鲍勃由于某些原因无法接入互联网,那他就一直无法确认交易。加 入 会 员 微 信
为了解决这个问题,比特币采用了第三方银行的做法,实际上,“银行”可能是一个交易所,或者是其他的金融媒介。如果爱丽丝要转账给鲍勃,爱丽丝会和她的银行联系,“我要付给鲍勃这些币,你能办理吗?”银行会回答:“好的。我会从你的账号扣钱,然后从我的绿色地址转账给鲍勃。”这样,收款人就不需要实时查看区块链来确认交易。
需要注意的是,款项并不是由银行直接支付给鲍勃,实际上,部分款项,可能会通过其他地址回到银行手中。但是,由于比特币从银行控制的某个账户——我们在此所称的“绿色账户”直接转给鲍勃,而且,银行保证它不会双重支持这个比特币,如果鲍勃也相信这一点,当他看到银行签名的交易时,就可以确认自己迟早会收到这些比特币——只要区块链确认这笔交易。
请注意,这不是比特币技术系统的保证,而是现实世界中银行的保证,银行为了保护它的声誉,不会双重支持比特币。银行可以向客户证明,“我一直使用这个账户来支付,从始至终也没有发生过双重支付,我以前没有这么做,以后也不会这么做。”如果鲍勃信任银行不会进行双重支付的承诺,他就无须信任爱丽丝——他对爱丽丝本来就了解不多。
当然,如果银行出现了双重支付事件,它就会自毁长城,人们不会再信任它。实际上,有两个提供绿色地址的机构[Instawallet和门头沟公司(Mt.Gox的昵称,位于日本东京,是全球最大的比特币交易商)]就是由于失信而倒闭的。目前,绿色地址使用得越来越少:最初,人们认为绿色地址可以实现快速支付,而且不需要通过查看区块链来确认交易结果;但是现在,人们认为,对“银行”过分信任是有风险的。
高效小额支付(efficient micro-payments)
我们再举一个比特币脚本应用的例子。假设爱丽丝是鲍勃的客户,需要持续向鲍勃支付小额费用,例如,鲍勃是爱丽丝的手机流量提供商,根据爱丽丝每分钟使用的流量计费。但是,每分钟支付一次是不现实的:即使技术上做得到,交易手续费也让人吃不消。
我们希望可以把每分钟的费用累积起来,最后一次性支付。为了实现这种想法,爱丽丝先发起一个MULTISIG交易,把可能花费的最大金额转到MULTISIG地址,但这个交易需要爱丽丝与鲍勃两个人的签名才能生效。爱丽丝在使用流量的时候,每隔一分钟就签名一次,向鲍勃支付这分钟所产生的流量费用,然后把剩余的钱转给自己,每分钟重复一次,直到挂机为止。请注意,这些交易只有爱丽丝的签名,还没有鲍勃的签名,因此,交易还没被放进区块链里。爱丽丝挂机之后,会告诉鲍勃“我用好了,你可以切断我的服务了”,此时,爱丽丝将不再支付费用,鲍勃也将切断服务,然后在爱丽丝发送的最后一个交易里签名,把它放入区块链里。
随着每个交易付给鲍勃的币越来越多,爱丽丝的币就会越来越少。最后一个交易会一次性向鲍勃支付所有的流量费,然后把剩余的币还给爱丽丝。整个过程中,爱丽丝单独签名的交易不会进入区块链(上面没有鲍勃的签名),最后它们都会被丢弃掉。
从技术上讲,所有这些交易都是双重支付。在介绍绿色地址时,我们特别提到防止双重支付的重要性,但在本例中,我们却主动创造了大量的双重支付。实际上,如果双方都是正常运作的话,鲍勃只会在最后一个交易上签名,所以我们在区块链上看不到中间产生的那些双重支付交易。
还有一个微妙的细节:如果鲍勃没有在最后一个交易上签名呢?他可能会说,“就让那些币待在第三方托管地址里吧。”这样一来,爱丽丝就会失去她一开始转到MULTISIG地址的所有比特币。但我们有一个聪明的办法来解决这个问题,那就是我们前面看到的一个代码——锁定时间。
锁定时间
为了避免上面说的这个问题,在小额支付协议开始之前,爱丽丝与鲍勃要签订一个交易,约定向爱丽丝退还所有的比特币,但是这个“退款”行为被上了锁,直到锁定时间到了为止。爱丽丝发起MULTISIG交易把比特币转入第三方托管之后,在向网络宣布这笔交易之前,她会从鲍勃那里要求这个退款交易。这样,如果过了t时间鲍勃还没有在最后一个交易上签名的话,她可以通过这个退款交易收回所有的比特币。
退款交易被锁定t时间是什么意思呢?还记得我们在第3章3.2节提到元数据的时候,有一个参数是“lock_time”,当时我们还没有解释。在此参数后面填上非零数值t, 这个值告诉矿工在记账的时候,要等待t时间之后才能把这笔交易记入区块链。这个交易在放入区块后,经过确定的区块数或者时间才生效。通过这个方式,人们可以发起一笔未来交易,当然,只有资金在未来时间点之前未被花费掉,这笔未来交易才会被执行。这在小额支付的例子里非常有效,它是爱丽丝的定心丸,能够确保在鲍勃最后没有签字的情况下她能拿回自己的比特币。
通过上面的例子,我们展示了比特币脚本可以轻易实现很多功能。我们虽然只讨论了三个例子,但其实人们研究过许多其他的功能。比如多人彩票系统,这个系统涉及一些十分复杂的多步操作协议,以及不同的锁定时间和第三方托管账户,来防止玩家作弊。还可以通过脚本语言实现多人混币,使得比特币更难被追踪。我们会在第6章展开讨论。
智能合约
所谓智能合约(smart contracts),就是那些不同于需要通过法律或者仲裁机构来保护执行的普通合约,智能合约是比特币系统里可以用技术手段来强制执行的合约,我们已经看到,比特币有非常好的特性让我们可以用脚本、矿工和交易验证——而不是通过中心化权威机构——来实现第三方托管协议或是小额支付。
智能合约的研究目前已经非常深入,能够实现非常多很复杂的功能,但比特币脚本语言的设计也有很多缺陷,还是有很多现实需要的智能合约无法用比特币的工作控制语言来实现[1]。不过这里我们就不一一细谈了。
[1] 但已经有很多有意义的探索,比如以太坊等实现了图灵完备的智能合约。——译者注