螞蟻區(qū)塊鏈第18課 區(qū)塊鏈預(yù)言機(jī)(ORACLE)的定義及在螞蟻BAAS中的使用

1偿荷,摘要

本文主要講解外部預(yù)言機(jī)ORACLE定義和原理,并講解螞蟻BAAS系統(tǒng)如何通過ORACLE預(yù)言機(jī)方式使用外部數(shù)據(jù)源的方法溉躲。

2星岗,外部預(yù)言機(jī)ORACLE定義和原理

2.1 預(yù)言機(jī)(Oracle)是什么?

2018年11 月 6 日首有,中國(guó)人民銀行發(fā)布的《區(qū)塊鏈能做什么燕垃?不能做什么?》報(bào)告中井联,是這樣對(duì)預(yù)言機(jī)定義的卜壕。

區(qū)塊鏈外信息寫入?yún)^(qū)塊鏈內(nèi)的機(jī)制,一般被稱為預(yù)言機(jī) (oracle mechanism) 烙常。

預(yù)言機(jī)的功能就是將外界信息寫入到區(qū)塊鏈內(nèi)轴捎,完成區(qū)塊鏈與現(xiàn)實(shí)世界的數(shù)據(jù)互通。它允許確定的智能合約對(duì)不確定的外部世界作出反應(yīng)蚕脏,是智能合約與外部進(jìn)行數(shù)據(jù)交互的唯一途徑侦副,也是區(qū)塊鏈與現(xiàn)實(shí)世界進(jìn)行數(shù)據(jù)交互的接口。

聽上去很難理解驼鞭,我們舉例來說秦驯。

大家會(huì)很形象的把公鏈比作操作系統(tǒng)(Windows、IOS挣棕、安卓)译隘,DAPP 類比的話就是 APP,那么預(yù)言機(jī)可以形象的比做 API 接口洛心。API 是一組定義固耘、程序及協(xié)議的集合,通過 API 接口實(shí)現(xiàn)計(jì)算機(jī)軟件之間的相互通信词身。這樣類比雖然不準(zhǔn)確厅目,但意思就是預(yù)言機(jī)是區(qū)塊鏈和現(xiàn)實(shí)世界之間的紐帶,可以實(shí)現(xiàn)數(shù)據(jù)互通的工具法严。

Oracle 為什么被中譯為預(yù)言機(jī)璧瞬?

跟別人提起預(yù)言機(jī),很多人的反應(yīng)都是預(yù)測(cè)市場(chǎng)渐夸,預(yù)言機(jī)這個(gè)名字確實(shí)容易想到預(yù)測(cè)嗤锉。

Oracle 最初是來源于古希臘宗教,意為“神諭墓塌、先知瘟忱、預(yù)言”奥额。而在互聯(lián)網(wǎng)領(lǐng)域,預(yù)言機(jī)(英語:oracle machine)访诱,又稱諭示機(jī)垫挨,是一種抽象電腦,用來研究決定型問題触菜【爬疲可以被視為一個(gè)多了個(gè)黑盒子(預(yù)言者)的圖靈機(jī),這個(gè)黑盒子的功能是可以在單一運(yùn)算之內(nèi)解答特定問題涡相。

也許你會(huì)好奇這跟甲骨文公司有什么關(guān)系嗎哲泊?其實(shí)沒有關(guān)系。

Oracle 在中國(guó)叫甲骨文公司的原因可能是另一個(gè)故事催蝗。在中國(guó)商朝晚期切威,王室把在動(dòng)物骨骼或龜甲上做占卜記事的文字叫甲骨文,甲骨文被英譯為 Oracle bone script丙号,后來 Oracle 公司到中國(guó)中譯為了甲骨文公司先朦。(很有道理的猜測(cè) 哈哈哈??)

2.2 區(qū)塊鏈為什么需要預(yù)言機(jī)?

區(qū)塊鏈?zhǔn)且粋€(gè)確定性的犬缨、封閉的系統(tǒng)環(huán)境喳魏,目前區(qū)塊鏈只能獲取到鏈內(nèi)的數(shù)據(jù),而不能獲取到鏈外真實(shí)世界的數(shù)據(jù)怀薛,區(qū)塊鏈與現(xiàn)實(shí)世界是割裂的刺彩。

一般智能合約的執(zhí)行需要觸發(fā)條件扩氢,當(dāng)智能合約的觸發(fā)條件是外部信息時(shí)(鏈外),就必須需要預(yù)言機(jī)來提供數(shù)據(jù)服務(wù)刨裆,通過預(yù)言機(jī)將現(xiàn)實(shí)世界的數(shù)據(jù)輸入到區(qū)塊鏈上扇住,因?yàn)橹悄芎霞s不支持對(duì)外請(qǐng)求。

具體原因是這樣的怀樟。區(qū)塊鏈?zhǔn)谴_定性的環(huán)境,它不允許不確定的事情或因素,智能合約不管何時(shí)何地運(yùn)行都必須是一致的結(jié)果呐能,所以虛擬機(jī)(VM)不能讓智能合約有 network call(網(wǎng)絡(luò)調(diào)用),不然結(jié)果就是不確定的抑堡。

也就是說智能合約不能進(jìn)行 I/O(Input/Output摆出,即輸入/輸出),所以它是無法主動(dòng)獲取外部數(shù)據(jù)的首妖,只能通過預(yù)言機(jī)將數(shù)據(jù)給到智能合約偎漫。

我們通過一個(gè)例子來說明一下。假設(shè)現(xiàn)在我被關(guān)進(jìn)了一個(gè)小黑屋里(不要多想有缆,只是例子 =-=)象踊,我對(duì)外面的世界發(fā)生了什么幾乎一無所知温亲,不知道外面是否有人,即使呼叫也沒有人回應(yīng)杯矩,只有外面的人在門口把他看到的聽到的都告訴我栈虚,我才可以得知外面的世界。

例子雖然不太恰當(dāng)史隆,但智能合約就像這個(gè)例子中的我一樣魂务,它無論何時(shí)何地,都無法主動(dòng)向外尋求信息泌射,只能外部把消息或數(shù)據(jù)給到里面粘姜。而預(yù)言機(jī)就是這個(gè)在外面輸送消息和數(shù)據(jù)的人。

好像這么看來魄幕,智能合約并不是很智能呀相艇,是的,智能合約其實(shí)是完成的不智能的事情纯陨,即寫好了條件和結(jié)果坛芽,當(dāng)給它條件的時(shí)候,就可以觸發(fā)翼抠,但也不會(huì)馬上執(zhí)行咙轩,還需要合約相關(guān)的人進(jìn)行私鑰簽署才可以執(zhí)行。

所以阴颖,網(wǎng)上很多文章其實(shí)都有水分活喊,比如智能合約某個(gè)時(shí)間或者觸發(fā)某個(gè)條件就可以自動(dòng)執(zhí)行之類的,只能說這樣的句子在邏輯上是有問題的量愧。關(guān)于預(yù)言機(jī)的很多文章也有水分钾菊,描述的并不準(zhǔn)確。

好了偎肃,上面就是區(qū)塊鏈為什么需要預(yù)言機(jī)煞烫,因?yàn)橹悄芎霞s無法主動(dòng)去獲取鏈外的數(shù)據(jù),只能被動(dòng)接受數(shù)據(jù)累颂。

2.3 預(yù)言機(jī)怎么解決這個(gè)問題

來源:ChainLink 白皮書

這就是理想中預(yù)言機(jī)的工作流程滞详,即用戶的智能合約把請(qǐng)求給鏈上 Oracle 合約,通過鏈下的 API 接口獲得外部數(shù)據(jù)紊馏,更確切的說是外部把數(shù)據(jù)給鏈上的 Oracle 合約料饥,然后 Oracle 合約再把數(shù)據(jù)給用戶的智能合約。

或許很難理解朱监,因?yàn)樵诨ヂ?lián)網(wǎng)中岸啡,調(diào)用數(shù)據(jù)是非常容易的,只需要在程序中寫調(diào)用的代碼就可以了赫编。但是區(qū)塊鏈與外部世界的數(shù)據(jù)交互凰狞,確實(shí)不能進(jìn)行這樣的操作篇裁。

2.4 預(yù)言機(jī)的應(yīng)用場(chǎng)景有哪些?

預(yù)言機(jī)作為區(qū)塊鏈與現(xiàn)實(shí)世界進(jìn)行數(shù)據(jù)交互的橋梁赡若,應(yīng)用場(chǎng)景非常多达布,可以說一切需要與鏈下進(jìn)行數(shù)據(jù)交互的DApp都需要預(yù)言機(jī)。比如金融衍生品交易平臺(tái)逾冬、借貸平臺(tái)黍聂、快遞追蹤/IoT、穩(wěn)定幣身腻、博彩游戲产还、保險(xiǎn)、預(yù)測(cè)市場(chǎng)等等嘀趟。

我們還是舉例來說脐区。

先說最近幣圈比較火熱的博彩游戲?yàn)槭裁葱枰A(yù)言機(jī)。博彩游戲的核心是不可預(yù)測(cè)她按、可驗(yàn)證的隨機(jī)數(shù)牛隅,從而決定賭注的最終結(jié)果,但是在鏈上是無法生成隨機(jī)數(shù)的或者說在鏈上的隨機(jī)數(shù)是可以被預(yù)測(cè)和破解的酌泰,這時(shí)候就需要預(yù)言機(jī)從外部給智能合約安全的媒佣、不可預(yù)測(cè)的隨機(jī)數(shù)。

現(xiàn)在的大多數(shù)博彩游戲都是在鏈上生成隨機(jī)數(shù)陵刹,所以很容易被預(yù)測(cè)和破解默伍,導(dǎo)致資產(chǎn)被盜,大家有興趣的可以去看一下DApp被盜的相關(guān)研究報(bào)告衰琐,很多因?yàn)殡S機(jī)數(shù)問題被盜的也糊。比如 BetDice、Dice2Win羡宙。

如果大家很感興趣狸剃,可以看一下我男神 DOS Network 創(chuàng)始人@nrek jonny 關(guān)于《智能合約中的隨機(jī)數(shù)》的分享。

其實(shí)辛辨,早在 Fomo3D 這個(gè)游戲出來之前捕捂,以太坊的 Team Leader 就在推特上說過鏈上是無法生成隨機(jī)數(shù)的瑟枫。Dear devs... you can`t generate random numbers on chain斗搞!

我們?cè)賮砜匆粋€(gè)關(guān)于快遞追蹤的例子。

假設(shè)當(dāng)我通過某個(gè) DApp 購物平臺(tái)購買某件物品快遞過來的時(shí)候慷妙,真實(shí)世界中的快遞寄送或到達(dá)信息僻焚,就可以通過 Oracle 把數(shù)據(jù)傳遞到鏈上,然后觸發(fā)鏈上的智能合約膝擂,我用自己的私鑰確認(rèn)收到了快遞虑啤,并完成付款隙弛。

大家發(fā)現(xiàn)了嗎?這里的智能合約不能自動(dòng)執(zhí)行狞山,而是需要我用自己的私鑰進(jìn)行確認(rèn)全闷,智能合約保證的是沒有第三方機(jī)構(gòu)做擔(dān)保和資金周轉(zhuǎn)(比如支付寶),這就是智能合約的價(jià)值萍启。

其他的案例就不細(xì)說了总珠,比如穩(wěn)定幣需要鏈下的利率,保險(xiǎn)需要鏈下的病例或車況等勘纯,具體可以看這篇文章《Oracle—區(qū)塊鏈與現(xiàn)實(shí)世界的紐帶》局服。

2.5 目前公鏈上的預(yù)言機(jī)項(xiàng)目

目前在預(yù)言機(jī)領(lǐng)域探索的項(xiàng)目還不是很多,每一個(gè)項(xiàng)目的預(yù)言機(jī)解決方案都略有差異驳遵,我找了幾家典型的預(yù)言機(jī)項(xiàng)目淫奔,做一個(gè)簡(jiǎn)單的闡述。

Oraclize:為以太坊提供中心化預(yù)言機(jī)服務(wù)

Oraclize 依托亞馬遜 AWS 服務(wù)和 TLSNotary 技術(shù)堤结,是一個(gè)可證明的誠(chéng)實(shí)的預(yù)言機(jī)服務(wù)唆迁,不過它是中心化的,目前只能在以太坊網(wǎng)絡(luò)使用霍殴,而且gas費(fèi)較高媒惕。但是不妨礙它是目前很受歡迎的預(yù)言機(jī)服務(wù),也可能是因?yàn)檫€沒有更好的選擇吧来庭。這里有 Oraclize 詳細(xì)的使用說明:Oraclize Documentation

ChainLink:以太坊上第一個(gè)去中心化預(yù)言機(jī)解決方案

ChainLink 的解決方案是通過在鏈上的智能合約和鏈下的數(shù)據(jù)節(jié)點(diǎn)妒蔚,通過獎(jiǎng)懲機(jī)制和聚合模型的方式,進(jìn)行數(shù)據(jù)的請(qǐng)求和饋送月弛。不過也有一些不足肴盏,比如鏈?zhǔn)骄酆铣杀据^高,拓展性差帽衙,基于聲譽(yù)系統(tǒng)容易集中化菜皂。他們更關(guān)注支付場(chǎng)景的應(yīng)用,比如幫助銀行與企業(yè)之間建立智能合約厉萝。

歐鏈 OracleChain:EOS 上的第一個(gè)去中心化預(yù)言機(jī)解決方案

歐鏈很早就提出了預(yù)言機(jī)的想法和方案恍飘,采用自主的 PoRD 機(jī)制(Proof-of-Reputation&Deposit),本質(zhì)上是一種抵押代幣獎(jiǎng)懲機(jī)制的聲譽(yù)系統(tǒng)谴垫,獎(jiǎng)勵(lì)數(shù)據(jù)節(jié)點(diǎn)懲罰作惡節(jié)點(diǎn)章母,可以實(shí)現(xiàn) Augur、Gnosis 等預(yù)測(cè)市場(chǎng)應(yīng)用的功能翩剪,還能支撐對(duì)鏈外數(shù)據(jù)有更高頻率訪問需求的智能合約業(yè)務(wù)乳怎。預(yù)測(cè)市場(chǎng)的結(jié)果本身有時(shí)也可以作為 Oracle 的輸入數(shù)據(jù)源,歐鏈更像是預(yù)測(cè)市場(chǎng)前弯,而且不足是單純的聲譽(yù)系統(tǒng)容易集中化蚪缀。目前歐鏈只在 EOS 上開發(fā)秫逝。

DOS Network:支持多條主流公鏈的去中心化預(yù)言機(jī)服務(wù)網(wǎng)絡(luò)

DOS Network 是一個(gè) Layer-2 的預(yù)言機(jī)解決方案,它通過在鏈上部署一個(gè)輕量級(jí)智能合約询枚,鏈下是一個(gè) p2p 網(wǎng)絡(luò)违帆,服務(wù)節(jié)點(diǎn)的選取和數(shù)據(jù)驗(yàn)證采用 VRF+閾值簽名等技術(shù),保證了去中心化和數(shù)據(jù)安全金蜀,并達(dá)到快速反應(yīng)前方。可以適配所有主流公鏈廉油,比如以太坊惠险、EOS、Tron抒线、Thunder班巩。目前已在以太坊測(cè)試網(wǎng)發(fā)布 alpha 版本 https://dosnetwork.github.io/docs

我們也期待預(yù)言機(jī)技術(shù)的不斷成熟嘶炭,進(jìn)而促進(jìn)更多區(qū)塊鏈與現(xiàn)實(shí)世界進(jìn)行數(shù)據(jù)交互的 DApp 落地抱慌。

3,螞蟻BAAS實(shí)現(xiàn)外部預(yù)言機(jī)的技術(shù)概述

區(qū)塊鏈預(yù)言機(jī)(Oracle)是區(qū)塊鏈與外部世界交互的一種實(shí)現(xiàn)機(jī)制眨猎,它通過可信計(jì)算技術(shù)或者其他建立信任的約束關(guān)系抑进,在區(qū)塊鏈與外部世界間建立一種可信任的橋接機(jī)制,使得外部數(shù)據(jù)可以安全可靠地進(jìn)入?yún)^(qū)塊鏈睡陪。

外部數(shù)據(jù)源服務(wù)是基于可信執(zhí)行環(huán)境(Trusted Execution Environment寺渗,TEE)技術(shù)實(shí)現(xiàn)的區(qū)塊鏈預(yù)言機(jī)服務(wù),該服務(wù)旨在為區(qū)塊鏈智能合約提供可信訪問外部數(shù)據(jù)源能力兰迫。

外部數(shù)據(jù)源服務(wù)會(huì)在智能合約平臺(tái)部署一個(gè)外部數(shù)據(jù)源服務(wù)合約信殊,用戶合約通過調(diào)用該服務(wù)合約發(fā)送外部數(shù)據(jù)源請(qǐng)求,鏈下的 TEE 外部數(shù)據(jù)源服務(wù)對(duì)接該服務(wù)合約汁果,監(jiān)聽用戶的請(qǐng)求涡拘,然后去對(duì)應(yīng)的外部數(shù)據(jù)源取數(shù)據(jù),最后將結(jié)果返回給用戶合約据德。

3.1 實(shí)現(xiàn)原理

外部數(shù)據(jù)源服務(wù)使用 TEE 技術(shù)實(shí)現(xiàn)鳄乏,對(duì)于每筆外部數(shù)據(jù)請(qǐng)求都將在可信硬件環(huán)境中執(zhí)行〖可信硬件環(huán)境會(huì)驗(yàn)證外部數(shù)據(jù)源的 TLS 通訊證書以確認(rèn)數(shù)據(jù)源的身份橱野,通過 TLS 協(xié)議確保拿到的數(shù)據(jù)沒有被第三方篡改∩囊耄可信硬件環(huán)境得到數(shù)據(jù)后仲吏,會(huì)使用硬件私鑰對(duì)數(shù)據(jù)進(jìn)行簽名不铆,并返回給智能合約蝌焚,智能合約將自動(dòng)驗(yàn)證可信硬件的簽名裹唆,確保數(shù)據(jù)是可信硬件執(zhí)行結(jié)果,沒有被第三方篡改只洒,從而安全可靠地獲取來自指定外部數(shù)據(jù)源的數(shù)據(jù)许帐。

3.2 功能特性

  • 數(shù)據(jù)安全可信
    區(qū)塊鏈預(yù)言機(jī)底層使用 TEE 技術(shù)實(shí)現(xiàn),TEE 是一個(gè)安全隔離的執(zhí)行環(huán)境毕谴,提供隔離執(zhí)行成畦、可信應(yīng)用的完整性、可信數(shù)據(jù)的機(jī)密性涝开、安全存儲(chǔ)等安全特征循帐,使預(yù)言機(jī)服務(wù)數(shù)據(jù)服務(wù)安全可信。

  • 支持 HTTPS 協(xié)議
    通過 HTTPS 協(xié)議舀武,區(qū)塊鏈預(yù)言機(jī)會(huì)與目標(biāo)數(shù)據(jù)源建立端到端的安全通行通道拄养,并且可以完成對(duì)數(shù)據(jù)源的證書校驗(yàn)以確定身份,從而安全银舱、可靠地獲取來自指定外部數(shù)據(jù)源的數(shù)據(jù)瘪匿。

  • 支持 JSON API
    JSON 是一種輕量級(jí)的數(shù)據(jù)交換格式,廣泛地被采用為 API 的數(shù)據(jù)交換格式寻馏。區(qū)塊鏈預(yù)言機(jī)內(nèi)置 JSON 解析器棋弥,如果請(qǐng)求的 URL 響應(yīng)格式是 JSON 格式,可以在請(qǐng)求命令中設(shè)置 jsonpath 命令诚欠,使區(qū)塊鏈預(yù)言機(jī)根據(jù) jsonpath 讀取部分 JSON 數(shù)據(jù)顽染,只返回這部分?jǐn)?shù)據(jù)上鏈。

  • 支持訪問要權(quán)限認(rèn)證的 API
    一些 API 需要認(rèn)證授權(quán)訪問轰绵,例如使用 OAuth 2.0 協(xié)議實(shí)現(xiàn)的 API家乘,需要在請(qǐng)求中攜帶服務(wù)端認(rèn)證鑒權(quán)需要的參數(shù),但這些參數(shù)屬于私密信息不可泄露藏澳。這種情況下仁锯,利用 TEE 技術(shù)提供的機(jī)密性,與區(qū)塊鏈預(yù)言機(jī)的 TEE 環(huán)境建立端到端的加密信封翔悠,使得請(qǐng)求只在 TEE 硬件可信執(zhí)行環(huán)境里面解密业崖,從而不會(huì)泄露請(qǐng)求機(jī)密。

  • 高可用預(yù)言機(jī)集群
    區(qū)塊鏈預(yù)言機(jī)服務(wù)使用集群架構(gòu)實(shí)現(xiàn)蓄愁,為合約提供高可用的數(shù)據(jù)訪問服務(wù)双炕。

3.3 使用場(chǎng)景

外部數(shù)據(jù)源服務(wù)適用于以下任意場(chǎng)景:

  • 智能合約需要可信訪問 Web 數(shù)據(jù)。
  • 智能合約通過調(diào)用 Open API 使用互聯(lián)網(wǎng)服務(wù)撮抓。
  • 智能合約需要與外部系統(tǒng)交互妇斤。
  • 智能合約依賴公共現(xiàn)實(shí)事件,如天氣、賽事信息站超、航班信息等荸恕。

4,螞蟻BAAS的外部數(shù)據(jù)源服務(wù)(實(shí)現(xiàn)ORACLE預(yù)言機(jī))接口

外部數(shù)據(jù)源服務(wù)在區(qū)塊鏈上部署了區(qū)塊鏈預(yù)言機(jī)(Oracle)合約死相,提供異步查詢互聯(lián)網(wǎng)數(shù)據(jù)接口(CURL)供用戶合約使用融求。正常情況下,用戶合約調(diào)用預(yù)言機(jī)合約發(fā)起查詢請(qǐng)求后算撮,預(yù)言機(jī)合約在 1~3 個(gè)區(qū)塊內(nèi)就能得到外部數(shù)據(jù)源服務(wù)取回的數(shù)據(jù)生宛,然后回調(diào)用戶合約傳入數(shù)據(jù)。

4.1 開發(fā)流程

通過外部數(shù)據(jù)源服務(wù)肮柜,讓智能合約獲取指定外部數(shù)據(jù)源數(shù)據(jù)的開發(fā)流程如下:

  1. 在 BaaS 平臺(tái)上獲得預(yù)言機(jī)合約 ID(進(jìn)入聯(lián)盟陷舅,選擇 聯(lián)盟內(nèi)的鏈 > 目標(biāo)合約鏈 > 管理 > 跨鏈管理 可查看合約 ID)。
  2. 獲取合約 API 定義(OracleInterface.sol)审洞。
  3. 在用戶合約中引入合約 API 定義(OracleInterface.sol)蔑赘。
  4. 用戶合約實(shí)現(xiàn)回調(diào)接口,用于異步接收請(qǐng)求結(jié)果预明。
  5. 用戶請(qǐng)求需要使用 CURL 命令構(gòu)建外部數(shù)據(jù)源請(qǐng)求缩赛。
  6. 用戶合約向預(yù)言機(jī)合約發(fā)送查詢請(qǐng)求,具體參考 合約 API 說明撰糠。

4.2 合約 API 使用流程

用戶的智能合約調(diào)用預(yù)言機(jī)合約的 CURL 接口發(fā)起查詢請(qǐng)求酥馍,預(yù)言機(jī)合約同步返回查詢結(jié)果,即請(qǐng)求單據(jù)號(hào)(reqeust_id)阅酪。預(yù)言機(jī)合約獲取到查詢結(jié)果數(shù)據(jù)后旨袒,會(huì)異步回調(diào)查詢用戶合約的回調(diào)接口。

4.3 合約 API接口詳解

合約 API 定義

OracleInterface.sol 中定義了用戶合約與預(yù)言機(jī)合約的通信接口术辐,其中用戶通過 curlRequest 接口調(diào)用預(yù)言機(jī)合約砚尽。用戶合約需要實(shí)現(xiàn) oracleCallbackCurlResponse 接口,用于接收預(yù)言機(jī)合約的請(qǐng)求結(jié)果回調(diào)辉词。

// OracleInterface.sol
pragma solidity ^0.4.22;
// 使用預(yù)言機(jī) API 需要在用戶合約中開啟 ABIEncoderV2 特性
pragma experimental ABIEncoderV2; 
 
interface OracleInterface {
    /**
     * function: 發(fā)送 CURL 請(qǐng)求
     * parameters:
     *         _biz_id            : 用戶自定義的業(yè)務(wù)請(qǐng)求 ID
     *         _curl_cmd          : CURL 命令必孤,參考 CURL 命令使用文檔進(jìn)行構(gòu)造
     *         _if_callback       : 是否需要預(yù)言機(jī)將請(qǐng)求結(jié)果回調(diào)用戶合約
     *         _callback_identity : 預(yù)言機(jī)請(qǐng)求結(jié)果回調(diào)的合約 ID,可以是發(fā)送請(qǐng)求的合約瑞躺,也可以是其他合約
     *         _delay_time        : 該特性未激活敷搪,填 0 即可
     * return value:           : 預(yù)言機(jī)請(qǐng)求 ID,是預(yù)言機(jī)合約為本次請(qǐng)求生成的唯一請(qǐng)求 ID
     */
    function curlRequestDefault(bytes32 _biz_id, string _curl_cmd, bool _if_callback, identity _callback_identity, uint256 _delay_time) external returns (bytes32);
 
    /**
     * function: oracleCallbackCurlResponse
     * parameters:
     *         _request_id        : 預(yù)言機(jī)合約請(qǐng)求 ID(在發(fā)送請(qǐng)求時(shí)預(yù)言機(jī)合約會(huì)返回此 ID)
     *         _biz_id            : 用戶合約的業(yè)務(wù)請(qǐng)求 ID
     *         _error_code         : 請(qǐng)求結(jié)果碼幢哨,如果值是 0赡勘,則表示預(yù)言機(jī)請(qǐng)求處理成功;如果是其他值捞镰,則為請(qǐng)求處理失敗闸与,詳見合約錯(cuò)誤碼表
     *        _resp_status       : HTTP 響應(yīng)的狀態(tài)碼毙替,一般 200 表示 HTTP 請(qǐng)求處理成功,5xx 表示服務(wù)端處理錯(cuò)誤践樱,調(diào)用者可根據(jù)自己的使用場(chǎng)景做判斷
     *        _resp_header       : HTTP 響應(yīng)的 header厂画,如果 CURL 中指定了要返回 HTTP 響應(yīng)的 header,則回調(diào)時(shí)會(huì)返回對(duì)應(yīng)的值
     *        _resp_body         : http 響應(yīng)的 body
     *        _call_identity     : 發(fā)起該請(qǐng)求的合約 ID
     * return value            : 無
     */
    function oracleCallbackCurlResponse (bytes32 _request_id, bytes32 _biz_id, uint32 _error_code, uint32 _resp_status, bytes _resp_header, bytes _resp_body, identity _call_identity) external;
 
}

請(qǐng)求接口

curlRequestDefault

curlRequestDefault 是業(yè)務(wù)合約向預(yù)言機(jī)合約發(fā)送請(qǐng)求的接口映胁。

函數(shù)原型
 function curlRequestDefault(bytes32 _biz_id, string _curl_cmd, bool _if_callback, identity _callback_identity, uint256 _delay_time) external returns (bytes32);
請(qǐng)求參數(shù)
參數(shù) 必選 類型 說明
_biz_id true bytes32 用戶自定義的業(yè)務(wù)請(qǐng)求 ID,預(yù)言機(jī)合約回調(diào)結(jié)果時(shí)甲雅,會(huì)回傳此 ID解孙。
_curl_cmd true string CURL 命令,參考 CURL 命令使用說明 進(jìn)行構(gòu)造抛人。
_if_callback true bool 是否需要預(yù)言機(jī)將請(qǐng)求結(jié)果回調(diào)用戶合約弛姜。
_callback_identity true identity 預(yù)言機(jī)請(qǐng)求結(jié)果回調(diào)的合約 ID,可以是發(fā)送請(qǐng)求的合約妖枚,也可以是其他合約廷臼。
_delay_time true uint256 該特性未激活,填 0 即可绝页。

返回字段

返回字段 字段類型 說明
_request_Id bytes32 預(yù)言機(jī)請(qǐng)求 ID荠商,是預(yù)言機(jī)合約為本次請(qǐng)求生成的唯一請(qǐng)求 ID。

回調(diào)接口

oracleCallbackCurlResponse

回調(diào)接口需要業(yè)務(wù)合約實(shí)現(xiàn)续誉,用于接收預(yù)言機(jī)合約的請(qǐng)求結(jié)果回調(diào)莱没,如果未能正確實(shí)現(xiàn)該合約,則將無法接收請(qǐng)求結(jié)果酷鸦。

業(yè)務(wù)合約通過 oracleCallbackCurlResponse 來接收預(yù)言機(jī)合約的 CURL 請(qǐng)求結(jié)果回調(diào)饰躲。

函數(shù)原型
 function oracleCallbackCurlResponse (bytes32 _request_id, bytes32 _biz_id, uint32 _error_code, uint32 _resp_status, bytes _resp_header, bytes _resp_body, identity _call_identity) external;
請(qǐng)求參數(shù)
參數(shù) 必選 類型 說明
_request_id true bytes32 預(yù)言機(jī)合約請(qǐng)求 ID,在發(fā)送請(qǐng)求時(shí)預(yù)言機(jī)合約會(huì)返回此 ID臼隔。
_biz_id true bytes32 用戶合約的業(yè)務(wù)請(qǐng)求 ID
_error_code true uint32 請(qǐng)求結(jié)果碼嘹裂,如果值是 0,則表示預(yù)言機(jī)請(qǐng)求處理成功摔握;如果是其他值寄狼,則為請(qǐng)求處理失敗,詳見 合約錯(cuò)誤碼表氨淌。
_resp_status true uint32 HTTP 響應(yīng)的狀態(tài)碼例嘱,一般 200 表示 HTTP 請(qǐng)求處理成功,5xx 表示服務(wù)端處理錯(cuò)誤宁舰,調(diào)用者可根據(jù)自己的使用場(chǎng)景做判斷拼卵。
_resp_header true bytes HTTP 響應(yīng)的 header,如果 CURL 中指定了要返回 HTTP 響應(yīng)的 header蛮艰,則回調(diào)時(shí)會(huì)返回對(duì)應(yīng)的值腋腮。
_resp_body true bytes HTTP 響應(yīng)的 body
_call_identity true identity 發(fā)起該請(qǐng)求的合約 ID

返回字段

無返回字段。

示例

pragma solidity ^0.4.22;
// 使用預(yù)言機(jī) API 需要在用戶合約中開啟 ABIEncoderV2 特性
pragma experimental ABIEncoderV2; 
 
import "./OracleInterface.sol";
 
// 實(shí)現(xiàn)一個(gè)demo合約
contract BizContract {
 
    // 業(yè)務(wù) ID 與預(yù)言機(jī)請(qǐng)求 ID 的關(guān)聯(lián)關(guān)系
    mapping(bytes32 => bytes32) request_id;
 
    // 調(diào)用預(yù)言機(jī)合約的 CURL 接口
    function rawCURLRequest(identity oracle_address, bytes32 biz_id, string cmd) public{
        // 1. 跨合約調(diào)用,需要通過合約 API 定義及合約 ID 生成一個(gè)合約對(duì)象
        OracleInterface oracle = OracleInterface(oracle_address);
 
        // 
        // 2. 發(fā)送 CURL 請(qǐng)求
        //   (例如查詢股票行情信息即寡,cmd 參數(shù)的值可以是“https://hq.sinajs.cn/list=hk00941”)
         bytes32 request_id = oracle.curlRequest(service_id, biz_id, cmd, true, this, 0);
          // 3. 記錄預(yù)言機(jī)返回的request id
         request_id[biz_id] = request_id;
 
        // 4. 請(qǐng)求階段結(jié)束徊哑,等待回調(diào)
        return;
    }
 
    // 業(yè)務(wù)合約用于接收預(yù)言機(jī)合約的 CURL 請(qǐng)求結(jié)果回調(diào)
    function oracleCallbackCurlResponse (bytes32 _request_id, bytes32 _biz_id, uint32 _error_code, uint32 _web_status, bytes _resp_header, bytes _resp_body, identity _call_identity) external {
 
        // 業(yè)務(wù)處理回調(diào)結(jié)果
    }
}

4.4 CURL 命令使用說明

本文主要對(duì)外部數(shù)據(jù)源服務(wù)涉及到的 CURL 命令的用法進(jìn)行說明。

說明:當(dāng)前外部數(shù)據(jù)源服務(wù)版本暫不支持 HTTP 分塊傳輸編碼聪富,即不支持 HTTP 響應(yīng)的 Transfer-Encoding 為 chunked莺丑,后續(xù)版本會(huì)支持該特性。

NAME
    curl
 
VERSION
    1.0.0_BETA
 
SYNOPSIS
    curl https://address[:port][/path][?args] [options]
 
DESCRIPTION    
    CURL 命令是預(yù)言機(jī)提供的 Web API 接口必要傳入?yún)?shù)之一墩蔓。CURL 命令描述了指定預(yù)言機(jī)訪問目的互聯(lián)網(wǎng)資源的 URI梢莽,以及其他可選配置項(xiàng)。
    當(dāng)前外部數(shù)據(jù)源服務(wù)版本暫不支持 HTTP 分塊傳輸編碼奸披,即不支持 HTTP 響應(yīng)的 Transfer-Encoding 為 chunked昏名,后續(xù)版本會(huì)支持該特性。
 
OPTIONS
    --request <GET|POST>
        HTTP 訪問的方法阵面,支持 GET 和 POST轻局。缺省使用 GET 方法。
        e.g. 
            --request GET
            --request POST
 
    --header <header:value>
        指定 HTTP 請(qǐng)求中附帶的 header 信息样刷。
        header 名和 header 值使用冒號(hào)分割仑扑。如果 header 名或者值包含空格,應(yīng)該使用單引號(hào)將其作為整體包起來置鼻,譬如 --header 'content-type:plain text'夫壁。
        --header 選項(xiàng)可以重復(fù)使用多次來配置多對(duì) header,最多不超過 100 對(duì)沃疮。
        以下為保留 header盒让,用戶配置不生效:"Host"、"Accept"司蔬、"User-Agent"邑茄、"Connection"、"Content-Length"俊啼。
        e.g.
            --header SomeHeader:SomeValue
            --header 'Some Header:Some Value' --header k2:v2
 
    --data <value>
        HTTP 使用 POST 方法時(shí)附帶的 body 信息肺缕,建議使用單引號(hào)包起來。
        e.g.
            --data 'Hello world!'
 
    --json-path <value> 
        指定了對(duì) HTTP 原始響應(yīng) body 進(jìn)行 JSONPath 處理授帕。
        JSONPath 語法說明:https://goessner.net/articles/JsonPath/
        目前支持:$.[]*
        e.g.
            --json-path '$.obj'  取子對(duì)象
            --json-path '$[0]'   從數(shù)組取下標(biāo)
            --json-path "$['obj']" 取子對(duì)象
            --json-path '$[0,1].obj' 取多個(gè)對(duì)象
 
    --body-plain-text 
        指定了返回正文內(nèi)容格式同木,缺省 --body-plain-text。
 
    --resp-header <header>
        指定了從 HTTP 原始響應(yīng) header 全集中返回給查詢方的子集跛十。
        如果指定的 header 不在原始響應(yīng) header 全集中彤路,則返回 value 為空字符串。
        可以指定多次 --resp-header 來指定返回多個(gè) header芥映。
 
    --header-plain-text
        指定了返回 HTTP 響應(yīng) header 的格式洲尊,缺省 --header-plain-text远豺。
        具體格式為每個(gè)"header:value"占一行,使用 \r\n 換行坞嘀。
 
    --header-to-json
        指定了返回 HTTP 響應(yīng) header 使用 JSON 格式組織躯护,每個(gè) header:value 為頂層 kv。
 
    --encrypted-envelope <value>
        加密信封字段丽涩,傳遞機(jī)密信息給預(yù)言機(jī) TEE 實(shí)例棺滞。
        加密信封為以下 JSON 格式字符串的 BASE64 編碼:
        { "cipher_text": "", // 機(jī)密信息密文,使用 aes-256-gcm 加密
          "aes_iv":"", // 對(duì)稱加密 iv
          "gcm_aad": "", // 對(duì)稱加密 add
          "gcm_tag": "" // 對(duì)稱加密 tag
          "encrypted_aes_key": "" // 經(jīng)過 TEE 公鑰加密后的對(duì)稱加密 key
          "rsa_key": "", // TEE 實(shí)例的 RSA 公鑰
         }
        其中 cipher_text 字段為機(jī)密信息矢渊,值為以下固定結(jié)構(gòu)的 JSON 字符串:
        {"macro_replacement":{}, "content_hash":"", "nonce_str":"", "timestamp":"", "time_to_live":""}
        其中 macro_replacement 存放宏替換內(nèi)容继准,可以在 URL path、body昆淡、header 中嵌入宏锰瘸,然后將替換值寫在macro_replacement 中刽严,只對(duì) TEE 可見昂灵。合法宏只能從 'ORACLE_SUB_MACRO_0' ~ 'ORACLE_SUB_MACRO_4' 選擇,并且替換值中不能包括合法宏舞萄。
        content_hash 存放 CURL 命令明文部分內(nèi)容計(jì)算的哈希值眨补,鎖定加密信封只能與鎖定的明文一起使用。
        nonce_str倒脓、timestamp撑螺、time_to_live 暫未啟用。
        機(jī)密信息使用 AES/GCM/NoPadding 加密崎弃,再用 TEE 的公鑰使用(TEE 的公鑰在跨鏈服務(wù)頁面中查詢)RSA/None/OAEPPadding 加密 AES 密鑰甘晤。

4.5 預(yù)言機(jī)合約錯(cuò)誤碼

錯(cuò)誤碼 16 進(jìn)制錯(cuò)誤碼值 10 進(jìn)制錯(cuò)誤碼值 描述 解決方法
OE_SUCCESS 0x0000 0 查詢成功
OE_UNKNOWN_ERROR 0x0002 2 未知錯(cuò)誤 聯(lián)系管理員。
OE_QUERY_COMMAND_PARSE_ERROR 0x1000 4096 命令解析錯(cuò)誤 檢查命令語法是否正確饲做。
OE_REQUEST_QUERY_COMMAND_NONSUPPORT 0x1001 4097 非法命令 檢查命令线婚,目前僅支持 CURL。
OE_TLS_ERROR 0x1002 4098 網(wǎng)絡(luò)連接錯(cuò)誤 聯(lián)系管理員盆均。
OE_UNRECOGNIZED_OPTION 0x1200 4608 非法選項(xiàng) 查命令選項(xiàng)是否拼寫有誤塞弊,檢查命令選項(xiàng)是否存在拼寫錯(cuò)誤或者存在 CURL 命令使用說明 中沒有的選項(xiàng)。
OE_OPTION_CONFLICTS 0x1201 4609 選項(xiàng)存在沖突 檢查是否同時(shí)使用了語義互斥的命令選項(xiàng)泪姨。
OE_INVALID_JSONPATH 0x1202 4610 JSONPath 語法錯(cuò)誤 檢查 JSONPath游沿。
OE_REQUEST_ENVELOPE_PARSE_ERROR 0x1203 4611 信封解析錯(cuò)誤 檢查信封字段。
OE_REQUEST_ENVELOPE_MISS_FIELD 0x1204 4612 信封缺失字段 檢查信封是否缺失必要字段肮砾,具體參考 CURL 命令使用說明诀黍。
OE_REQUEST_ENVELOPE_DECRYPT_ERROR 0x1205 4613 信封解密失敗 檢查信封是否使用了規(guī)定的加密算法,具體參考 CURL 命令使用說明仗处。
OE_REQUEST_ENVELOPE_CONTENT_PARSE_ERROR 0x1206 4614 信封內(nèi)容解析勢(shì)必 檢查信封結(jié)構(gòu)是否遵循規(guī)定的結(jié)構(gòu)蔗草,具體參考 CURL 命令使用說明咒彤。
OE_REQUEST_ENVELOPE_CONTENT_MISS_FIELD 0x1207 4615 信封內(nèi)容缺失字段 檢查信封是否缺失必要字段,具體參考 CURL 命令使用說明咒精。
OE_REQUEST_ENVELOPE_CONTENT_HASH_CHECK_ERROR 0x1208 4616 信封內(nèi)容哈希不一致 檢查是否采用了規(guī)定的哈希算法镶柱,具體參考 CURL 命令使用說明
OE_REQUEST_ENVELOPE_CONTENT_MACRO_CHECK_ERROR 0x1209 4617 信封內(nèi)容宏錯(cuò)誤 檢查信封中關(guān)于宏的使用方法是否正確模叙。
OE_CONTENT_EXCEED_LIMIT 0x1400 5120 返回原始內(nèi)容超長(zhǎng) 檢查數(shù)據(jù)源串長(zhǎng)度是否超出限制歇拆。
OE_RESPONSE_ERROR 0x1401 5121 數(shù)據(jù)源返回失敗 遠(yuǎn)端數(shù)據(jù)源返回失敗,需要用戶根據(jù)需求重新發(fā)起請(qǐng)求范咨。
OE_JSON_PATH_NOT_IN_CONTENT 0x1402 5122 返回內(nèi)容中不存在指定 JSONPath 檢查數(shù)據(jù)源的返回?cái)?shù)據(jù)格式故觅,根據(jù)實(shí)際情況使用 JSONPath 命令。
OE_JSON_PATH_FOR_NON_JSON 0x1403 5123 返回內(nèi)容不是 JSON 但指定了 JSONPath渠啊。 檢查數(shù)據(jù)源的返回?cái)?shù)據(jù)格式是否為 JSON输吏,否則不能使用 JSONPath 命令。
OE_CURL_INVALID_SCHEMA 0x2000 8192 非法 URL Schema 僅支持 HTTPS替蛉。
OE_CURL_INVALID_PORT 0x2001 8193 非法端口 檢查端口是否有效贯溅,可以使用 Linux CURL 工具進(jìn)行測(cè)試。
OE_CURL_INVALID_PATH 0x2002 8194 非法路徑 檢查 path 的語法是否正確躲查,具體參考 CURL 命令使用說明它浅。
OE_CURL_HEADER_NUM_EXCEED_LIMIT 0x2003 8195 —header 選項(xiàng)個(gè)數(shù)過多 最多指定 100 個(gè) header。
OE_CURL_HTTP_HEADER_PARSE_ERROR 0x2004 8196 —header 的值格式錯(cuò)誤 必須是“key:value”镣煮。
OE_CURL_METHOD_NON_SUPPORTED 0x2005 8197 非法的請(qǐng)求方法 僅支持 GET 和 POST 方法姐霍。
REJECT_SYSTEM_ERROR 0x5000 20480 服務(wù)處理請(qǐng)求解析失敗,拒絕該請(qǐng)求典唇。 預(yù)言機(jī)系統(tǒng)處理該筆請(qǐng)求錯(cuò)誤镊折,需要客戶端重新發(fā)起請(qǐng)求。
REJECT_ILLEGAL_REQUEST 0x5100 20736 服務(wù)處理請(qǐng)求解析失敗介衔,拒絕該請(qǐng)求恨胚。 非法 CURL 語法。檢查 CURL 命令是否按照 CURL 命令使用說明 中的約束構(gòu)建夜牡。
REJECT_ILLEGAL_CMD 0x5101 20737 服務(wù)處理請(qǐng)求解析失敗与纽,拒絕該請(qǐng)求 非法 CURL 語法。檢查 CURL 命令是否按照 CURL 命令使用說明 中的約束構(gòu)建塘装。
REJECT_ILLEGAL_SERVICE_ID 0x5102 20738 不存在請(qǐng)求指定的 Service ID急迂。 使用正確的 Service ID。
REJECT_OVERSIZE_CMD 0x5104 20740 請(qǐng)求內(nèi)容過大 CURL 命令不大于 10240 字節(jié)蹦肴。
REJECT_ENVELOPE_ILLEGAL_BASE64 0x5105 20741 加密信封 Base64 解碼失敗 檢查加密信封 Base64 編碼僚碎。
REJECT_ENVELOPE_NOT_EXIST_KEY 0x5106 20742 加密信封的 key 不存在 檢查加密信封的結(jié)構(gòu)是否正確傳入 key。
REJECT_ENVELOPE_UNKNOWN_KEY 0x5107 20743 加密信封的 key 未能識(shí)別 檢查加密信封的 key 是否使用約定的用法傳入阴幌。
REJECT_BY_REQUEST_FILTER 0x5301 21249 請(qǐng)求白名單限制 配置請(qǐng)求白名單勺阐。
REJECT_BY_RESPONSE_FILTER 0x5302 21250 請(qǐng)求結(jié)果安全校驗(yàn)失敗 請(qǐng)求結(jié)果中內(nèi)容安全處理失敗卷中,檢查數(shù)據(jù)源的安全性。

5. 參考

(1)外部數(shù)據(jù)源服務(wù)
https://tech.antfin.com/docs/2/108575
(2)預(yù)言機(jī)(oracle)2.0:用完即走渊抽,為智能合約可信地與外部世界交互提供必要條件(上)
https://zhuanlan.zhihu.com/p/35007714
(3)什么是區(qū)塊鏈預(yù)言機(jī)(BlockChain Oracle)
https://zhuanlan.zhihu.com/p/52369816

截止2019.04.10蟆豫,針對(duì)創(chuàng)新大賽的TEE硬件隱私合約鏈的外部預(yù)言機(jī)功能還未開放出來,但是標(biāo)準(zhǔn)合約鏈的外部預(yù)言機(jī)ORACLE功能已開放懒闷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末十减,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子愤估,更是在濱河造成了極大的恐慌帮辟,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玩焰,死亡現(xiàn)場(chǎng)離奇詭異由驹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)昔园,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門蔓榄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蒿赢,你說我怎么就攤上這事润樱≡ィ” “怎么了羡棵?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嗅钻。 經(jīng)常有香客問我皂冰,道長(zhǎng),這世上最難降的妖魔是什么养篓? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任秃流,我火速辦了婚禮,結(jié)果婚禮上柳弄,老公的妹妹穿的比我還像新娘舶胀。我一直安慰自己,他們只是感情好碧注,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布嚣伐。 她就那樣靜靜地躺著,像睡著了一般萍丐。 火紅的嫁衣襯著肌膚如雪轩端。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天逝变,我揣著相機(jī)與錄音基茵,去河邊找鬼奋构。 笑死,一個(gè)胖子當(dāng)著我的面吹牛拱层,可吹牛的內(nèi)容都是我干的弥臼。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼根灯,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼醋火!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起箱吕,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤芥驳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后茬高,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兆旬,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年怎栽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丽猬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡熏瞄,死狀恐怖脚祟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情强饮,我是刑警寧澤由桌,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站邮丰,受9級(jí)特大地震影響行您,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜剪廉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一娃循、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧斗蒋,春花似錦捌斧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至爆哑,卻和暖如春洞难,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工队贱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留色冀,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓柱嫌,卻偏偏與公主長(zhǎng)得像锋恬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子编丘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 預(yù)言機(jī)(Oracle)是區(qū)塊鏈中非常重要的一個(gè)功能与学,但我發(fā)現(xiàn)很少有人討論,也可能很多人對(duì)此并不了解嘉抓。而網(wǎng)上關(guān)于預(yù)言...
    筆名輝哥閱讀 1,369評(píng)論 0 50
  • 清淺時(shí)光索守,歲月靜好。 窗外抑片,又下起了毛毛細(xì)雨卵佛,不想出去散步,于是打開電腦敞斋,靜靜聽著音樂截汪,一切都是那么美...
    石上清泉之心語閱讀 411評(píng)論 1 2
  • 成語有“水至清則無魚,人至察則無徒”植捎,意思是水太清了衙解,魚就無法生存;要求別人太嚴(yán)了焰枢,就沒有伙伴隅要。 養(yǎng)了盆碗蓮炊苫,買的...
    樸姬淑閱讀 278評(píng)論 0 0
  • 今天的主題:一次只能養(yǎng)成一個(gè)好習(xí)慣铭若! 習(xí)慣有好有壞灰追,好習(xí)慣對(duì)我們的人生非常有助益架诞,它能夠讓你做事高效拟淮,生活也變得有...
    Rose二姐閱讀 273評(píng)論 0 2
  • 鑠鑠: 晚上好。 今天跟你視頻真的挺開心的谴忧,幾件事情都很好很泊。 一是你的作業(yè)真的昨天就寫完了,把最應(yīng)該做的事情第一時(shí)...
    菜芯雞蛋羹閱讀 77評(píng)論 0 1