以太坊中 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 就能很好的解决上边的问题。
三、如何使用 GraphQL
3.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 }
- 免责声明
- 世链财经作为开放的信息发布平台,所有资讯仅代表作者个人观点,与世链财经无关。如文章、图片、音频或视频出现侵权、违规及其他不当言论,请提供相关材料,发送到:2785592653@qq.com。
- 风险提示:本站所提供的资讯不代表任何投资暗示。投资有风险,入市须谨慎。
- 世链粉丝群:提供最新热点新闻,空投糖果、红包等福利,微信:juu3644。

币小葱



