![](http://yuml.me/diagram/scruffy/class/[Blockchain] Oracle -.->[Real world])

在以太坊上创建一个智能合约不可思议的简单,这里几乎不会牵扯到复杂的编程知识或者法律合约知识。一个普通人可以快速的创建一个ERC20 token。这使得区块链在这个世界蔓延生根的更快。在不久的未来,很多事物都可以通过智能合约来执行,而不需要借助一个中央机构。智能合约加速了交易,并且透明的保护了参与者双方的完全信息对称。

在智能合约上,可以快速的发起一个ICO:给它设定一个起始时间和终止时间,发行多少Token和解锁策略。这使得一些优秀的企业或是项目,可以在不需要进行IPO就可以募集到启动资金。(由于ICO的门槛低廉,会导致衍生出很多骗局)。

在智能合约中,可以通过内置的对象获取一些额外的信息,比如打包当前交易的区块的当前时间戳、区块的高度等等。

  function time() constant returns (uint) {
        return block.timestamp;
    }

但是,无法从智能合约的内部依赖真实世界的数据。

比如你不能这样

function extra_real_world_data() constant returns (uint) {
        return load_from_facebook();
    }

在日常的编程经验中,我们可以写出这样的编程代码,这没有任何问题。但注意,智能合约跟传统的软件有着非常大的区别。它不是由一台服务器执行的,而是由以太坊执行的。这就意味着有无数个节点需要可以执行它。每个节点对load_from_facebook()的调用都是不相同的。

我们依赖 www.facebook.com 作为数据源,伴随着有些节点的DNS被污染,可能定向到一个伪造的facebook。或者对facebook的数据访问被恶意篡改,或者facebook本身被控制或是做出恶意的行为。 在这样的环境下,节点对外部因素参与的计算的结果很难统一。

然而,我们要实现一个对赌合约,比如来赌下一次奥运会的中国金牌数的时候,就真实的依赖中国的金牌数。这时候,智能合约就无能为力了。因为智能合约无法知道下一次中国金牌数是多少。 (即便是我们有一个权威的地址可以访问,当智能合约运行的时候,每一台运行智能合约的节点都对同一个地址的请求都可能产生不同的结果。有些节点为了欺骗,会给予错误的数据来影响合约的执行结果。更重要的是,权威节点往往是中心化的,它被某些利益团体操控,或者被攻击)

智能合约当然不能永远只停留在沙盒里面,它不能只能获得区块的信息和时间戳。它应该可以获取到更多的真实世界的信息。只有这样,它才能发挥最大的威力。

所以,我们需要预言机。

预言机是区块链与真实世界进行交互的实体。它确保外部的输入是真实的。智能合约和预言机进行信息交换。 因此,智能合约必须要借助预言机,才能发挥它的最大作用。