Index and Query Blockchain Data with Ghost using DYLI on Abstract
Overview
This guide is in collaboration with DYLI to showcase how they are using Ghost to index and query their smart contract data on Abstract Chain
What is Ghost and Why Does It Matter?
Ghost is a next-generation indexing stack that empowers developers to build GraphQL APIs for extracting, transforming, storing, and querying blockchain data.
What sets Ghost apart from other indexers:
-
Write indexers in the same language as your smart contracts (Solidity) - Since smart contract developers emit critical events for indexers, they should also have the ability to write the indexers themselves, without needing to learn new languages or tools.
-
Fully browser-based - Ghost requires no command-line tools or downloads. Everything is built and deployed directly from your browser, streamlining the developer experience.
-
Blazing-fast performance - Deploy indexers (subgraphs) in seconds, drastically reducing setup time and increasing efficiency for real-time blockchain data access.
Ghost is designed to make blockchain data indexing more intuitive, seamless, and efficient for smart contract developers.
What is DYLI?
DYLI allows users to instantly launch, collect, and trade physical products, with the option to redeem them whenever they're ready.
A quick overview:
-
Launch and Sell Drops: Quickly move from idea to product launch—DYLI handles production, warehousing, and shipping
-
Buy and Trade Instantly: Purchase limited drops directly from creators and trade them instantly on our marketplace, with creators earning royalties on every transaction.
-
Redemption: Redeem your digital drop for the physical product whenever you're ready, with authenticity guaranteed.
-
Unified Experience: DYLI merges primary and secondary markets, making the creating and collecting experiences more streamlined and enjoyable for everyone.
In this example, we will track on-chain events emitted by DYLI's marketplace contract. Using their testnet app, we'll take actions and verify the data indexed by Ghost in real-time.
Pre-requisites
To follow along, you'll need to sign up for two accounts:
- A Ghost account. This will be used to create our indexer for DYLI's marketplace contract.
- A DYLI account. We'll use this to submit on-chain transactions on DYLI's testnet platform and verify that the transactions are being properly indexed.
Let's Get Started
Log in to Ghost and navigate to the library.
Here, you’ll find all the Ghost Graphs created and shared by the community, including teams and other protocols.
Filter by Abstract Testnet
and locate the dyliMarketplace
Ghost Graph created by DYLI. Click the fork button to copy
this graph into your own workspace.
Next, navigate to the Indexes
tab and select the graph to open it in the code editor.
Code Editor
There are three files that you need to familiarize yourself in the code editor.
- Events.sol
- Schema.sol
- Indexer.sol
Events.sol
Smart contracts emit events for users to track. In this case, we define the specific events we want to monitor.
While there are several events of interest, we'll focus on the OfferCreated
event for this example.
Whenever someone offers to purchase an item on DYLI, a transaction is submitted onchain and DYLI's marketplace smart
contract will emit the OfferCreated
event for anyone who wants to track this event.
Schema.sol
The schema file allows us to define entities as Solidity structs. In this example, we have Listing
and Offer
entities.
You can think of an entity as an object with multiple properties. These entities are what we'll create and keep
updated (we'll cover how in the next section) and can be queried after deployment.
By storing Listings
and Offers
, we can track and query the latest events emitted on-chain, such as new listings or
offers.
Indexer.sol
Once you've reviewed the events and schema, we can move on to indexer.sol
, where the core indexing logic resides. In
this file, we register the contract addresses we want to listen to for events. Check out the registerHandle
function
for how we link these addresses.
We also define transformation functions for each event type (as defined in events.sol
). These functions allow us to
retrieve an entity, update it using event data, and then save the updated entity.
For example, whenever an OfferCreated
event is emitted, we perform a transformation. Here, we create a new Offer
object, populate it with the event parameters, and store it in the respective fields within a struct. Finally, we save
the entity using graph.saveOffer(offer)
, enabling us to query this data later.
Compile and Deploy
After reviewing every file, compile and deploy your Ghost Graph. After a few seconds, your Ghost Graph should be fully deployed and synchronized with the chain. You'll see how many entities are stored in your graph and have access to various buttons for further exploration.
Next, click on the playground
button to launch your GraphQL playground.
GraphQL Playground
Copy and paste the query below into your playground and click on the big pink play button to query your graph.
query LatestOffers {
offers(orderBy: "timestamp", orderDirection: "desc") {
items {
expiration
id
isActive
timestamp
tokenId
txHash
buyer
amount
offerId
}
}
}
Let's keep this tab open as we will come back to it later.
Take Action on the DYLI Testnet
Next, head to DYLI’s testnet and click the Place an offer
button to make an offer.
This will trigger an on-chain transaction on the Abstract Chain
that emits an OfferCreated
event, which Ghost
will
automatically track and index!
Return to the GraphQL Playground
Re-run the same query as before, and you'll see the latest offer appear at the top of the list. In this updated example,
the latest offerId is 14
, whereas it was previously 13
.
Conclusion
That's it! You've successfully tracked smart contract events using Ghost. This example should inspire dApp developers building on Abstract, and we'd like to thank DYLI for sharing their indexer code with the Abstract community as a valuable reference for others.