以太坊中GraphQL簡介及使用

買賣虛擬貨幣
以太坊在去年升級的go-ethereum(geth)1.9.0大版本,除了效能得到大幅提升之外,引入了GraphQL,一種節點介面查詢機制,用以補充JSON-RPC。本文將會介紹GraphQL是什麼,Geth[1]為什麼要引入GraphQL以及如何使用GraphQL三個方面對以太坊的GraphQL做一個介紹。一、GraphQL是什麼GraphQL官網對GraphQL的介紹是:GraphQL 是一個用於 API 的查詢語言,是一個使用基於型別系統來執行查詢的服務端執行時(型別系統由你的資料定義)。GraphQL 並沒有和任何特定資料庫或者儲存引擎繫結,而是依靠你現有的程式碼和資料支撐。GraphQL有以下特點:1、請求你所要的資料,不多不少
目前大部分的專案都是採用前後端分離的開發模式,前後端採用API進行資料交流。API返回資料往往是前後端協商定義的,而後端為了滿足不同的客戶端,減小後端請求的複雜性,往往會給出一些冗餘資料。GraphQL很強大的一個功能就是能夠指定所需要的API資料並獲得可預測的結果。2、獲取多個資源,只用一個請求在使用REST API時,我們如果需要多個資源,則會分別請求不同的介面,而使用GraphQL 可以透過一次請求就獲取你應用所需的所有資料。3、使用型別描述所有的可能GraphQL API 基於型別和欄位的方式進行組織,而非入口端點。你可以透過一個單一入口端點得到你所有的資料能力。GraphQL 使用型別來保證應用只請求可能的資料,還提供了清晰的輔助性錯誤資訊。應用可以使用型別,而避免編寫手動解析程式碼。二、以太坊為什麼要使用GraphQL
以太坊在EIP1767[2]中描述了“在以太坊節點中使用GraphQL”的提案,在以太坊節點中使用GraphQL模式目的時完全替代使用JSON-RPC獲取只讀資訊,使用GraphQL具有高可用性、一致性、高效率和麵向未來的優勢。之所以引入GraphQL,是因為使用JSON-RPC有一些不足,這些不足包括:1、對一些異常請求資料的判斷的複雜性如對空字元的判斷,不同的地方對(""、"0x"、"0x0")的判斷是不同的,會導致一些不必要的工作。2、為了返回資料全面而額外增加資源消耗例如,我們在呼叫eth_getBlock時會返回totalDifficulty欄位,而該欄位與塊頭是分開儲存,需要單獨讀取磁碟,許多呼叫者不需要此欄位,但是RPC伺服器無法知道使用者是否需要此欄位,只能對每次呼叫eth_getBlock檢索此欄位。
3、介面重複呼叫,重複浪費資源例如,我們在發起一筆交易後,通常會以輪詢的方式呼叫eth_getTransactionReceipt介面,來判斷交易是否上鍊。以太坊中的交易收據作為每個塊的單個二進位制Blob儲存在磁碟上,獲取單個交易的收據需要獲取並反序列化此blob,然後找到相關條目並返回,重複呼叫時,節點實現要重複獲取和反序列化相同資料,造成資源浪費。針對JSON-RPC的這些不足,有的同學會說,那我透過修改JSON-RPC的介面,也可以避免上邊的問題,但是這樣增加介面的複雜性。而API查詢語言GraphQL就能很好的解決上邊的問題。三、如何使用GraphQL3.1 開啟Geth對GraphQL的支援Geth在1.9.0及以上版本支援了GraphQL,要開啟GraphQL支援,在啟動Geth客戶端時增加--graphql。
Geth與GraphQL相關的配置命令有:•--graphql ,在節點中開啟GraphQL服務•--graphql.addr value,GraphQL服務地址,預設時localhost•--graphql.port value,GraphQL服務埠號,預設8547•--graphql.corsdomain value,GraphQL服務訪問的跨域配置•--graphql.vhosts value,主機名白名單配置

預設配置啟動GraphQL服務後,在瀏覽器中訪問http://localhost:8547 會看到如下介面。

3.2 GraphQL使用示例

GraphQL的語法詳見官網,這裡不贅述。https://spec.graphql.cn[3] 另外,在GraphQL瀏覽器中,也有請求的示例和補全,使用起來相對比較簡單。

1、查詢網路區塊同步狀態

query {
  syncing {
    currentBlock
    highestBlock
    knownStates
    pulledStates
    startingBlock
  }
}

2、查詢事件

{
  logs(filter: {fromBlock: 0,
    addresses: ["0xf105795bf5d1b1894e70bd04dc846898ab19fa62"],
    topics: [["0x0f0c27adfd84b60b6f456b0e87cdccb1e5fb9603991588d87fa99f5b6b61e670"]]}
  ) {
    transaction {
      hash
      from {
        address
      }
      block{
        number
        timestamp
      }
    }
  }
}

3、查詢區塊資訊

query c{
  blocks(from:100, to:120) {
    number
    hash
    timestamp
  }
}

4、查詢交易

{
  transaction(hash:"0x0f0c27adfd84b60b6f456b0e87cdccb1e5fb9603991588d87fa99f5b6b61e670") {
    nonce
    from {
      address
    }
    to {
      address
    }
  }
}

3.3 GraphQL對JSON-RPC的向後相容

GraphQL實現了JSON-RPC節點介面提供的大部分只讀功能。可以將現有的RPC呼叫對映到GraphQL查詢, 所有介面實現大家可以在原文[4]檢視。

3.4 Quorum對GraphQL的支援

Quorum在v2.6.0版本中將Geth升級到了1.9.7,並支援GraphQL。在以太坊GraphQL服務的基礎上,增加了對隱私交易的支援。

# Transaction is an Ethereum transaction.
type Transaction {
    ...
    # IsPrivate is an indicator of Quorum private transaction
    isPrivate: Boolean
    # PrivateInputData is the actual payload of Quorum private transaction
    privateInputData: Bytes
}

查詢隱私交易的語法:

transaction(hash: "0x58462fa0b6074a8feb5d9b8cd0e6bb7ef4d1528471396070d9ae617c5dee40a8") {
    isPrivate
    inputData
    privateInputData
}

References

[1] Geth: https://learnblockchain.cn/tags/Geth
[2] EIP1767: https://learnblockchain.cn/docs/eips/eip-1767.html
[3] https://spec.graphql.cn: https://spec.graphql.cn/
[4] 原文: https://learnblockchain.cn/article/1062

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;