剖析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…

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

相关文章
|
存储 安全 区块链
NFT+DeFi质押流动性模式系统开发(项目分析)|LP系统开发
去中心化安全性:区块链的数据存储和验证由网络上多个节点共同完成
|
存储 区块链
NFT+defi质押流动性系统开发技术分析
智能合约采用的是区块链技术,其中数据和程序的完整性得到了高度保障
|
区块链
Defi/IDO代币预售借贷分红模式系统开发部署搭建
pragma solidity ^0.8.0; contract IDX { // 代币总量 uint256 public totalSupply;
|
区块链 数据安全/隐私保护
  DeFi借贷对冲功能开发部署
DeFi借贷对冲是指通过使用DeFi协议进行借贷,并使用对冲工具来降低借贷风险的方式。
dapp/defi/nft/lp借贷理财流动性质押挖矿开发功能版,dapp/defi/nft/lp借贷理财流动性质押挖矿系统开发(开发方案)
From the perspective of conceptual model,the metauniverse is the superposition of technology system,content system,economic system,cooperation system and governance system.The core of the technical system is integration,and its technical system should be characterized by open