# Deploy a Subgraph

Deploying a subgraph involves creating a GraphQL schema, defining mappings to extract data from a blockchain or data source, and deploying the subgraph to a GraphNode service. In this tutorial, we'll walk you through the process of deploying a subgraph using the Graph CLI.

## Prerequisites

1. Node.js and npm: Make sure you have Node.js and npm installed on your system by checking in Terminal (or you can download them from the [Node.js website](https://nodejs.org/)):

   ```
   $ node -v
   v19.9.0
   $ npm -v
   9.6.3
   ```
2. Graph CLI: Install the Graph CLI globally using npm:

   ```bash
   npm install -g @graphprotocol/graph-cli
   ```
3. Access to a graph node: Ensure that you have access to a running graph node service. You have set up your own graph node at [here](/services/the-graph/deploy-a-graph-node.md).

We will deploy a subgraph for smart contract `MyToken.sol` on Solaris mainnet: [0xb4C122037a433aEc9FcB25A415Fe1f91845e3958](https://u2uscan.xyz/address/0xb4C122037a433aEc9FcB25A415Fe1f91845e3958).

## Create new project

Create new Node.js project and install dependencies:

```
mkdir sample_subgraph
cd sample_subgraph
npm init -y
```

Let's modify your `package.json` file to set up Node.js project:

```
{
  "name": "sample-subgraph",
  "version": "1.0.0",
  "scripts": {
    "codegen": "graph codegen",
    "create": "graph create u2u/subgraph --node http://127.0.0.1:8020",
    "deploy": "graph deploy u2u/subgraph --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020"
  },
  "devDependencies": {
    "@amxx/graphprotocol-utils": "^1.1.0",
    "@graphprotocol/graph-cli": "^0.59.0",
    "@graphprotocol/graph-ts": "^0.31.0"
  },
  "dependencies": {}
}
```

Now install dependencies:

```
npm install
```

## Add contract ABI

At project directory, create new folder called `abis`. Then create new file `MyToken.json` that located inside `abis` folder:

```
abis/
    MyToken.json
```

`MyToken.json` contains `MyToken` contract's ABI. You can retrieve ABI of verified contract via explorer (Contract detail page > tab Contract > button Code > Contract ABI) or copy from compiled ABI with hardhat (`artifacts` folder). It has this format:

```
{
    "contractName": "MyToken",
    "abi": [ /* copy ABI and paste here */ ]
}
```

## Define schema

A GraphQL schema that defines what data is stored for your subgraph, and how to query it via GraphQL. The schema for your subgraph is in the file `schema.graphql`. GraphQL schemas are defined using the GraphQL interface definition language. If you've never written a GraphQL schema, it is recommended that you check out this primer on the GraphQL type system. Reference documentation for GraphQL schemas can be found in the [GraphQL API](https://thegraph.com/docs/en/querying/graphql-api/) section.

At project directory, create new file called `schema.graphql` and paste following contents:

```
type Account @entity {
	id: Bytes!
	asERC20: ERC20Contract
	ERC20balances: [ERC20Balance!]! @derivedFrom(field: "account")
	ERC20approvalsOwner: [ERC20Approval!]! @derivedFrom(field: "owner")
	ERC20approvalsSpender: [ERC20Approval!]! @derivedFrom(field: "spender")
	ERC20transferFromEvent: [ERC20Transfer!]! @derivedFrom(field: "from")
	ERC20transferToEvent: [ERC20Transfer!]! @derivedFrom(field: "to")
	events: [Event!]! @derivedFrom(field: "emitter")
}
type ERC20Contract @entity(immutable: true) {
	id: Bytes!
	asAccount: Account!
	name: String
	symbol: String
	decimals: Int!
	totalSupply: ERC20Balance!
	balances: [ERC20Balance!]! @derivedFrom(field: "contract")
	approvals: [ERC20Approval!]! @derivedFrom(field: "contract")
	transfers: [ERC20Transfer!]! @derivedFrom(field: "contract")
}
type ERC20Balance @entity {
	id: ID!
	contract: ERC20Contract!
	account: Account
	value: BigDecimal!
	valueExact: BigInt!
	transferFromEvent: [ERC20Transfer!]! @derivedFrom(field: "fromBalance")
	transferToEvent: [ERC20Transfer!]! @derivedFrom(field: "toBalance")
}
type ERC20Approval @entity {
	id: ID!
	contract: ERC20Contract!
	owner: Account!
	spender: Account!
	value: BigDecimal!
	valueExact: BigInt!
}
type ERC20Transfer implements Event @entity(immutable: true) {
	id: ID!
	emitter: Account!
	transaction: Transaction!
	timestamp: BigInt!
	contract: ERC20Contract!
	from: Account
	fromBalance: ERC20Balance
	to: Account
	toBalance: ERC20Balance
	value: BigDecimal!
	valueExact: BigInt!
}
interface Event {
	id: ID!
	transaction: Transaction!
	emitter: Account!
	timestamp: BigInt!
}
type Transaction @entity(immutable: true) {
	id: ID!
	timestamp: BigInt!
	blockNumber: BigInt!
	events: [Event!]! @derivedFrom(field: "transaction")
}
```

[Learn more about defining entities in your subgraph](https://thegraph.com/docs/en/developing/creating-a-subgraph/#defining-entities).

## Subgraph manifest

Subgraph manifest is a configuration file for a subgraph. Below is the subgraph manifest for our sample:

```
specVersion: 0.0.4
description: Sample Subgraph
repository: https://github.com/unicornultrafoundation/subgraph
schema:
  file: ./schema.graphql
dataSources:
  - kind: ethereum/contract
    name: MyToken
    source:
      abi: MyToken
      address: "0xa3Aa4cb3DB300355613cb3388D4eD8823f4ED07A"
      startBlock: 7699806
    mapping:
      kind: ethereum/events
      apiVersion: 0.0.6
      language: wasm/assemblyscript
      entities:
        - TransferEvent
      abis:
        - name: MyToken
          file: ./abis/MyToken.json
      eventHandlers:
        - event: Transfer(indexed address,indexed address,uint256)
          handler: handleTransfer
      file: ./src/mytoken.ts
```

Let's break down the elements of this subgraph manifest:

* `specVersion: 0.0.4`: This specifies the version of the subgraph manifest. It indicates which version of the subgraph schema and configuration format is being used.
* `description: Sample Subgraph`: This is a human-readable description of the subgraph, providing information about its purpose or functionality.
* `schema.file`: This points to the GraphQL schema file used for defining the data structure and types that the subgraph will query and expose.
* `dataSources`: This section defines the data sources that the subgraph will query:
  * `kind`: Specifies that the data source is smart contract.
  * `name:` A user-assigned name for the data source.
  * `source.abi`: The ABI for the smart contract with the name `MyToken`.&#x20;
  * `source.address`: The address of contract `MyToken`.
  * `source.startBlock`: block number from which indexing should start.
* `mapping`: specifies how the data from the Ethereum smart contract is mapped to the subgraph:
  * `kind: ethereum/events`: This indicates that the data source is indexed based on events.
  * `apiVersion: 0.0.6`: The version of the AssemblyScript being used.
  * `language: wasm/assemblyscript`: The programming language used for writing the mapping logic.
  * `entities`: the entities that the data source writes to the store. The schema for each entity is defined in the schema.graphql file
  * `abis`: one or more named ABI files for the source contract as well as any other smart contracts that you interact with from within the mappings.
  * `eventHandlers`: lists the smart contract events this subgraph reacts to and the handlers in the mapping—`./src/mytoken.ts` in the example—that transform these events into entities in the store.

Check out this link to learn more about [subgraph manifest](https://thegraph.com/docs/en/developing/creating-a-subgraph/#the-subgraph-manifest).

## Define mappings

The mappings take data from a particular source and transform it into entities that are defined within your schema. Mappings are written in a subset of [TypeScript](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html) called [AssemblyScript](https://github.com/AssemblyScript/assemblyscript/wiki) which can be compiled to WASM ([WebAssembly](https://webassembly.org/)). AssemblyScript is stricter than normal TypeScript, yet provides a familiar syntax.

For each event handler that is defined in `subgraph.yaml` under `mapping.eventHandlers`, create an exported function of the same name. Each handler must accept a single parameter called `event`with a type corresponding to the name of the event which is being handled.

At project directory, create a new folder `src`. Add 2 files as below:

```
src/
    fetch.ts
    mytoken.ts
```

```
// fetch.ts
import {
	Address,
} from '@graphprotocol/graph-ts'

import {
	Account,
	ERC20Contract,
	ERC20Balance,
	ERC20Approval,
} from '../generated/schema'

import {
	MyToken,
} from '../generated/MyToken/MyToken'

import {
	constants,
} from '@amxx/graphprotocol-utils'

export function fetchAccount(address: Address): Account {
	let account = new Account(address)
	account.save()
	return account
}

export function fetchERC20(address: Address): ERC20Contract {
	let contract = ERC20Contract.load(address)

	if (contract == null) {
		let endpoint = MyToken.bind(address)
		let name = endpoint.try_name()
		let symbol = endpoint.try_symbol()
		let decimals = endpoint.try_decimals()

		// Common
		contract = new ERC20Contract(address)
		contract.name = name.reverted ? null : name.value
		contract.symbol = symbol.reverted ? null : symbol.value
		contract.decimals = decimals.reverted ? 18 : decimals.value
		contract.totalSupply = fetchERC20Balance(contract as ERC20Contract, null).id
		contract.asAccount = address
		contract.save()

		let account = fetchAccount(address)
		account.asERC20 = address
		account.save()
	}

	return contract as ERC20Contract
}

export function fetchERC20Balance(contract: ERC20Contract, account: Account | null): ERC20Balance {
	let id = contract.id.toHex().concat('/').concat(account ? account.id.toHex() : 'totalSupply')
	let balance = ERC20Balance.load(id)

	if (balance == null) {
		balance = new ERC20Balance(id)
		balance.contract = contract.id
		balance.account = account ? account.id : null
		balance.value = constants.BIGDECIMAL_ZERO
		balance.valueExact = constants.BIGINT_ZERO
		balance.save()
	}

	return balance as ERC20Balance
}

export function fetchERC20Approval(contract: ERC20Contract, owner: Account, spender: Account): ERC20Approval {
	let id = contract.id.toHex().concat('/').concat(owner.id.toHex()).concat('/').concat(spender.id.toHex())
	let approval = ERC20Approval.load(id)

	if (approval == null) {
		approval = new ERC20Approval(id)
		approval.contract = contract.id
		approval.owner = owner.id
		approval.spender = spender.id
		approval.value = constants.BIGDECIMAL_ZERO
		approval.valueExact = constants.BIGINT_ZERO
	}

	return approval as ERC20Approval
}

```

```
// mytoken.ts
import {
	Address,
} from '@graphprotocol/graph-ts'

import {
	ERC20Transfer,
} from '../generated/schema'

import {
	Transfer as TransferEvent,
	Approval as ApprovalEvent,
} from '../generated/MyToken/MyToken'

import {
	decimals,
	events,
	transactions,
} from '@amxx/graphprotocol-utils'

import {
	fetchERC20,
	fetchERC20Balance,
	fetchERC20Approval,
	fetchAccount,
} from './fetch'

export function handleTransfer(event: TransferEvent): void {
	let contract = fetchERC20(event.address)
	let ev = new ERC20Transfer(events.id(event))
	ev.emitter = contract.id
	ev.transaction = transactions.log(event).id
	ev.timestamp = event.block.timestamp
	ev.contract = contract.id
	ev.value = decimals.toDecimals(event.params.value, contract.decimals)
	ev.valueExact = event.params.value

	if (event.params.from == Address.zero()) {
		let totalSupply = fetchERC20Balance(contract, null)
		totalSupply.valueExact = totalSupply.valueExact.plus(event.params.value)
		totalSupply.value = decimals.toDecimals(totalSupply.valueExact, contract.decimals)
		totalSupply.save()
	} else {
		let from = fetchAccount(event.params.from)
		let balance = fetchERC20Balance(contract, from)
		balance.valueExact = balance.valueExact.minus(event.params.value)
		balance.value = decimals.toDecimals(balance.valueExact, contract.decimals)
		balance.save()

		ev.from = from.id
		ev.fromBalance = balance.id
	}

	if (event.params.to == Address.zero()) {
		let totalSupply = fetchERC20Balance(contract, null)
		totalSupply.valueExact = totalSupply.valueExact.minus(event.params.value)
		totalSupply.value = decimals.toDecimals(totalSupply.valueExact, contract.decimals)
		totalSupply.save()
	} else {
		let to = fetchAccount(event.params.to)
		let balance = fetchERC20Balance(contract, to)
		balance.valueExact = balance.valueExact.plus(event.params.value)
		balance.value = decimals.toDecimals(balance.valueExact, contract.decimals)
		balance.save()

		ev.to = to.id
		ev.toBalance = balance.id
	}
	ev.save()
}

export function handleApproval(event: ApprovalEvent): void {
	let contract = fetchERC20(event.address)

	let owner = fetchAccount(event.params.owner)
	let spender = fetchAccount(event.params.spender)
	let approval = fetchERC20Approval(contract, owner, spender)
	approval.valueExact = event.params.value
	approval.value = decimals.toDecimals(event.params.value, contract.decimals)
	approval.save()
}
```

[Learn more about writing mappings here](https://thegraph.com/docs/en/developing/creating-a-subgraph/#writing-mappings).

## Codegen, create and deploy subgraph

At the project structure, open up your Terminal, to generate code:

```
npm run codegen
```

After finishing, `generated` folder will be created. It contains AssemblyScript files that defined in GraphQL schema and ABI files:

```
generated/
    MyToken/
        MyToken.ts
    schema.ts
```

Then create your subgraph on graphnode:

```
npm run create
```

You'll see something similar:

```
> sample-subgraph@1.0.0 create
> graph create u2u/subgraph --node http://127.0.0.1:8020

Created subgraph: u2u/subgraph
```

Next deploy your subgraph:

```
npm run deploy
```

The output is as below:

```
> sample-subgraph@1.0.0 deploy
> graph deploy u2u/subgraph --ipfs http://127.0.0.1:5001 --node http://127.0.0.1:8020

Which version label to use? (e.g. "v0.0.1"): v0.0.1
  Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
  Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
  Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
  Skip migration: Bump mapping apiVersion from 0.0.4 to 0.0.5
  Skip migration: Bump mapping apiVersion from 0.0.5 to 0.0.6
  Skip migration: Bump manifest specVersion from 0.0.1 to 0.0.2
  Skip migration: Bump manifest specVersion from 0.0.2 to 0.0.4
✔ Apply migrations
✔ Load subgraph from subgraph.yaml
  Compile data source: MyToken => build/MyToken/MyToken.wasm
✔ Compile subgraph
  Copy schema file build/schema.graphql
  Write subgraph file build/MyToken/abis/MyToken.json
  Write subgraph manifest build/subgraph.yaml
✔ Write compiled subgraph to build/
  Add file to IPFS build/schema.graphql
                .. QmTJC228tSzgV6ano5uSgVkk4yq3tdpUAZ11xBBnqtKbmm
  Add file to IPFS build/MyToken/abis/MyToken.json
                .. QmUfqVeUafPnxQbia1tCA9mCtvcRDAoxLjsCnvioEfK2P4
  Add file to IPFS build/MyToken/MyToken.wasm
                .. QmZjUQmrLP75UqCypjvQSLzfYs35nX5GvNRur3QCjgYq8P
✔ Upload subgraph to IPFS

Build completed: Qmf6snbu1krZwRL3MbjK1xBusxvbWeP39G2Z54WK6WPsfX

Deployed to http://127.0.0.1:8000/subgraphs/name/u2u/subgraph/graphql

Subgraph endpoints:
Queries (HTTP):     http://127.0.0.1:8000/subgraphs/name/u2u/subgraph
```

## Visit your subgraph's GraphiQL

Use your browser to access deployed subgraph: `http://127.0.0.1:8000/subgraphs/name/u2u/subgraph/graphql`

<figure><img src="/files/TxoRtYKIkNAlqW2qD6Ri" alt=""><figcaption></figcaption></figure>

## Summary

We have gone through how to deploy subgraph on graphnode that watches U2U network. For more detail please visit [The Graph documentation](https://thegraph.com/docs/en/developing/creating-a-subgraph/).

To sum up:

1. Add contract ABI
2. Write mappings for contract in `/src/*`
3. Define models in `schema.graphql`&#x20;
4. Wire up contract, its events, mappings in `subgraph.yaml`
5. Try `codegen` to see if any errors
6. Run `create` then `deploy`


---

# 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.u2u.xyz/services/the-graph/deploy-a-subgraph.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.
