> For the complete documentation index, see [llms.txt](https://docs.u2u.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.u2u.xyz/services/the-graph/deploy-a-subgraph.md).

# 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`
