# 使用 The Graph 获取各大元宇宙项目交易信息

By [Yooma](https://paragraph.com/@yooma) · 2022-08-01

---

**The graph 工作原理**

**Graph 根据subgraph描述（称为subgraph.graphq）学习什么以及如何索引以太坊数据。子图描述定义了subgraph感兴趣的智能合约，这些合约中要关注的事件，以及如何将事件数据映射到 The Graph 将存储在其数据库中的数据。**

![](https://storage.googleapis.com/papyrus_images/b39058de505bd2127a585aa07e4a1e8d1a6a9d56f6f0b0a7dc35eb9d1325534e.png)

**该流程遵循以下步骤：**

*   **去中心化应用程序通过智能合约上的交易将数据添加到以太坊。**
    
*   **智能合约在处理交易时发出一个或多个事件。**
    
*   **Graph Node 不断地扫描以太坊以寻找新的块以及它们可能包含的子图的数据。**
    
*   **Graph Node 在这些块中为您的子图查找 Ethereum 事件并运行您提供的映射处理程序。映射是一个 WASM 模块，它创建或更新 Graph Node 存储的数据实体以响应以太坊事件。**
    
*   **去中心化应用程序使用节点的**[**GraphQL 端点**](https://graphql.org/learn/)**查询 Graph 节点以获取从区块链索引的数据。Graph 节点反过来将 GraphQL 查询转换为对其底层数据存储的查询，以便利用存储的索引功能获取此数据。去中心化应用程序在丰富的 UI 中为最终用户显示这些数据，他们使用这些数据在以太坊上发布新交易。循环重复**
    
    (来自[The graph](https://thegraph.com/docs/en/about/)官网)
    

一：工具
----

*   **1：** [**The Graph**](https://thegraph.com/en/)
    
*   **2：** [**OpenSea api**](https://docs.opensea.io/reference/retrieving-asset-events)
    
*   **3：Python**
    

二：流程
----

*   **1：使用**[**The Graph**](https://thegraph.com/en/)**编写Subgraph来获取各个平台最新的 transfer 的parcel id, tx\_hash等信息**
    
*   **2：使用python调用在 the graph 中编写的subgraph获取最新的 transfer 的 parcel id**
    
*   **3：通过opensea api 获取该 parcel id 的交易详细数据**
    

三：用法(以otherside为例)
------------------

### 1：The Graph

### （1）：创建Subgraph

**在 The Graph Subgraph页面创建Subgraph**

![](https://storage.googleapis.com/papyrus_images/48bf3cb766b9bacf68a63be29edcd990b18ecb1441bd5aa991d396f11019b017.png)

**选择Indexed Chain（我这里选择以太坊主网）→ Subgraph名字 → continue**

![监听otherside的transfer,这里我选择Ethereum Mainnet](https://storage.googleapis.com/papyrus_images/08ff8e69415bc76258e9bbcf26a301901f9ff841be5deae3113a3e8003253c9b.png)

监听otherside的transfer,这里我选择Ethereum Mainnet

**（进入创建的Subgraph页面右侧会有流程指南）**

**首先安装 the graph cli**

![The Graph官网流程截图---选择其一](https://storage.googleapis.com/papyrus_images/bdb6cb08460d74373e0f59c807a49c8c935b7b35dd1a5d46029dddb1f985cf09.png)

The Graph官网流程截图---选择其一

**命令执行成功后，输入graph，有以下提示代表安装成功。**

![安装the graph cli 成功](https://storage.googleapis.com/papyrus_images/6db84e289beeaf8a6130decfedf557f69ac54c64138e5639f5e720a231f78e16.png)

安装the graph cli 成功

**在本地创建Subgraph项目（otherside是项目名字)**

![The Graph官网流程截图](https://storage.googleapis.com/papyrus_images/cc490036a2a04e76d0911fff0485ecd119a012d2dd9038b6c47f2199937638c8.png)

The Graph官网流程截图

![后面可以直接指定otherside的合约地址](https://storage.googleapis.com/papyrus_images/dce2add89e4e22055d39f1ff26049aae4ad616ab56d54537d086840ebad14e10.png)

后面可以直接指定otherside的合约地址

**回车之后在选择Ethereum network这里选择mainnet (刚刚在The Graph官网创建的选择Ethereum Mainnet)**

![](https://storage.googleapis.com/papyrus_images/488dfa77cd403e31bbd102efecf386d69c3c5f3cb59b7ef20332c8e2e2ff0043.png)

其余的默认即可。

* * *

### (2): 编写代码

**创建项目成功之后进入到项目目录使用VSCode编辑代码**

![](https://storage.googleapis.com/papyrus_images/2f142f53139f8e7cb9412438f53d4b0e1bf9d14f8d0ccb6412ba47d48f2aa5e2.png)

![](https://storage.googleapis.com/papyrus_images/ce05b75fed0e4560c568f12b95277796c659bcf314a343b4e1cd9a8943c0b1ee.png)

**\-- 整体编写分两步：**

**\-- 第一步：只需要关心schema.graphql和subgraph.yaml两个文件的作用以及用法。**

**\-- 第二步：需要知道 ./src/contract.ts 的作用以及用法**

**schema.graphql：**

**定义子图的schema。 GraphQL schema是使用 GraphQL 接口定义语言定义的。 需要具体了解GraphQL schema可以查看参考文档** [**GraphQL API**](https://thegraph.com/docs/zh/querying/graphql-api/) **。**

**直白的讲，我们在该文件定义好每个实体（下图 Transfer和Parcel）之后，The Graph官网的项目中也就会暴露出我们代码中定义的实体**

![比如我们代码中定义了Transfer和Parcel](https://storage.googleapis.com/papyrus_images/3bc7d79d86d1b5b167c16031514461da2b2f0defde63419aeeaf9a8a54af4469.png)

比如我们代码中定义了Transfer和Parcel

**根据这些查询参数要获取想要的信息**

![The Graph官网项目中暴露出的查询参数](https://storage.googleapis.com/papyrus_images/79901bda03e696381481938dc2490eb28ee2ced413b30936560d133a72ce93ec.png)

The Graph官网项目中暴露出的查询参数

**schema.graphql在定义好之后只是一个用于我们查询的模板。但是数据从哪里来以及如何匹配，就需要用到subgraph.yaml 和 ./src/contract.ts**

### subgraph.yaml：

**定义了subgraph索引的智能合约，这些合约中需要关注的事件，以及如何将事件数据映射到 Graph 节点存储并允许查询的实体。**

![](https://storage.googleapis.com/papyrus_images/c60b96c2dacebc87e5d8a28ea503a57eea53bdfdfbb78e9e8543307645990b06.png)

**(创世块的查找：在**[**ethscan**](https://etherscan.io/)**中输入otherside合约地址)**

![1](https://storage.googleapis.com/papyrus_images/a2fbaf98029dc83d9584a758bbbf6c51736753463be5fb1ccb2dd75312d061d0.png)

1

![2](https://storage.googleapis.com/papyrus_images/b7e42e2f4f8ceae5651a723efb51fdf6a1e867756bc40933400a7368776f40b3.png)

2

**eventHandlers：**

**Transfer 对应abi中的Transfer事件**

![](https://storage.googleapis.com/papyrus_images/d9c93c232ce03c50a5cad566f787eea74bad730b1b2090712d6099452eb60eda.png)

**handleTransfer 对应 ./src/contract.ts中我们定义的function（在下文会提到），现在先写到这里**

**写好schema.graphql和subgraph.yaml之后回到终端执行graph codegen命令**

![这里会自动生成一些代码文件](https://storage.googleapis.com/papyrus_images/964a803e4f6d3c91e77c1868c3a5d947740a204e8c38617ee5fa384f537bee5e.png)

这里会自动生成一些代码文件

### ./src/contract.ts:

**最后一步来做数据的匹配**

![](https://storage.googleapis.com/papyrus_images/c4e47eee37e9246b0c8644d93717b36be9b3c83e6f9e9a01a2018b78bf385f91.png)

**代码完成之后回到The Graph官网创建的项目中，继续右侧的流程，执行最后一步**

![部署subgraph](https://storage.googleapis.com/papyrus_images/5435c1ed86f6bff64b1e95aa2850023c88024835406c941134b36932105587c4.png)

部署subgraph

**之后在The Graph官网会看见自己的版本号**

**当进度条到100%后代表otherside从设置的创世块到目前最新的块的数据都已经匹配到，如果有新块生成同样也会自动匹配**

![](https://storage.googleapis.com/papyrus_images/f78b5ca1c43133e1f3d061f240346f9a8cee5a86280243dea14c79fda3770c42.png)

* * *

### (3): 使用部署的subgraph

![](https://storage.googleapis.com/papyrus_images/6e0b72248faa646b73345156823ac6350c38f3e408e99b2c1d2a6468d44f04b7.png)

**至此 the graph 的 subgraph已经部署完成。**

**使用python来请求数据**

* * *

2：python
--------

**python这里不多做解释，使用requests来请求接口**

    import requests
    url = "创建的subgraph -->detail中的DEVELOPMENT QUERY URL"
    query = """
          {
            transfers(orderBy: date, orderDirection: desc, first: 50){
              id
              date
              parcel{
                id
              }
            }
          }
    """
    requests_res = requests.post(url, json={'query': query})
    

* * *

3：opensea api
-------------

**使用** [**opensea api**](https://docs.opensea.io/reference/retrieving-asset-events) **获取交易的数据需要4个参数**

**_token\_id: parcel id_** _（the graph 获取的 parcel id---例如上张图片中的 “74425”）_

**_asset\_contract\_address: 平台的合约地址_**\*（otherside：0x34d85c9cdeb23fa97cb08333b511ac86e1c4e258）\*

![](https://storage.googleapis.com/papyrus_images/ef2dbd7aeae455f09c8cb01fab55114ca1b3d6bf342ac9b6ed73758bf3e93fa2.png)

**_event\_type: 用于检索我们获取该parcel id什么类型的数据_** _（在the graph编写subgraph中获取的是transfer事件的信息，我们通过这个参数来检索获取交易的信息。）_**_由于目的要获取交易数据，所以选择successful。_**

![](https://storage.googleapis.com/papyrus_images/2e909661d287ced5f9d11b4b8d2502f5ced93fb1b9824774ca83b16f253d0fa9.png)

**API-KEY: 需要向opensea平台申请！**

![](https://storage.googleapis.com/papyrus_images/1faecd836f0cedcfafb35ef22cb4239e39ad6d2131f3f1818ed8e3304f019567.png)

**调用方法同样使用python requests，再经过处理获取出buyer,seller，交易金额等数据 ，也可以从返回的数据中获取其他需要的数据。**

* * *

4：总结概括：
-------

**由于部署了subgraph之后，会自动实时匹配链上新的块的信息。所以可以使用python写一个脚本，然后放到crontab中来定时调用该接口以获取新的transfer的parcel id，再用opensea event\_type中的successful参数过滤出交易的信息（因为subgraph中定义的实体Transfer的id是txhash--唯一值，可以使用它来记录每一次取到最新值的位置）**

注： 开发过程中参考的文档

*   [The Graph 官方文档](https://thegraph.com/docs/en/)
    
*   [Cryptovoxels Parcels源码](https://github.com/cryptovoxels/parcel-market-subgraph)

---

*Originally published on [Yooma](https://paragraph.com/@yooma/the-graph)*
