『学概念找员外』以太坊的燃料、激励和安全
和比特币不一样的是,以太坊支持循环语句,虽然第一个例子里并不需要循环。循环语句一听就容易让人产生警觉,因为有循环的地方就会有无限死循环。从根本上说,以太坊合约有可能因为种种原因而无限循环。计算机领域里一个著名的研究结果(难以判断的终止问题)证明,不存在任何算法,可以根据源代码去判断一个程序是否可以无限运行下去。因此,如何防止合约无限运行下去呢?
更进一步讲,即使条约不会无限运行,也需要某种方式来限制它不会运行太久。以太坊体系通过一种称作“燃料费用”的机制来实现这一点。简单地说,每执行一条虚拟机器的指令需要花费一小部分的成本费用,我们称之为“燃料费用”。不同的操作花费不同。基本的像加减操作只花费1单位燃料费用,而计算SHA-3哈希值(内置函数)需要20单位燃料费用,在永久存储器上写256比特长的字符需要100单位燃料费用。每笔交易也需要先支付21 000单位燃料费用。你可以把以太坊体系想象成超级折扣的航空公司。机票只是你支付乘飞机的费用,任何其他需求都要多付钱。完整操作清单和固定的燃料费用都可以从以太坊里找到。任何清单和费用的变动都需要以太坊产生一个硬分叉,这和比特币脚本语言的语义改变一样。
燃料费用是通过以太坊体系内部被称为以太(ether)的货币来支付的。它只是在用来支付合约操作的时候才叫燃料费用。每笔交易都规定了燃料的价格,也就是说,每份燃料需要多少以太。燃料费用就像比特币的交易费,矿工可以自由公布交易的燃料费用,每个矿工都可以独立地决定收费方式。这样会得出一个反映市场供求关系的燃料市场价格。2016年年初,虽然以太坊网络体系还是属于实验阶段,市场已经默认50 gigawei为1单位价格。50gigawei等于5×10-8 以太,根据以太币和比特币2016年1月的汇兑比例,这也就是大约3×10-10 比特币。
每次调用之前,必须设定燃料费用的最高限,也就是愿意支付价格的最大值。当达到这个值(燃料用完了),程序就会终止,发生的所有程序状态的变化就会被重新设置到原始状态,但是矿工还是保留燃料。由此可见,不要用完燃料,这一点非常重要。燃料的使用要求,意味着以太坊不适合很耗费资源的计算。以太坊系统未被设计成像云计算那样的服务,即支付一定的费用让云服务完成自己无法做到的计算。像亚马逊的弹性计算云或者微软云计算平台,提供划算百万倍的计算量。另一方面,以太坊更加适合创建安全逻辑协议。本质上来说,以太坊提供了一种两个或者多个匿名交易者可以信赖的服务系统。
以太坊上区块链的安全还没有像比特币一样完善。理论上,以太坊比较复杂,也比较难以用数学推理来论证。实际上,以太坊才刚刚开始发展,其安全性还没有像比特币一样经过很多考验。尤其是,担心处理交易的成本会让类似比特币的激励机制失效,我们在共同挖矿的分析中讨论过存在这种担心的情况。当交易成本占矿工的总成本的比重不再能忽略不计的时候,大的矿工有明显优势,因为成本和哈希算力相互独立。更重要的是,燃料只支付给最初包括该交易的区块的挖工。但是所有的在这之上建立区块的矿工都必须验证该区块,却得不到任何报酬。这意味着,他们将有动力去跳过该验证。正如之前所看到的,这种情况不利于区块链体系的健康发展。
以太坊体系中的国际象棋
我们还没涉及以太坊中新功能如何运用,所以让我们看第二个案例。假设喵妹和员外下国际象棋,赌注是一定数额的金钱。唯一的问题是喵妹和员外生活在不同的国家,他们都不相信对方输了会支付赌注。这个问题可以用以太坊来解决。
喵妹写下以太坊程序,这个程序设定了国际象棋的规则并且被上传到以太坊网络。她给这个合约支付一定数量的以太作为赌注。员外可以看到这个合约,如果他答应接受挑战,他把他的赌注支付给这个合约,就等于开始了这个游戏。员外在接受挑战之前应该确认,这个合约是准确无误地遵守了国际象棋的规则,并且最后会把所有赌注支付给获胜者。
一旦双方都支付了赌注,假设他们约定下同样的赌注,合约会检查双方的赌注是否相等。这时候,游戏就开始了。任何一方除非赢了游戏,否则无法从合约里取出钱来。其他人在任何情况下也无法取得这笔钱。
喵妹和员外轮流把自己的下棋步骤发给这个合约。这个合约也会检查轮到谁下确保指令是由喵妹或者员外发出,而不是其他人。大家是否还记得调用者需要在每个操作(促使合约执行一个动作)上签名,因为合约可以根据签名确认调用者。合约也会根据国际象棋的规则校验双方的步骤。如果一方试图把兵移动3格,合约会拒绝该步骤。
到最后游戏结束。合约在每一步都会检测是否有一方被将军,或者双方打平,或者满足其他打平的条件。玩家也可以发送投降的指令。当游戏结束时,合约终止,并把所有的钱支付给获胜者,或者平局下平分赌注。
从概念上看,这是一个以太坊的简单应用,但是有很多微妙的地方值得探讨。如果一方快输了他就放弃了?合约应该设定一个机制,如果一方在规定的时间没有提交有效的下一步,钱就支付给另一方。
哪个玩家先走呢?白方先走的话,白方就拥有微小的优势。因此,双方都想做白方。这就碰到了以太坊合约的一个难题:没有内置的随机源。之所以是一个难题,是因为随机数发生器需要所有矿工的检验(因为他们需要检验合约是否正确地执行),但是这些随机数对任何人来说都是不可预测的(否则的话,玩家也许就因为不能先走而拒绝参加这个游戏)。
随机数“信号塔”(randomness beacons)可以解决这个问题。在双方都加入游戏后,合约计算区块链下一个区块的哈希值。对这个特定的游戏应用而言,这个问题比较容易解决,因为只要让喵妹和员外双方确信决定谁先谁后是随机的,这样就满足要求,而不需要向所有人证明。所以他们可以采用的办法是:他们两个同时提交一个随机数的哈希值,并且公开他们的输入值,然后从双方的输入总值算出随机数。实际操作中,以上两种方法都可以使用。