再談預(yù)言機:Oracle如何重新定義智能合約?|Neo專欄

上期專欄
《設(shè)計預(yù)言機面臨哪些技術(shù)挑戰(zhàn)?》
為我們介紹了「什么是Oracle」、
「Oracle解決什么問題」、
「設(shè)計Oracle的過程中要面臨哪些技術(shù)難題」等問題??
而在本期專欄中,作者將詳細解釋
預(yù)言機是如何實現(xiàn)
「把現(xiàn)實世界中的數(shù)據(jù)以交易的形式記錄在區(qū)塊鏈上」
這一功能的?
「N3預(yù)言機有哪些問題亟需解決?」??
快來一起來看看吧????
制約區(qū)塊鏈發(fā)展的一個重要因素是落地,也就是把區(qū)塊鏈技術(shù)用于現(xiàn)實生活中。為此我們就需要不停地設(shè)想各種可能需要用到區(qū)塊鏈的場景,比如游戲,比如發(fā)票,比如非同質(zhì)化通證。可是這些場景依然很單薄,完全不能支持大家對區(qū)塊鏈技術(shù)的期望,更無法發(fā)揮區(qū)塊鏈技術(shù)的實力。就好像現(xiàn)在的5G技術(shù),空有一身本領(lǐng),到頭來大家只是用來做Speedtest。
但是為什么我們無法找到更多適合區(qū)塊鏈的場景呢?因為區(qū)塊鏈技術(shù)太封閉,為了安全,區(qū)塊鏈只信任自己鏈上的數(shù)據(jù),不接受鏈外的數(shù)據(jù)流,比如UTXO全是鏈上的交易構(gòu)造的,比如Neo Legacy里的智能合約執(zhí)行的時候只能通過少數(shù)接口獲取鏈上的數(shù)據(jù)。所以想跟區(qū)塊鏈打交道,那么你的場景里就不能有對外界信息的依賴。但是現(xiàn)實世界中大多場景都需要大量的信息交互,你打開手機,哪有應(yīng)用不需要聯(lián)網(wǎng)的。
●比如訂票軟件,你需要實時的機票余票信息和價格信息。
●比如交易軟件,你需要物價信息。
●比如快遞軟件,你需要最新的物流信息。
很無奈,這些都沒辦法用區(qū)塊鏈去做。
因此,為了拓寬區(qū)塊鏈的應(yīng)用場景,充分發(fā)揮區(qū)塊鏈的潛力,可以給區(qū)塊鏈投喂鏈外數(shù)據(jù)流的交互方式——預(yù)言機,應(yīng)運而生。預(yù)言機就是一個可以把現(xiàn)實世界中的數(shù)據(jù)以交易的形式記錄在區(qū)塊鏈上的機制。熟悉計算機的小伙伴可以把預(yù)言機理解成一個現(xiàn)實世界和區(qū)塊鏈之間的巨大cache。由于現(xiàn)實世界的數(shù)據(jù)在語義上與區(qū)塊鏈是存在巨大的gap的,比如現(xiàn)實世界的數(shù)據(jù)可能會實時變化,可能有多個數(shù)據(jù)源,可能需要復(fù)雜的計算或者轉(zhuǎn)換,這些都無法在區(qū)塊鏈共識的過程中解決,否則不同的共識節(jié)點在驗證交易的時候可能獲取到的數(shù)據(jù)都不同,但是如果共識節(jié)點不從現(xiàn)實世界直接取數(shù)據(jù),而是從“cache”里取,那么就可以保證各個節(jié)點在驗證交易時輸入數(shù)據(jù)的一致性。因此需要在將數(shù)據(jù)寫入?yún)^(qū)塊鏈之前,有一個處理數(shù)據(jù)的過程,把數(shù)據(jù)處理成區(qū)塊鏈可以接受的形式,比如把實時數(shù)據(jù)取樣出一個當前的固定數(shù)據(jù)。

預(yù)言機的實現(xiàn)大致有三種,一種是中心化的第三方,第二種是可信的數(shù)據(jù)提供方,第三種則是去中心化的基于共識機制的預(yù)言機。在N3中則是因地制宜地使用了拓展性更好的去中心化預(yù)言機機制。
根據(jù)文檔,N3是指定一些預(yù)言機節(jié)點來對交易的數(shù)據(jù)請求結(jié)果進行共識,以此來避免可能存在的預(yù)言機偽造數(shù)據(jù)問題。流程是:用戶發(fā)起交易,在交易里觸發(fā)智能合約里的預(yù)言機請求,這個請求的本質(zhì)其實是調(diào)用N3內(nèi)置的原生預(yù)言機合約里的request方法:
/// <summary>
/// 創(chuàng)建 Oracle Request 請求數(shù)據(jù)
/// </summary>
/// <param name="url">訪問資源路徑,最大長度為 256 字節(jié).</param>
/// <param name="filter">過濾器,用于在從數(shù)據(jù)源返回的結(jié)果中過濾出有用信息</param>
/// <param name="callback">回調(diào)函數(shù)方法名</param>
/// <param name="userData">用戶自定義數(shù)據(jù)</param>
/// <param name="gasForResponse">回調(diào)函數(shù)執(zhí)行預(yù)付款</param>
void Request(string url, string filter, string callback, object userData, long gasForResponse);
原生合約會根據(jù)參數(shù)構(gòu)建一個請求,然后預(yù)言機節(jié)點根據(jù)請求來獲取數(shù)據(jù),在預(yù)言機節(jié)點完成數(shù)據(jù)采集之后,會生成一個新的交易并在交易里調(diào)用用戶合約里的回調(diào)函數(shù)。所以觸發(fā)一次N3的預(yù)言機,將會有兩筆交易被寫入到區(qū)塊鏈里,一筆是觸發(fā)預(yù)言機,另一筆是回調(diào)。這樣通過URL機制將數(shù)據(jù)源的選擇權(quán)交給合約開發(fā)者或者數(shù)據(jù)調(diào)用者,進而規(guī)避了預(yù)言機本身對數(shù)據(jù)源的信任問題,異步回調(diào)機制則解決了智能合約調(diào)用預(yù)言機延遲過大的話可能會Block掉共識過程的問題。

按照這個邏輯,理論上如果我們要觸發(fā)預(yù)言機,那么在調(diào)用預(yù)言機之后就應(yīng)該會終止當前合約的執(zhí)行,所以在一個合約方法里寫在觸發(fā)預(yù)言機語句之后的代碼應(yīng)該是不會執(zhí)行的。不過這里由于一些環(huán)境配置問題,我還沒辦法做驗證。
預(yù)言機雖然被定義為用來獲取數(shù)據(jù)的工具,但是其實預(yù)言機也可以用來做一些比較迷的操作。因為調(diào)用預(yù)言機這個過程,實質(zhì)上跟異步調(diào)用別的合約沒有什么太大的區(qū)別,甚至N3里就是把預(yù)言機內(nèi)置為一個原生合約。這就意味著,我們可以把預(yù)言機作為一個智能合約的外掛接口,把一些原本應(yīng)該寫入智能合約的邏輯寫入在合約之外。比如計算量非常大的任務(wù),我們就可以把任務(wù)通過預(yù)言機發(fā)到鏈外,然后在鏈外執(zhí)行再返回結(jié)果。再比如一些我們想隱藏起來的邏輯,比如隨機數(shù)生成算法,也可以通過預(yù)言機把這部分功能遷移到鏈外。
N3預(yù)言機系統(tǒng)現(xiàn)存問題
雖然N3原生的預(yù)言機系統(tǒng)很好很強大,依然有一些問題沒有能夠完美解決:
1N3的預(yù)言機作為分布式系統(tǒng),其處理變化頻率過快的數(shù)據(jù)比較麻煩。比如比特幣的價格,基本上是實時變化的,因此不同的預(yù)言機節(jié)點在獲取比特幣價格的時候,很可能不同的節(jié)點獲取到的價格就有零點零幾的不同,從而導(dǎo)致預(yù)言機共識失敗。雖然這也可以通過用戶優(yōu)化數(shù)據(jù)格式在一定程度上解決。
2預(yù)言機系統(tǒng)是一個異步回調(diào)系統(tǒng),再加上存在共識過程,因此其獲取到的數(shù)據(jù)相較于觸發(fā)交易來說存在較大的延遲。比如你當前看著機票的價格很低,然后立即發(fā)送一筆交易到鏈上,你的交易立即得到的了執(zhí)行,這卻并不意味著你能獲取到的價格就是交易執(zhí)行時的價格,畢竟預(yù)言機的回調(diào)交易并不是和你的觸發(fā)交易同步發(fā)生的。
3還有一個比較大的問題是數(shù)據(jù)源的可信程度,我們允許用戶通過預(yù)言機將鏈外的數(shù)據(jù)引入到鏈內(nèi),這在相當大的程度上將鏈外的不可信因素引入到了區(qū)塊鏈。以前攻擊區(qū)塊鏈就只能攻擊區(qū)塊鏈節(jié)點本身,這個過程由共識協(xié)議來保護。可是當我們引入了預(yù)言機后,攻擊區(qū)塊鏈的方式就變得多樣了,因為黑客可以通過攻擊合約里指定的預(yù)言機數(shù)據(jù)源來將攻擊的影響輻射到區(qū)塊鏈里。此外,不可靠的合約開發(fā)者也可能通過預(yù)言機機制在智能合約里引入不可知的后門,畢竟通過預(yù)言機調(diào)用的部分功能并沒有寫入在區(qū)塊鏈里,因此不可靠的開發(fā)者完全可以在神不知鬼不覺的情況下更改系統(tǒng)邏輯。
4最后還有一個問題是數(shù)據(jù)的冗余。我在前文中提到預(yù)言機的功能類似于在區(qū)塊鏈和數(shù)據(jù)源之間加了一層數(shù)據(jù)緩存以保證數(shù)據(jù)的可信??墒菍嶋H上這個緩存只是我抽象出來便于大家理解的,實際上N3的預(yù)言機在處理數(shù)據(jù)的時候并不會像緩存那樣對數(shù)據(jù)進行保存以便于后續(xù)的請求。相反的,N3的預(yù)言機請求只跟用戶發(fā)起的觸發(fā)交易相關(guān),用戶發(fā)起了多少筆觸發(fā)交易,就會有多少對應(yīng)的預(yù)言機請求,即使在同一個區(qū)塊內(nèi)有許許多多的交易都在請求同一個數(shù)據(jù),這樣就難免導(dǎo)致預(yù)言機寫入大量的冗余到區(qū)塊鏈上。
以上。
All in One · All in Neo
Neo是一個由社區(qū)驅(qū)動的開源平臺。利用區(qū)塊鏈技術(shù)與數(shù)字身份,開發(fā)者可以通過智能合約實現(xiàn)資產(chǎn)管理數(shù)字化與自動化。Neo致力于通過分布式網(wǎng)絡(luò)建設(shè)下一代互聯(lián)網(wǎng)基礎(chǔ)設(shè)施,為區(qū)塊鏈技術(shù)大規(guī)模落地奠定基礎(chǔ),以實現(xiàn)智能經(jīng)濟的宏大愿景。
自2016年上線至今,Neo主網(wǎng)已穩(wěn)定運行超過四年。全新版本Neo N3預(yù)將于2021年發(fā)布,將提供更高吞吐量、更強穩(wěn)定性與安全性,并帶來優(yōu)化的智能合約系統(tǒng)及功能豐富的基礎(chǔ)設(shè)施集合,旨在賦能開發(fā)者并加速企業(yè)級區(qū)塊鏈創(chuàng)新。


