> ## Content Index
> Fetch the complete content index at: https://blog.morph.network/llms.txt
> Use this file to discover other available public pages before exploring further.

# Query and Index Smart Contracts on Morph using Goldsky
- URL: https://blog.morph.network/query-and-index-smart-contracts-on-morph-using-goldsky/
- Published: 2024-07-23T15:07:38.000Z
- Updated: 2024-11-10T04:17:42.000Z
- Author: Morph
- Tags: #ernest

# **Introduction**

**Picture this:** you're a developer with a brand-new smart contract deployed on the Morph. Your next challenge is to efficiently query and retrieve on-chain data for your decentralized application (dApp). That's where subgraphs come in. Subgraphs offer a powerful and flexible way to index and query blockchain data, making it easy to build responsive and data-rich dApps.

In this tutorial, we'll walk through deploying a smart contract on the Morph chain and setting up a subgraph to query this contract. We’ll also introduce Goldsky, a tool that makes creating and managing subgraphs a breeze. Let’s get started and see what we can build together!

## **Real-World Use Cases for Subgraphs**

Subgraphs are incredibly useful in various scenarios, such as:

**Decentralized Finance (DeFi)**: Indexing and querying trading volumes, liquidity pools, and token swaps.

**NFT Marketplaces:** Tracking ownership, sales, and metadata of NFTs.

**DAO Governance**: Fetching proposal details, vote counts, and participant information.

**Supply Chain Management**: Monitoring the flow of goods and verifying transactions.

## **What is a Subgraph?**

A subgraph is a way to ingest, process, and index data from a blockchain. It lets you define which data to index and how to store it, making it easy to query later. Subgraphs are exposed to developers via GraphQL APIs, allowing users to query the transaction data happening on their contract in real time. Subgraphs are especially beneficial for developers of complex, custom smart contracts that need to have robust frontend interfaces.

## **Why Use a Subgraph Instead of Direct Contract Queries?**

You might wonder, *"Why not just query the contract directly using tools like Wagmi?"* Here are a few reasons why subgraphs are often a better choice:

- **Efficiency**: Direct contract queries can be inefficient and slow, especially when dealing with large datasets. Subgraphs index data off-chain, enabling faster and more efficient queries.
- **Complex Queries**: Subgraphs allow for more complex queries that can involve filtering, sorting, and aggregating data, which can be cumbersome to do directly on-chain.
- **Reduced Load**: By offloading data processing to subgraphs, you reduce the computational load on the blockchain, which can be beneficial for both your dApp's performance and the network's health.
- **User Experience**: Faster and more efficient data retrieval improves the user experience, making your dApp more responsive and engaging.

## **Introducing Goldsky**

Goldsky is a high-performance data indexing provider for Morph that makes it easy to extract, transform, and load on-chain data to power both application and analytics use cases.

 It provides an intuitive interface and powerful features that streamline your development workflow, allowing you to focus on building your dApp without worrying about the complexities of data indexing.

## **What are we building?**

 In this tutorial, we will build a subgraph that indexes data from our [Fractionalized real-estate dApp](https://blog.morph.network/developer-guide-realestate-dapp/). We will use the subgraph to query details about properties, including ownership shares, prices and more.

 By the end of this tutorial, you will have a functional subgraph, and knowledge to create rich, data driven applications.

## **Setting up your environment** 

Before we start building, let us set up our environment. We will need a few tools and dependencies to get everything up and running. 

### **Prerequisites** 

- Node and npm: Ensure you have nodejs and npm installed. You can download them from [nodejs.org .](http://nodejs.org/?ref=blog.morph.network)
- Git - You will need git for version control.
- Graph CLI: The graphcli is essential for creating and deploying subgraphs

| npm install -g @graphprotocol/graph-cli |
| --------------------------------------- |

For Mac pc users, consider running this command with “sudo”.

### **Setting up a new project** 

| mkdir morph-goldsky cd morph-goldsky |
| ------------------------------------ |

  
## **Creating your subgraph**

Create a package.json file by running the following command in your terminal

| yarn init -yyarn add @graphprotocol/graph-ts |
| -------------------------------------------- |

The above command creates a package.json file and installs graph protocol types.

In the root of your project, follow these steps to set up the necessary files and folders:

1. Create a folder named abis and within it, create a file called Okido.json.
2. Create another folder named src and within it, create a file named mapping.ts.
3. In the root directory, create two additional files: schema.graphql and subgraph.yaml.

Your project directory should look this: 

![](https://lh7-us.googleusercontent.com/docsz/AD_4nXc9QJULaervPXR4xUok5umlBrHWpXRqpwlH5z4kw15EzJZ4fOHz27eZdpfY-w-Ohw0Zq5fK3HZW0dlatoEBWe-0k0jM98wl3QCVraqtU9x2mJ9iHV9mpG454TvRuCw1cXC2sL-rNgj8LHgEwNpFhckuUV6Q?key=M-HMzybTAYjA2mPxivMJ5g)

**Adding the ABI**

In your /abis/Okido.json file, paste in the abi for the Okido finance platform. You can access the abi [here](https://gist.github.com/Ernesto-tha-great/dbed048a68a27f15ee13d245ca15d528?ref=blog.morph.network).

**Defining the schema**

Navigate to the schema.graphql file and paste the following schema. The schema defines the types and relationships between our different entities. 

| type Property @entity { id: ID! tokenId: BigInt! fractionalContract: Bytes! pricePerShare: BigInt! totalShares: BigInt! sharesSold: BigInt! name: String! uri: String! shares: \[Share!\]! @derivedFrom(field: "property")}type Share @entity { id: ID! property: Property! owner: User! shares: BigInt! purchaseTimestamp: BigInt!}type User @entity { id: ID! properties: \[Share!\]! @derivedFrom(field: "owner")}type PropertyCreated @entity { id: ID! tokenId: BigInt! fractionalContract: Bytes! pricePerShare: BigInt! timestamp: BigInt!}type SharesPurchased @entity { id: ID! tokenId: BigInt! buyer: User! shares: BigInt! timestamp: BigInt!} |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

**Write the mappings**

Open the src/mapping.ts file and define the handlers for the events emitted by your smart contract. These functions constitute the logic that will run when an event is emitted. The function in our mappings allows us to fetch all properties, users and share data. You can copy the mappings for our project below :

| import { BigInt } from "@graphprotocol/graph-ts";import {Okido, PropertyCreated as PropertyCreatedEvent, SharesPurchased as SharesPurchasedEvent,} from "../generated/OkidoFinance Subgraph/Okido";import { Property,Share,User,PropertyCreated, SharesPurchased} from "../generated/schema";export function handlePropertyCreated(event: PropertyCreatedEvent): void { let property = new Property(event.params.tokenId.toString()); property.tokenId = event.params.tokenId; property.fractionalContract = event.params.fractionalContract; property.pricePerShare = event.params.pricePerShare; property.totalShares = BigInt.fromI32(0); property.sharesSold = BigInt.fromI32(0); property.name = event.params.name; property.uri = event.params.uri; property.save(); let propertyCreated = new PropertyCreated( event.transaction.hash.toHex() + "-" \+ event.logIndex.toString() ); propertyCreated.tokenId = event.params.tokenId; propertyCreated.fractionalContract = event.params.fractionalContract; propertyCreated.pricePerShare = event.params.pricePerShare; propertyCreated.timestamp = event.block.timestamp; propertyCreated.save();}export function handleSharesPurchased(event: SharesPurchasedEvent): void { let shareId = event.params.tokenId.toString() + "-" \+ event.params.buyer.toHex(); let share = Share.load(shareId); if (share == null) { share = new Share(shareId); share.property = event.params.tokenId.toString(); share.owner = event.params.buyer.toHex(); share.shares = BigInt.fromI32(0); share.purchaseTimestamp = event.block.timestamp; } share.shares = share.shares.plus(event.params.shares); share.save(); let property = Property.load(event.params.tokenId.toString()); if (property != null) { property.sharesSold = property.sharesSold.plus(event.params.shares); property.save(); } let user = User.load(event.params.buyer.toHex()); if (user == null) { user = new User(event.params.buyer.toHex()); } user.save(); let sharesPurchased = new SharesPurchased( event.transaction.hash.toHex() + "-" \+ event.logIndex.toString() ); sharesPurchased.tokenId = event.params.tokenId; sharesPurchased.buyer = event.params.buyer.toHex(); sharesPurchased.shares = event.params.shares; sharesPurchased.timestamp = event.block.timestamp; sharesPurchased.save();} |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

**Configure the subgraph/manifest**

Navigate to the subgraph.yaml file in the root of your project and configure it to index the events from your smart contract. Copy the manifest below and paste it into your project.

| specVersion: 0.0.4schema: file: ./schema.graphqldataSources: \- kind: ethereum name: OkidoFinance Subgraph network: morph-testnet source: address: "0xC97acACa1ed181d88aE2B86Fd49AE66482083B28" abi: Okido startBlock: 4132207 mapping: kind: ethereum/events apiVersion: 0.0.7 language: wasm/assemblyscript entities: \- Property \- Share \- User \- PropertyCreated \- SharesPurchased abis: \- name: Okido file: ./abis/Okido.json eventHandlers: \- event: PropertyCreated(indexed uint256,indexed address,uint256,string,string) handler: handlePropertyCreated \- event: SharesPurchased(indexed uint256,indexed address,uint256) handler: handleSharesPurchased file: ./src/mapping.ts |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

In this manifest, 

- Source: The address points to the deployment address of the Okido finance dApp, and the startBlock refers to the block where we intend to start indexing from. In this case, it's the block where the contract was deployed. You can get these details from the [morph holesky explorer](https://explorer-holesky.morphl2.io/tx/0xf1a18ab22fb99d6184e431e7fafe2666321bda1d0efbdf8c2e3fd140a6a087c1?ref=blog.morph.network).
- Entities: This refers to the types we created in our schema. For our project, we have five entities.
- Event Handlers: This specifies the event from the smart contract we are indexing (Okido finance in this case. You can check out the contract [here](https://gist.github.com/Ernesto-tha-great/c6b8665f1ae67ae86fad29d1d71327c5?ref=blog.morph.network)) and the handlers which perform logic as described in our mappings.ts file.

**Building the subgraph**

In your terminal, run:

| graph codegen |
| ------------- |

This generates the types and loads the abi of our project. Afterwards, you run:

| graph build |
| ----------- |

**Deploying on Goldsky**

To deploy our subgraph on Goldsky is really easy and just a few simple steps.

1. Navigate to [app.goldsky.com](http://app.goldsky.com/?ref=blog.morph.network) on your browser to create an account.
2. Create an API key on the settings page.
3. Install the Goldsky CLI and Login:

| curl https://goldsky.com \| sh |
| ------------------------------ |

Run the login command and add the API key created earlier:

| goldsky login |
| ------------- |

**Deploying the subgraph**

To deploy your subgraph, run the following command

| goldsky subgraph deploy okido-subgraph/1.0.5 --path |
| --------------------------------------------------- |

And voila! You should get a message saying your subgraph has been deployed. You should also be able to see your deployed subgraph on your project dashboard.

![](https://lh7-us.googleusercontent.com/docsz/AD_4nXcmZxWqqYwe7c3MHhHPW-dK0ITxnNuCCD8O4fZNdSA1_q-lBfhXPSbwHG6Zh2M1bFozVxWzXYQ8c7uAhxic2cpTWIEkQWBt5awBh-QEuZahg89lX45eeLm0PeN5ZwkEmPxi_2PddCmilMhwwCPc9TiIIQFF?key=M-HMzybTAYjA2mPxivMJ5g)

![](https://lh7-us.googleusercontent.com/docsz/AD_4nXfINDlc3BNXtbi48Pl9p70mX0RZS47p1ORj3aGdYuc0NcbtYS81SeLdblv7kE3bqD4IyeOqO3plGtpY3l5Uc8t5MrV9CZGq2PXIx_R_eyJOWxQtshOGbKVENvll7t4WTHynnL1eUwPflGHfDbAKpQm5M4V3?key=M-HMzybTAYjA2mPxivMJ5g)

  
![](https://lh7-us.googleusercontent.com/docsz/AD_4nXfnl940kYpUMbmsDXzbtU5ksXp6t-aVWt73D5T7srZJkiAPyqhH00MdG91xvleFle1bSiBkuBzujrmmqKJEh2QXASJALh3qVNtjMoe5Q0vcMm1W8qqPRyWtN9NlvlDV9o-fQSQxstMwhnzE7lCEI8ZFmDxd?key=M-HMzybTAYjA2mPxivMJ5g)

**Querying our subgraph**

We are going to be making two queries to test our subgraph.

- Fetching all properties.
- Fetching a single property using its token id.

#### **Fetching all properties**

To do so, click on the public graphql link to open the graphql playground. Then, run the query below to fetch all properties.

| query Properties{ properties { id tokenId pricePerShare totalShares sharesSold fractionalContract name uri shares { id owner { id } shares purchaseTimestamp } }} |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |

You should get the result of our query which lists every property created and share details for each.

![](https://lh7-us.googleusercontent.com/docsz/AD_4nXfnY86Vayr46Htk6qzmSHINbSuivlpwL89W-ivzusYKhmjS_k5WsylvP6WqxEAiMq2husesOuZ1W05BOkXdH791YI3dalkNjYRLYYmsgFlGyicg_P-e6xaC2kJ4Ewr7Zi4rGplPKsbBttrx7rSaRzoUKCE?key=M-HMzybTAYjA2mPxivMJ5g)

#### **Fetching a single property with token id**

To fetch a single property with an ID, we will modify our query as follows:

| query FetchPropertyById($tokenId:ID!) { property(id: $tokenId) { id tokenId pricePerShare totalShares sharesSold fractionalContract name uri shares { id owner { id } shares purchaseTimestamp } }} |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

![](https://lh7-us.googleusercontent.com/docsz/AD_4nXdSURd948q-8_JEkQH4GMCVnai4jcApAf0A_UaMY3NATGF_EnHCz1yZOaPv6OmGHsqXt2ekSdRNJCJ029IxJd3EeuwIjsqTRRldNstrySSv_Ot51k8jd3h4svcLf0ss2knJf93oFG3LQzg8zLY1X8Zq23I?key=M-HMzybTAYjA2mPxivMJ5g)

  
### **Conclusion**

Congratulations! You've successfully built a subgraph for querying data from a smart contract deployed on the Morph chain. You've learned how to define a schema, map events from your contract, and deploy your subgraph using Goldsky. This subgraph allows you to efficiently query and index blockchain data, providing a powerful tool for building more responsive and dynamic applications.

If you found this guide useful, leave a comment. You can check out the complete code for this project [here](https://github.com/Ernesto-tha-great/Goldsky-subgraph?ref=blog.morph.network). If you have any questions or get stuck, create an[ issue](https://github.com/Ernesto-tha-great/Goldsky-subgraph/issues?ref=blog.morph.network) on github or reach out on [discord](https://discord.com/invite/5SmG4yhzVZ?ref=blog.morph.network).