# 远程部署

在上一节中，我们基于graph init 命令

`graph init subgraphdemo/heco --network heco --from-contract 0x0bb480582ecae1d22bbaeaccfbb849b441450026`

成功地生成了项目的脚手架文件，整个执行命令输出如下：

`✔ Subgraph name · subgraphdemo/heco`

`✔ Directory to create the subgraph in · candy`

`✔ Ethereum network · heco`

`✔ Contract address · 0x0bb480582ecae1d22bbaeaccfbb849b441450026`

`✔ Fetching ABI from https://hecoinfo.com:https://api.hecoinfo.com/api?module=contract&action=getabi&address=0x0bb480582ecae1d22bbaeaccfbb849b441450026`

`✔ Contract Name · Contract`

`———`

&#x20;`Generate subgraph from ABI`

&#x20;`Write subgraph to directory`

`✔ Create subgraph scaffold`

`✔ Initialize subgraph repository`

`✔ Install dependencies with yarn`

`✔ Generate ABI and schema types with yarn codegen`

`Subgraph subgraphdemo/heco created in candy for network heco`

`Next steps:`

&#x20;`` 1. Run `graph auth https://deploy.hg.network <access-token>` ``

&#x20;`to authenticate with the hosted service. You can get the access token from`

&#x20;`https://dashboard.hg.network/.`

&#x20;``2. Type `cd candy` to enter the subgraph.``

&#x20;``3. Run `yarn deploy` to deploy the subgraph to``

&#x20;`https://e.hg.network/subgraph/subgraphdemo/heco.`

`Make sure to visit the documentation on https://docs.hg.network for further information.`

此示例代码，也已经提交到github，请见：

<https://github.com/HGDotNetwork/candy-subgraph>

下面对代码做一些简单的调整，然后进行部署测试和查询测试。

首先来了解一下代码的结构：

.`/abis`

`./abis/Contract.json 合约的接口定义文件，根据指定的合约地址、网络，graph 程序自动获得`

`./schema.graphql 示例的数据实体定义文件，在其中放置要操作的数据对象和属性定义`

`./subgraph.yaml 子图数据源定义，包括合约、起始区块（默认没有）、事件、处理程序等`

`./yarn.lock yarn 依赖更新文件`

`./package.json 项目依赖以及定义`

`./src AssemblyScript 目录，用于存放解析逻辑代码`

`./src/mapping.ts 事件处理程序文件，针对每一个合约事件，均可以在这里编写相应的处理程序，对数据进行统计`

下面我们调整代码：

1. abis 目录下的内容不需要调整，除非我们要新增合约解析，就将新合约的 abi 文件放置到这里。
2. 这里用的是一个线上发送红包的合约，脚手架程序已经自动为我们自动生成了一个示例实体，示例实体对应了第一个示例事件以及相应的处理程序。

我们找到该合约的事件定义，这个很容易找，根据合约地址去区块浏览器上找即可：

<https://hecoinfo.com/address/0x0bb480582ecae1d22bbaeaccfbb849b441450026#code>

`event Packetstarted(uint256 total, address tokenAddress);`

这个事件是每发一个红包会生成的事件，并且传入了两个参数，第一个参数是红包的总金额，第二个参数是红包的币种。

再对照 schema.graphql，已经为此事件生成了示例实体：

`type ExampleEntity @entity {`

&#x20;`id: ID!`

&#x20;`count: BigInt!`

&#x20;`total: BigInt! # uint256`

&#x20;`tokenAddress: Bytes! # address`

`}`

根据发红包的逻辑，我们做一个简单的命名上的调整，并且增加一个某一个币种发红包的统计，修改 schema.graphql 如下：

`type PackageEntity @entity {`

`id: ID!`

`count: BigInt!`

`total: BigInt! # uint256`

`tokenAddress: Bytes! # address`

`}`

`type PackageToken @entity {`

`id: ID!`

`total: BigInt! # uint256`

`}`

为了逻辑尽可能简单的，其他实体先不处理

修改了schema 定义，就得相应调整mapping.ts ,也特别简单，将发红包的发送记录，保存在PackageEntity 里，然后使用PackageToken 对数据数据进行统计，将handlePackagestarted 调整如下：

`export function handlePacketstarted(event: Packetstarted): void {`

`// Entities can be loaded from the store using a string ID; this ID`

`// needs to be unique across all entities of the same type`

`let entity = PackageEntity.load(event.transaction.hash.toHex())`

`// Entities only exist after they have been saved to the store;`

``// `null` checks allow to create entities on demand``

`if (entity == null) {`

`entity = new PackageEntity(event.transaction.hash.toHex())`

`// Entity fields can be set using simple assignments`

`entity.count = BigInt.fromI32(0)`

`}`

`let tokenEntity = PackageToken.load(event.params.tokenAddress.toHex())`

`if(tokenEntity == null){`

`tokenEntity = new PackageToken(event.params.tokenAddress.toHex())`

`tokenEntity.total = BigInt.fromI32(0);`

`}`

`tokenEntity.total = tokenEntity.total.plus(event.params.total)`

`// BigInt and BigDecimal math are supported`

`entity.count = entity.count + BigInt.fromI32(1)`

`// Entity fields can be set based on event parameters`

`entity.total = event.params.total`

`entity.tokenAddress = event.params.tokenAddress`

`` // Entities can be written to the store with `.save()` ``

`entity.save()`

`tokenEntity.save()`

`}`

这样就实现发红包的保存与红包金额的简单统计，下面我们来测试一下部署，为了方便起见，这里不演示本地部署，如果对本地部署感兴趣的可以自动部署本地环境以进行测试。

部署过程分为三步：

1、首先要根据Abi生成相应的代码，以操作合约数据

2、根据HyperGraph 控制后台的提示，在线上生成子图

3、根据 HyperGraph 控制后台的提示，在远程部署子图

1. 进入示例项目目录（package.json所在目录)， 生成代码使用命令为：

`yarn codegen`

或者手工执行

`npx graph codegen`

或者安装了全局 graph ，可以直接执行&#x20;

`graph codegen`

输出如下：

`✔ Apply migrations`

`✔ Load subgraph from subgraph.yaml`

&#x20; `Load contract ABI from abis/Contract.json`

`✔ Load contract ABIs`

&#x20; `Generate types for contract ABI: Contract (abis/Contract.json)`

&#x20; `Write types to generated/Contract/Contract.ts`

`✔ Generate types for contract ABIs`

`✔ Generate types for data source templates`

`✔ Load data source template ABIs`

`✔ Generate types for data source template ABIs`

`✔ Load GraphQL schema from schema.graphql`

&#x20; `Write types to generated/schema.ts`

`✔ Generate types for GraphQL schema`

`Types generated successfully`

1. 在HyperGraph 控制后台找到API方式的部署提示，获得创建子图的命令，如下图：

![](/files/-MZ6oZKK6x52yARz1zav)

可以打开命令行操作提示：

![](/files/-MZ6oZKLpIH-dcI8kr-v)

使用上图红框中的命&#x4EE4;**（具体命令可能由于节点和网络不同而会不同，请以界面上的提示命令为准）**

`% graph create subgraphdemo/heco \`

`--node https://deploy.hg.network \`

`--access-token <AuthToken>`

`Created subgraph: subgraphdemo/heco`

请注意，创建子图一定要加 access-token 参数，否则创建不会成功。access-token 参数的值 AuthToken 在控制台的子图详情页可以看到。

如此就可以创建子图，从输出上看，子图创建成功。

1. 创建成功之后，就可以正式部署了。注意，部署也要带上 access-token 参数, 根据命令行提示，我们使用这个命令：**（具体命令可能由于节点和网络不同而会不同，请以界面上的提示命令为准）**

`graph deploy --debug \`

`--node https://deploy.hg.network \`

`--ipfs https://f.hg.network subgraphdemo/heco \`

`--access-token <AuthToken>`

`✔ Apply migrations`

`✔ Load subgraph from subgraph.yaml`

&#x20; `Compile data source: Contract => build/Contract/Contract.wasm`

`✔ Compile subgraph`

&#x20; `Copy schema file build/schema.graphql`

&#x20; `Write subgraph file build/Contract/abis/Contract.json`

&#x20; `Write subgraph manifest build/subgraph.yaml`

`✔ Write compiled subgraph to build/`

&#x20; `Add file to IPFS build/schema.graphql`

&#x20;               `.. QmPPWmHomaJ3ZBNvuAw5sjhPJhhxjwnQR1uw4b7WyJycs3`

&#x20; `Add file to IPFS build/Contract/abis/Contract.json`

&#x20;               `.. QmaHZdbi1ZTfMPq2rGhH3vgrsbF1o4HxfhQczfeYnccZQH`

&#x20; `Add file to IPFS build/Contract/Contract.wasm`

&#x20;               `.. QmcyaikiQnY2m9iP9VecLEqHZDs1sEMff7VNWsqi3cC4Fk`

`✔ Upload subgraph to IPFS`

`Build completed: QmSS3zRxoky8gpDNdTaUW1XJKtYeZeZZ1yb6qyEmegZ6vU`

`✖ Failed to deploy to Graph node https://deploy.hg.network/: Ethereum network not supported by registrar: heco`

这个时候，出了错误，这是由于部署节点，将 RPC 网络没有调整过来，在后续会逐步调整，现在我们修改一下 subgraph.yaml ，将 network 修改为：mainnet（**如果使用的是公开节点，不需要此步骤，分别为heco或者bsc**），同时为了高效索引起见，也加上 startBlock，subgraph.yaml 内容如下：

`specVersion: 0.0.2`

`schema:`

&#x20; `file: ./schema.graphql`

`dataSources:`

&#x20; `- kind: ethereum/contract`

&#x20;   `name: Contract`

&#x20;   `network: mainnet`

&#x20;   `source:`

&#x20;     `address: "0x0bb480582ecae1d22bbaeaccfbb849b441450026"`

&#x20;     `startBlock: 2095189`

&#x20;    `abi: Contract`

&#x20;    `mapping:`

&#x20;      `kind: ethereum/events`

&#x20;      `apiVersion: 0.0.4`

&#x20;      `language: wasm/assemblyscript`

&#x20;     `entities:`

&#x20;       `- Packetstarted`

&#x20;       `- PacketClaimed`

&#x20;       `- Packetended`

&#x20;       `- ClaimedTokens`

&#x20;       `- ClaimedPacketTokens`

&#x20;       `- OwnershipTransferred`

&#x20;     `abis:`

&#x20;       `- name: Contract`

&#x20;     `file: ./abis/Contract.json`

&#x20;       `eventHandlers:`

&#x20;         `- event: Packetstarted(uint256,address)`

&#x20;           `handler: handlePacketstarted`

&#x20;         `- event: PacketClaimed(uint256,address,uint32,address)`

&#x20;           `handler: handlePacketClaimed`

&#x20;         `- event: Packetended(uint256,address)`

&#x20;           `handler: handlePacketended`

&#x20;         `- event: ClaimedTokens(address,address,uint256)`

&#x20;           `handler: handleClaimedTokens`

&#x20;         `- event: ClaimedPacketTokens(uint32,address,address,uint256)`

&#x20;           `handler: handleClaimedPacketTokens`

&#x20;         `- event: OwnershipTransferred(address,address)`

&#x20;           `handler: handleOwnershipTransferred`

&#x20;       `file: ./src/mapping.ts`

然后我们再执行部署命令，此时已经部署成功：

`✔ Apply migrations`

`✔ Load subgraph from subgraph.yaml`

&#x20; `Compile data source: Contract => build/Contract/Contract.wasm`

`✔ Compile subgraph`

&#x20; `Copy schema file build/schema.graphql`

&#x20; `Write subgraph file build/Contract/abis/Contract.json`

&#x20; `Write subgraph manifest build/subgraph.yaml`

`✔ Write compiled subgraph to build/`

&#x20; `Add file to IPFS build/schema.graphql`

&#x20;               `.. QmPPWmHomaJ3ZBNvuAw5sjhPJhhxjwnQR1uw4b7WyJycs3`

&#x20; `Add file to IPFS build/Contract/abis/Contract.json`

&#x20;               `.. QmaHZdbi1ZTfMPq2rGhH3vgrsbF1o4HxfhQczfeYnccZQH`

&#x20; `Add file to IPFS build/Contract/Contract.wasm`

&#x20;               `.. QmcyaikiQnY2m9iP9VecLEqHZDs1sEMff7VNWsqi3cC4Fk`

`✔ Upload subgraph to IPFS`

`Build completed: QmfPj5bvz7q69oqTrimwisC8sXiGxDY54yJG5vCLug2Qhx`

`Deployed to https://e.hg.network/subgraph/subgraphdemo/heco`

`Subgraph endpoints:`

`Queries (HTTP):     https://q.hg.network/subgraphs/name/subgraphdemo/heco`

`Subscriptions (WS): wss://w.hg.network/subgraphs/name/subgraphdemo/heco`

通过HyperGraph 控制台，也可以看到已经更新的子图内容编号，在日志一栏中，也可以看到日志输出了。

![](/files/-MZ6oZKMx1OL5ul5p-xz)

可以的看到，上述的HTTP 查询链接是：

<https://q.hg.network/subgraphs/name/subgraphdemo/heco>

打开此链接输入一下简单的查询，就可以得到查询结果。右边文档区还可以看到Schema 的定义。

![](/files/-MZ6oZKN6vXwcPUxri_v)

至此，我们成功完成了一个子图从后端控制台添加，使用graph-cli 构建开发环境，从合约搭建脚手架，然后再一步步调整代码，直至部署成功的整个过程。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hg.network/product-chan-pin-bang-zhu/cheng-xu-kai-fa/yuan-cheng-bu-shu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
