您的位置:首頁 > 區塊鏈 >

        oracle可查詢JSON API 可保存請求和答案

        2019-07-15 15:19:38 來源: 區塊鏈研究實驗室

        背景以太坊中的智能合約可以為廣泛的應用提供動力,但由于區塊鏈的性質,智能合約缺乏必要的功能:互聯網連接。以太坊被設計為完全確定性,

        背景

        以太坊中的智能合約可以為廣泛的應用提供動力,但由于區塊鏈的性質,智能合約缺乏必要的功能:互聯網連接。

        以太坊被設計為完全確定性,這意味著如果有人下載整個網絡歷史并重放它們,它們應該總是以相同的狀態結束。確定性是必要的,這樣節點就可以達成一致。

        但是,互聯網具有不是確定性,在某個時間點查詢API的智能合約,不能保證以后查詢相同的API會得到相同的結果。 Web上的API和數據發生了變化。因此,智能合約本質上缺乏連通性。

        oracle這個名字來源于這樣一個事實:從歷史上講,oracles是事實的來源。這就是我們所需要的事實。

        對于智能合約來說,預言機就是每個智能合約的輸入參數。所有智能合約都繞不開預言機的輸入數據,輸入數據決定了智能合約的運行結果。通過向區塊鏈中添加具有所需信息的交易,智能合約可以運行并始終獲取相同的信息,因為數據都是從區塊中進行檢索。

        解決方案

        我們將創建一個oracle服務,該服務可以查詢JSON API并從API響應中檢索單個值。 oracle將保存所有請求和答案,并將擁有一組預定義的利益相關者。

        利益相關者是運行node.js服務的帳戶,該服務查詢API并返回對oracle的響應。 oracle還具有必須接收的最小數量的相等響應,以確認所提供的答案是有效的。

        這樣競爭方依賴于oracle來支持他們的合約,但是如果其中一方(節點)試圖去操縱結果,那就無法實現了。因為他們同意預定義了法定人數的等量答案結果。

        oracle包含兩個組件。on-chain oracle(智能合約)和off-chain oracle服務(node.js服務器)。

        on-chain oracle是一個智能合約,它有一個公共函數createRequest,接收URL,查詢和要檢索的屬性。然后啟動一個事件來提醒新鏈接oracle的新請求。

        off-chain oracle由不同方部署的幾個node.js服務組成,這些服務將查詢API并將響應返回給合約。

        on-chain Oracle會驗證是否已達到最小數量的相等響應,如果已達到,則會發出一個事件,表明其已就價值達成共識,以便查詢Oracle的客戶機智能合約知道其已收到響應。

        On-chain Oracle實施

        我們用約定的條款定義Oracle合同:最低法定人數和Oracle總數。對于這個例子,有三個利益相關者,為了達成共識,3個中的2個必須提供相同的答案。

        pragma solidity >=0.4.21 <0.6.0;

        contract Oracle {

        Request[] requests; //list of requests made to the contract

        uint currentId = 0; //increasing request id

        uint minQuorum = 2; //minimum number of responses to receive before declaring final result

        uint totalOracleCount = 3; // Hardcoded oracle count

        }

        然后我們添加Request Struct,它將保存請求:

        // defines a general api request

        struct Request {

        uint id; //request id

        string urlToQuery; //API url

        string attributeToFetch; //json attribute (key) to retrieve in the response

        string agreedValue; //value from key

        mapping(uint => string) anwers; //answers provided by the oracles

        mapping(address => uint) quorum; //oracles which will query the answer (1=oracle hasn't voted, 2=oracle has voted)

        }

        現在我們可以創建公共函數createRequest,客戶端智能合約(任何想要使用oracle服務的合同)都會調用:

        function createRequest (

        string memory _urlToQuery,

        string memory _attributeToFetch

        )

        public

        {

        uint lenght = requests.push(Request(currentId, _urlToQuery, _attributeToFetch, ""));

        Request storage r = requests[lenght-1];

        // Hardcoded oracles address

        r.quorum[address(0x6c2339b46F41a06f09CA0051ddAD54D1e582bA77)] = 1;

        r.quorum[address(0xb5346CF224c02186606e5f89EACC21eC25398077)] = 1;

        r.quorum[address(0xa2997F1CA363D11a0a35bB1Ac0Ff7849bc13e914)] = 1;

        // launch an event to be detected by oracle outside of blockchain

        emit NewRequest (

        currentId,

        _urlToQuery,

        _attributeToFetch

        );

        // increase request id

        currentId++;

        }

        該功能包含利益相關者之間協議的重要部分。 受信任參與最終解決方案的帳戶的地址。并且發出被off-chain oracle監聽的事件NewRequest。

        //event that triggers oracle outside of the blockchain

        event NewRequest (

        uint id,

        string urlToQuery,

        string attributeToFetch

        );

        在監聽此事件后,off-chain Oracle將調用公共函數updateRequest。

        //called by the oracle to record its answer

        function updateRequest (

        uint _id,

        string memory _valueRetrieved

        ) public {

        Request storage currRequest = requests[_id];

        //check if oracle is in the list of trusted oracles

        //and if the oracle hasn't voted yet

        if(currRequest.quorum[address(msg.sender)] == 1){

        //marking that this address has voted

        currRequest.quorum[msg.sender] = 2;

        //iterate through "array" of answers until a position if free and save the retrieved value

        uint tmpI = 0;

        bool found = false;

        while(!found) {

        //find first empty slot

        if(bytes(currRequest.anwers[tmpI]).length == 0){

        found = true;

        currRequest.anwers[tmpI] = _valueRetrieved;

        }

        tmpI++;

        }

        uint currentQuorum = 0;

        //iterate through oracle list and check if enough oracles(minimum quorum)

        //have voted the same answer has the current one

        for(uint i = 0; i < totalOracleCount; i++){

        bytes memory a = bytes(currRequest.anwers[i]);

        bytes memory b = bytes(_valueRetrieved);

        if(keccak256(a) == keccak256(b)){

        currentQuorum++;

        if(currentQuorum >= minQuorum){

        currRequest.agreedValue = _valueRetrieved;

        emit UpdatedRequest (

        currRequest.id,

        currRequest.urlToQuery,

        currRequest.attributeToFetch,

        currRequest.agreedValue

        );

        }

        }

        }

        }

        }

        此函數將首先檢查調用者是否是預定義地址之一。 然后它會檢查oracle沒有投票,如果是,它將保存oracle答案。 然后它將檢查該答案是否至少由所需的最低法定人數提供。 如果是這樣,那么我們就結果達成一致,并將發出一個事件,即UpdatedRequest,以警告客戶合同結果。

        //triggered when there's a consensus on the final result

        event UpdatedRequest (

        uint id,

        string urlToQuery,

        string attributeToFetch,

        string agreedValue

        );

        Off-chain Oracle實施

        這是更簡單的部分,它是可以監聽發出的區塊鏈事件和查詢API的任何服務。

        off-chain Oracle使用web3監聽鏈上Oracle發出的事件,并查詢請求的api,解析檢索到的json以獲取請求的密鑰,并調用公共函數updateRequest。

        您可以在github上找到off-chain oracle所有利益相關方應該部署的此服務的代碼。https://github.com/pedroduartecosta/blockchain-oracle/tree/master/off-chain-oracle

        這種實現允許不依賴于一方作為唯一一個查詢API的真實來源,而是讓多方就一個結果達成一致。它也是一個非常靈活的服務,因為它可以查詢任何公共JSONAPI,允許在大量的用例中使用。(鏈三豐)

        關鍵詞: oracle JSON API 答案

        精選 導讀

        募資55億港元萬物云啟動招股 預計9月29日登陸港交所主板

        萬科9月19日早間公告,萬物云當日啟動招股,預計發行價介乎每股47 1港元至52 7港元,預計9月29日登陸港交所主板。按發行1 167億股計算,萬

        發布時間: 2022-09-20 10:39
        管理   2022-09-20

        公募基金二季度持股情況曝光 隱形重倉股多為高端制造業

        隨著半年報披露收官,公募基金二季度持股情況曝光。截至今年二季度末,公募基金全市場基金總數為9794只,資產凈值為269454 75億元,同比上

        發布時間: 2022-09-02 10:45
        資訊   2022-09-02

        又有上市公司宣布變賣房產 上市公司粉飾財報動作不斷

        再有上市公司宣布變賣房產。四川長虹25日稱,擬以1 66億元的轉讓底價掛牌出售31套房產。今年以來,A股公司出售房產不斷。根據記者不完全統

        發布時間: 2022-08-26 09:44
        資訊   2022-08-26

        16天12連板大港股份回復深交所關注函 股份繼續沖高

        回復交易所關注函后,大港股份繼續沖高。8月11日大港股份高開,隨后震蕩走高,接近收盤時觸及漲停,報20 2元 股。值得一提的是,在7月21日

        發布時間: 2022-08-12 09:56
        資訊   2022-08-12

        萬家基金再添第二大股東 中泰證券擬受讓11%基金股權

        7月13日,中泰證券發布公告,擬受讓齊河眾鑫投資有限公司(以下簡稱齊河眾鑫)所持有的萬家基金11%的股權,交易雙方共同確定本次交易的標的資

        發布時間: 2022-07-14 09:39
        管理   2022-07-14

        央行連續7日每天30億元逆回購 對債市影響如何?

        央行12日再次開展了30億元逆回購操作,中標利率2 10%。這已是央行連續7日每天僅進行30億元的逆回購縮量投放,創下去年1月以來的最低操作規

        發布時間: 2022-07-13 09:38
        資訊   2022-07-13

        美元指數創近20年新高 黃金期貨創出逾9個月新低

        由于對美聯儲激進加息的擔憂,美元指數11日大漲近1%創出近20年新高。受此影響,歐美股市、大宗商品均走弱,而黃金期貨創出逾9個月新低。美

        發布時間: 2022-07-13 09:36
        資訊   2022-07-13

        美股三大股指全線下跌 納斯達克跌幅創下記錄以來最大跌幅

        今年上半年,美股持續回落。數據顯示,道瓊斯指數上半年下跌15 3%,納斯達克綜合指數下跌29 5%,標普500指數下跌20 6%。其中,納斯達克連續

        發布時間: 2022-07-04 09:51
        推薦   2022-07-04

        融資客熱情回升 兩市融資余額月內增加超344億元

        近期A股走強,滬指6月以來上漲4%,融資客熱情明顯回升。數據顯示,截至6月16日,兩市融資余額1 479萬億元,月內增加344 67億元,最近一個半

        發布時間: 2022-06-20 09:41
        資訊   2022-06-20

        4個交易日凈買入超百億元 北向資金持續流入A股市場

        北向資金凈流入態勢延續。繼6月15日凈買入133 59億元后,北向資金6月16日凈買入44 52億元。自5月27日至今,除6月13日以外,北向資金累計凈

        發布時間: 2022-06-17 09:37
        推薦   2022-06-17