剖析DeFi借贷产品之Compound:Subgraph篇(一)

简介: 笔记

什么是Subgraph


Subgraph 是由 The Graph 所提供的一种技术。The Graph 是一种去中心化的索引协议,用于查询类似以太坊和 IPFS 的区块链网络数据,目前支持了 Ethereum 主网和几个测试网,以及 BSC、Matic、Fantom 等。任何人都可以基于其创建和部署开放 API,即 subgraph,使得区块链数据更容易访问。

即是说,subgraph 是由开发者创建并部署到 The Graph 的开放索引服务。

基于 The Graph 和 subgraph,数据流大致如下:

  1. 一个 DApp 通过合约执行一个 transaction,合约 emit 了一个或多个 event;
  2. The Graph 的节点持续扫描区块数据,而你定义的 subgraph 设置了所需要监听的事件;
  3. Graph 节点监听到你的 subgraph 所关心的事件,会根据你的 subgraph 所定义的处理方法创建或更新实体对象的数据,这些数据会保存在 Graph 节点中;
  4. 前端框架连接到 Graph 节点,通过编写 GraphQL 查询相应的实体对象数据并展示到页面上。

简单地说,通过 subgraph 可以对链上数据进行再封装,形成更便于查询的数据。因为有些数据,是难以在链上直接查询得到的。

官方文档中举了一个例子,比如:谁是 2018 年 1 月至 2 月出生的 CryptoKitties 的所有者? 要回答这个问题,必须处理所有 Birth事件 ,然后 为每个出生的 CryptoKitty 调用 ownerOf方法。即使对于这个相对简单的问题,运行在浏览器中的 Dapp 也需要数小时甚至数天才能得到答案。索引区块链数据很困难。区块链属性,如最终性、链重整或未处理的块,使这个过程进一步复杂化,不仅耗时,而且在概念上很难从区块链数据中检索正确的查询结果。The Graph 通过一个为区块链数据编制索引的托管服务解决了这个问题。然后可以使用标准 GraphQL API 查询这些索引(subgraph)。

5.png


Graph Node


Graph Node 是 Subgraph 的运行环境,而目前其实存在三种方式的运行环境:

  • Hosted Service:The Graph官方团队提供的中心化的托管服务,也是目前使用最广泛便利的一种方式。
  • Private Node:私有节点,由 Dapp 团队根据开源的 graph-node 项目自主搭建。
  • The Graph Network:去中心化网络,主网已上线,但目前还不稳定,开发团队目前也无法直接将 Subgraph 部署上去,需 The Graph 技术团队协同才能迁移到主网。

使用 Hosted Service 是最方便的,也是目前最推荐的一种方式。基于 Hosted Service 的 subgraph 部署流程如下:


1. 在官网注册账号

第一步,需要在 The Graph 官网(thegraph.com/explorer/)用 Github 账号进行注册,如果没有 Github 账号的话,还需要先去注册一个 Github 账号。

6.png


2. 在官网添加 Subgraph

创建账户并登录之后,进入 Dashboard 就可以开始通过界面创建 subgraph。进入你的 Dashboard,并点击 Add Subgraph。另外,每个账户都有一个 Access token,在将 subgraph 部署到 Graph 节点时需要用到。

7.png

需要填写以下信息:

1.png

其中,除了 Subgraph NameAccount 无法修改,其他字段都是后续可以修改的。另外,Subgraph Name 是区分大小写的,后续创建本地项目时需指定 Subgraph Name,切记这点。


3. 本地安装 Graph CLI

在本地环境安装 Graph CLI,即 Graph 的客户端工具,可以用 npm 或 yarn:

$ npm install -g @graphprotocol/graph-cli
$ yarn global add @graphprotocol/graph-cli

在这个安装的过程中,可能会因为国内的网络问题导致失败,可以使用翻墙工具并通过设置代理的方式解决,而且可能还需要设置为 socks5 代理。我安装的过程中,曾经只设置为 http 代理,但有一个依赖的库总是报 ESOCKETTIMEOUT。

另外,npm 和 yarn 只支持设置 http 代理,并不支持设置 socks5 代理,因此,还需要一个工具将 http 代理转为 socks5 代理。这个工具为 http-proxy-to-socks

# 假设本地socks5代理端口为1086
# 首先安装转换工具
npm install -g http-proxy-to-socks
# 然后使用这个工具监听8002端口,支持http代理,然后所有8002的http代理数据都将转换成socks的代理数据发送到1086上
hpts -s 127.0.0.1:1086 -p 8002
# 最后设置npm代理
npm config set proxy http://127.0.0.1:8002
npm config set https-proxy http://127.0.0.1:8002

使用 yarn 同理。对应的几个 npm 命令可改为:

# 安装转换工具
yarn global add http-proxy-to-socks
# 设置代理为
yarn config set proxy http://127.0.0.1:8002
yarn config set https-proxy http://127.0.0.1:8002

另外,使用期间,hpts -s 127.0.0.1:1086 -p 8002 需要一直开着。

当然,这是我遇到的情况,有些人可能遇到的问题不一样,我也不确定我的这种方案是否能解决你的问题,但至少可以尝试一下。

最后再补充一点,如果因为 git 原因发生网络问题,那可以将 git 也设置为使用代理。


4. 创建本地 subgraph 项目

在本地环境初始化一个 subgraph 项目主要使用 graph init 命令,后续参数可以指定 --from-contract--from-example。--from-contract 是从一个合约地址新建项目,--from-example 则是用一个官方提供的案例进行初始化。

--from-contract 是比较实用的一种方式,使用的命令格式为:

graph init \
  --from-contract <CONTRACT_ADDRESS> \
  [--network <ETHEREUM_NETWORK>] \
  [--abi <FILE>] \
  <GITHUB_USER>/<SUBGRAPH_NAME> [<DIRECTORY>]
  • --from-contract:配置合约地址
  • --network:指定所使用的网络,目前支持了多种网络,包括 mainnet、kovan、rinkeby、ropsten、goerli、poa-core、xdai、poa-sokol、matic、mumbai、fantom、bsc、clover
  • --abi:指定所使用的 abi 文件,如不指定,则会用 etherscan 获取,但因为网络原因,基本获取不到,所以最好指定本地文件
  • <GITHUB_USER>/<SUBGRAPH_NAME>:就是前面在官网所创建的 subgraph,比如我之前创建的为 keeganlee/First
  • [DIRECTORY]:指定创建的 subgraph 项目存放的目录,不指定的情况下和 SUBGRAPH_NAME 同名

比如,我创建的示例项目所使用的具体参数如下:

graph init \
  --from-contract 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B \
  --network mainnet \
  --abi Comptroller.json \
  keeganlee/First

创建的过程中,还会下载一些依赖的库,可能也会因为国内网络原因而失败,因此,可以用上面所提到的方法设置代理。

创建成功后,项目的目录结构如下:

subgraph.yaml     #manifest文件,也是subgraph的入口点,很多信息都是在该文件中配置
schema.graphql    #schema主要定义了保存到Graph节点中的各种实体数据的数据结构
package.json
yarn.lock
abis              #合约的abi文件都放在这里
  - Contract.json
src               #主要编写对合约事件监听后的处理,处理逻辑一般就是创建或更新实体数据
  - mapping.ts
generated         #这是自动生成的,修改以上的文件后可用graph codegen命令重新生成
  - schema.ts
  - Contract
    - Contract.ts

5. 编码

根据实际的业务需要对subgraph项目进行编码工作,主要需要修改和编写的文件为:

  • subgraph.yaml
  • schema.graphql
  • mapping.ts

这里面涉及到较多的知识点,后面再说。


6. 部署

当编码工作完成,也没什么问题之后,就可以将其部署到 The Graph 的 Hosted Service 中去。

部署之前,第一步是先进行授权,执行以下命令:

graph auth https://api.thegraph.com/deploy/ <access-token>

其中,access-token 就是你的 Dashboard 中所显示的那个 Access token,也是前面提到的。

接着,就可以在你的 subgraph 项目的根目录下调用以下命令进行部署:

yarn deploy

部署完成之后,就可以在 The Graph 官网中进入你的 subgraph 查看,比如我的 subgraph 部署完之后如下:

10.png

里面,有一个进度条,显示 Syncing(4.6%),这是在同步区块数据。

Playground 中右边展示了项目中所定义的 schema,左边则可以用 GraphQL 编写查询语句,点击 Play 按钮,则会将查询结果的数据展示在中间那片空白区域中。


私有节点

若要自己搭建私有节点,可按照 Github 上的 graph-node 项目的说明进行部署。其 Github 地址为:

部署 graph-node 也有两种方式,一是 README 上所描述的步骤,二是用 Docker 进行部署。两种方式我都尝试过,但第一种方式以失败告终,多次尝试解决问题依然无果,第二种方式很快就成功了,所以我强烈推荐用 Docker 方式进行部署。

首先,在需要部署的服务器安装好 docker 和 docker-compose。

其次,打开 graph-node/docker/docker-compose.yml 文件,修改其中一行:

ethereum: 'mainnet:http://host.docker.internal:8545'

该行指定了使用的网络和节点,比如,我部署接入 kovan 网络,节点使用 infura 的,那设置的值为:

ethereum: 'kovan:https://kovan.infura.io/v3/<PROJECT_ID>'

其中,<PROJECT_ID> 是在 infura 注册项目时所分配的项目ID。

最后,在 graph-node/docker 目录下,执行以下命令:

docker-compose up -d

将会自动下载 IPFS、Postgres 和 Graph Node 三个 Docker 镜像,并以后台的方式运行容器。

至此,私有的 Graph 节点就启动了,就可以访问以下这些:

  • Graph Node:
  • GraphiQL: http://localhost:8000/
  • HTTP: http://localhost:8000/subgraphs/name/<subgraph-name>
  • WebSockets: ws://localhost:8001/subgraphs/name/<subgraph-name>
  • Admin: http://localhost:8020/
  • IPFS:
  • 127.0.0.1:5001 or /ip4/127.0.0.1/tcp/5001
  • Postgres:
  • postgresql://graph-node:let-me-in@localhost:5432/graph-node

再配置下对外的端口和权限,外部也可以访问节点了。

而本地的 subgraph 项目想要部署到此私有节点的话,需要先在本地执行以下命令:

graph create <SUBGRAPH_NAME> --node http://<NODE_IP>:8020

其中,<SUBGRAPH_NAME> 替换成你自己的 subgraph 名称,<NODE_IP> 则替换成你的节点地址。

接着,需要修改下 subgraph 项目中的 package.json 的脚本配置。比如,使用 The Graph 官方的 Hosted Service 时,我的 package.json 中的 scripts 配置是这样的:

"scripts": {
    "codegen": "graph codegen --output-dir src/types/",
    "build": "graph build --ipfs https://api.staging.thegraph.com/ipfs/",
    "create-local": "graph create keeganlee/First --node http://127.0.0.1:8020",
    "deploy-local": "graph deploy keeganlee/First --debug --ipfs http://localhost:5001 --node http://127.0.0.1:8020/",
    "deploy": "graph deploy keeganlee/First --debug --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
    "deploy-staging": "graph deploy --debug --ipfs https://api.staging.thegraph.com/ipfs/ --node https://api.staging.thegraph.com/deploy/ keeganlee/First",
    "prettier": "./node_modules/.bin/prettier —-write '**/*.ts'"
  },

其中,build、deploy、deploy-staging 这三个命令的 --ipfs--node 参数后面的 URL 都需要更改为自己搭建的私有节点地址,以 deploy 的为例:

"deploy": "graph deploy keeganlee/First --debug --ipfs http://<NODE_IP>:5001 --node http://<NODE_IP>:8020",

之后就可以执行 yarn deploy 命令进行部署了。


The Graph Network

关于去中心化的 The Graph Network,虽然主网已经上线,但目前还没有文档说明如何将 subgraph 部署到 Network,目前那些迁移到了 Network 的 subgraph 都是官方技术团队协同迁移过去的。官方团队人员还表示,最近会等主网表现稳定后,再把其他 subgraph 也迁移到主网。

目前对 Network 最详细的介绍,就是官方文档了:

thegraph.com/docs/networ…

至于详细内容,我自己还没有深入去研究,所以就不展开了,等以后深入研究后再另外发文讲解这一块。

相关文章
|
区块链 数据安全/隐私保护 开发者
ptahdao普塔道系统开发|ptahdao普塔道质押模式系统开发
智能合约是区块链技术的一大创新,它是一种在区块链上运行的自动化合约。
|
存储 IDE 搜索推荐
NFT铸造质押借贷dapp系统开发|赋能功能模式定制
NFT铸造质押借贷dapp系统开发|赋能功能模式定制
|
11月前
|
存储 区块链
NFT+defi质押流动性系统开发技术分析
智能合约采用的是区块链技术,其中数据和程序的完整性得到了高度保障
|
存储 安全 区块链
|
区块链
Defi/IDO代币预售借贷分红模式系统开发部署搭建
pragma solidity ^0.8.0; contract IDX { // 代币总量 uint256 public totalSupply;