智能合约设计模式 - 预言机

本文为智能合约设计模式系列的一部分。

目的

访问区块链外的数据

动机

以太坊上的每个计算需要网络中的每个参与节点验证,允许合约访问外部网络不切实际,因为每个节点都必须进行同样的访问以验证结果。这样不仅会导致小站点无法处理过量的访问请求,访问信息的更改也会破坏共识算法。因此,智能合约无法和外部世界通讯,这意味着它们无法从互联网等外部来源获得信息。但是对于许多合约来说,它们的核心功能依赖于外部信息,特别是针对一些复杂应用。已经有合约依赖于体育赛事结果、货币价格或航班信息等。这个问题的第一个解决方案是Orisi,发布于2014年,旨在成为比特币和外部世界之间的中介。从那时起,以预言机之名,各个区块链都出现了类似服务。预言机充当区块链上的代理,提供针对外部查询的响应。

区块链处理数据的一个重点是达成信任。由于没有中心节点,信任必须通过不变性或共识算法等方式达成。当依赖外部信息时,也必须有一种办法建立对该信息的信任。

适用性

在以下条件时使用预言机模式

  • 所需的信息无法从区块链上获得
  • 信任外部信息的提供者

参与者和协作

预言机模式由三部分组成:发起请求的合约,预言机和数据源。整个过程从一个合约发起外部查询请求开始,外部查询请求发给预言机,预言机也是一个位于区块链上的智能合约。查询请求包含一些可选参数,例如指定的外部数据源,或某个提供响应的未来时间。

然后,预言机将请求转发给数据源,因为数据源位于链下,所以不能同通过交易和其通信,而是通过其他方式。

数据源处理请求后将结果返回预言机。预言机可以将结果发给调用合约,或等到到达指定时间。调用合约提供回调方法处理返回结果。

实现

我们主要关注合约中的模式实现。预言机本身是在链下实现,这里不做介绍。互联网上有好几个资源介绍如何根据智能合约和业务逻辑实现自己的预言机。然而,用户可能会对采用自实现预言机合约望而却步,因为他们必须信任合约创建者,同时也是预言机操作者,并没有操控预言机结果以影响合约执行。这引入了新的信任需求,而这正是我们试图通过区块链来解决的。

更常见的方式是使用独立的服务作为预言机。这一领域的领导者是英国公司Oraclize。其他预言机服务有Town Crier、使用可信硬件或现实密钥

无论预言机是自己实现还是使用外部服务,调用合约至少包含下面2个方法:

  1. 第一个方法生成查询,通过事务提交请求给预言机合约。根据不同预言机实现,请求可以增额外参数。通常,预言机会返回一个请求ID。
  2. 第二个方法是回调函数。预言机调用这个方法返回结果。回调方法可以保存结果也可以执行任何内部逻辑。第一个方法返回的ID作为参数传入。回调方法需要包含一个检查以确保只有预言机可以调用它,否则,恶意用户可能会调用它提供错误结果来影响合约执行。

代码示例

由于Oraclize服务被广泛使用,下面的示例代码将展示如何使用Oraclize服务接收欧元兑换美元汇率。其他的预言机集成也是类似方式。相关语法的细节,请参考相关文档。

// This code has not been professionally audited, therefore I cannot make any promises about
// safety or correctness. Use at own risk.
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";

contract OracleExample is usingOraclize {

    string public EURUSD;

    function updatePrice() public payable {
        if (oraclize_getPrice("URL") > this.balance) {
            //Handle out of funds error
        } else {
            oraclize_query("URL", "json(http://api.fixer.io/latest?symbols=USD).rates.USD");
        }
    }
    
    function __callback(bytes32 myid, string result) public {
        require(msg.sender == oraclize_cbAddress());
        EURUSD = result;
    }
}

第3行从GitHub中导入Oraclize API,如果编译器不支持从GitHub直接导入,则需要改用本地导入。API提供地址访问以及与预言机交互的功能。第5行代码指定合约使用is关键字从API继承。updatePrice方法想预言机发送查询,这个方法需要payable修饰器,因为Oraclize服务需要收费,收费标准可以在Oraclize文档中找到。第10行确保合约有足够的余额支付查询费用,如果不够,应通知用户,例如通过触发事件。如果余额足够,第13行发送查询给Oraclize合约。第一个参数指明查询URL,第二个参数包含具体url和响应JSON对象中感兴趣的部分。互联网上的任何API都可以通过这种方式访问。

预言机调用__callback方法返回结果。第一个参数myid对应查询时返回的请求id。第18行确保调用者是预言机,第19行保存结果到合约中。

结果

预言机模式最重要的结果是访问链上不能提供的数据,由此产生全新的业务模型和用例。除此之外,预言机还自动触发合约的方法通过在查询中提供触发时间,这可以解决区块链经常遇到的定时任务问题。它还可以 用来生成随机数,一个困难任务,在随机数模式中介绍。对开发人员来说,实现预言机模式很容易,特别是在使用已有服务时。使用已有服务的另个好处是,它们已经过了严格的审核,降低了出错的风险。

使用预言机的一个负面结果是引入了单一故障点。合约以及交互用户在很大程度上依赖预言机提供的信息。预言机或数据源曾经发生的错误,在将来很可能再次发生。不仅错误,即使数据格式的很小改动也会影响智能合约,就像reddit发布的案例,数据源将拳击比赛的输出格式从小写改为大写,导致不可变的智能合约无法工作。另个负面结果是必须信任预言机和数据源,依赖一个外部实体和区块链致力于去中心化的宗旨相矛盾。这个问题可以通过访问多个独立的预言机得到缓解。一种可能的策略是访问M个独立的预言机,采用至少N个返回的相同结果(N < M)。这个方法的一个缺点是每增加一个预言机就会增加成本,并且大多数情况下,得到结果的时间也会增加,因为必须等待至少N个返回。另一个解决方式是Oraclize采用的TLS证明。使用TLS证明,Oraclize可以证明他们在某个时间确实访问了指定网站,并确实收到了提供的结果。虽然这不能阻止Oraclize在获得结果前多次查询,但如果结果不会在短时间内波动,还是值得信赖。

未来可以通过采用去中心化的预言机来解决更多的信任问题,目前仍需大量的工作。

已知应用

区块链上有很多采用预言机的合约。一个使用Oraclize服务的例子是Etherisc合约,预言机用于获取航班延误数据,如果航班延误,合约将向用户支付赔偿。

另一个预言机的实现是体育博彩合约Ethersquares。合约所有人充当预言机,用户借助投票机制可以验证所有者提供的结果是否正确。

推而广之

智能合约或去中心化应用由于其确定性和运行时间限制等原因,无法访问或不适合访问链下数据,这极大地限制了它们的应用范围。目前解决这个问题的主流方式就是采用预言机模式。

预言机模式的另个重要作用就是定时执行。不像传统程序能够通过系统调用或后台线程容易实现主动定时执行,区块链应用自己无法实现主动执行,它的调用只能通过客户端发起。但是,复杂的合约或应用往往需要完成一些定时任务,这就需要引入预言机模式。特别是在联盟链这种具有身份机制,并且链下彼此有信任基础的系统,引入预言机完成定时任务更容易被各方接受。

完整内容请查看智能合约设计模式系列

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,002评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,777评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,341评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,085评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,110评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,868评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,528评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,422评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,938评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,067评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,199评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,877评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,540评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,079评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,192评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,514评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,190评论 2 357

推荐阅读更多精彩内容