Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated NFT Subgraph Workshop 2023 #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
node_modules
generated
build
build
.git
.gitignore
.vscode
149 changes: 76 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,45 @@
## Slides

[![Top Slide](./slide1.png)](https://docs.google.com/presentation/d/1-jZd4Sp83YW6r2KhXYeU4sOlKdcmp0LVi3WF1VAkxzk/edit?usp=sharing)
[![Top Slide](./slide1how3marcus.png)](https://docs.google.com/presentation/d/1MMgXx_GrufU_o0JdFhEmqpxRKAFyMAxSdYyGO-9kfnU/edit?usp=sharing)

## Cheatsheet

[![Cheatsheet](./cheatsheet.png)](./cheatsheet_Design_ETH_SF.pdf)

## Good subgraphs:

- [Messari Subgraphs](https://subgraphs.messari.io)
- [EIP-721 (NFTS on The Graph Network)](https://thegraph.com/explorer/subgraph?id=AVZ1dGwmRGKsbDAbwvxNmXzeEkD48voB3LfGqj5w7FUS&view=Overview)
- [Lens Protocol](https://thegraph.com/hosted-service/subgraph/anudit/lens-protocol)
- [Unlock Protocol on The Graph Network](https://thegraph.com/explorer/subgraph?id=8u7KcVRxjtTDRgEJup3UuPJk6YoRDTHNpSMk5BEpdw42&view=Overview)
- [Open Sea Subgraph](https://thegraph.com/hosted-service/subgraph/protofire/opensea-wyvern-exchange-subgraph)
- [LiNEAR](https://thegraph.com/hosted-service/subgraph/linear-protocol/linear)
- [Aave Gotchi](https://thegraph.com/hosted-service/subgraph/aavegotchi/aavegotchi-core-matic)
- [Tellor](https://thegraph.com/hosted-service/subgraph/tellor-io/tellorxoraclemainhgraph)
- [Live Peer](https://thegraph.com/hosted-service/subgraph/livepeer/arbitrum-one)
- [ENS](https://thegraph.com/hosted-service/subgraph/ensdomains/ens)
- [UMA on The Graph Network](https://thegraph.com/explorer/subgraph?id=41LCrgtCNBQyDiVVyZEuPxbvkBH9BxxLU3nEZst77V8o&view=Overview)
- [Messari Subgraphs](https://subgraphs.messari.io)
- [EIP-721 (NFTS on The Graph Network)](https://thegraph.com/explorer/subgraph?id=AVZ1dGwmRGKsbDAbwvxNmXzeEkD48voB3LfGqj5w7FUS&view=Overview)
- [Lens Protocol](https://thegraph.com/hosted-service/subgraph/anudit/lens-protocol)
- [Unlock Protocol on The Graph Network](https://thegraph.com/explorer/subgraph?id=8u7KcVRxjtTDRgEJup3UuPJk6YoRDTHNpSMk5BEpdw42&view=Overview)
- [Open Sea Subgraph](https://thegraph.com/hosted-service/subgraph/protofire/opensea-wyvern-exchange-subgraph)
- [LiNEAR](https://thegraph.com/hosted-service/subgraph/linear-protocol/linear)
- [Aave Gotchi](https://thegraph.com/hosted-service/subgraph/aavegotchi/aavegotchi-core-matic)
- [Tellor](https://thegraph.com/hosted-service/subgraph/tellor-io/tellorxoraclemainhgraph)
- [Live Peer](https://thegraph.com/hosted-service/subgraph/livepeer/arbitrum-one)
- [ENS](https://thegraph.com/hosted-service/subgraph/ensdomains/ens)
- [UMA on The Graph Network](https://thegraph.com/explorer/subgraph?id=41LCrgtCNBQyDiVVyZEuPxbvkBH9BxxLU3nEZst77V8o&view=Overview)

## Info

- [Contract to index](https://etherscan.io/address/0xc2c747e0f7004f9e8817db2ca4997657a7746928)
- [Google Slides for NFT Subgraph Development Workshop](https://docs.google.com/presentation/d/1-jZd4Sp83YW6r2KhXYeU4sOlKdcmp0LVi3WF1VAkxzk/edit?usp=sharing)
- Questions: **[twitter.com/schmid_si](https://twitter.com/schmid_si)**
- [Contract to index](https://etherscan.io/address/0xc2c747e0f7004f9e8817db2ca4997657a7746928)
- [Google Slides for NFT Subgraph Development Workshop](https://docs.google.com/presentation/d/1-jZd4Sp83YW6r2KhXYeU4sOlKdcmp0LVi3WF1VAkxzk/edit?usp=sharing)
- Questions:
- **[twitter.com/schmid_si](https://twitter.com/schmid_si)**
- **[twitter.com/Marcus_Rein\_](https://twitter.com/Marcus_Rein_)**

## Prerequisites

- Install graph-cli: `yarn global add @graphprotocol/graph-cli`
- Install graph-cli: `yarn global add @graphprotocol/graph-cli`

## First Steps

- [Find the contract on Etherscan](https://etherscan.io/address/0xc2c747e0f7004f9e8817db2ca4997657a7746928)
- [Find the contract creation transaction for startBlock](https://etherscan.io/tx/0xe9e60dc12e1a7bc545aa497bc494f5f54ce81da06de4f6fef50459816218e66b)
- Download the ABI
- [Find the contract on Etherscan](https://etherscan.io/address/0xc2c747e0f7004f9e8817db2ca4997657a7746928)
- [Find the contract creation transaction for startBlock](https://etherscan.io/tx/0xe9e60dc12e1a7bc545aa497bc494f5f54ce81da06de4f6fef50459816218e66b)
- Download the ABI

- Run this command to initialise the subgraph with events:
- Run this command to initialise the subgraph with events:

```bash
graph init \
Expand All @@ -51,8 +54,8 @@ graph init \
hashmasks hashmasks-subgraph
```

- Inspect the source
- Change startblock:
- Inspect the source
- Change startblock:

```
source:
Expand All @@ -63,18 +66,18 @@ source:

– Create new subgraph on [Subgraph Studio](https://thegraph.com/studio/) named "Hashmasks"

- `graph auth --studio ...`
- `yarn deploy`
- `graph auth --studio ...`
- `yarn deploy`

## Remove unused Entities and Events

```graphql
# schema.graphql
type Transfer @entity {
id: ID!
from: Bytes! # address
to: Bytes! # address
tokenId: BigInt! # uint256
id: ID!
from: Bytes! # address
to: Bytes! # address
tokenId: BigInt! # uint256
}
```

Expand All @@ -84,78 +87,78 @@ Make them immutable for performance improvements

```graphql
type Transfer @entity(immutable: true) {
id: ID!
from: Bytes! # address
to: Bytes! # address
tokenId: BigInt! # uint256
timestamp: BigInt!
blockNumber: BigInt!
id: ID!
from: Bytes! # address
to: Bytes! # address
tokenId: BigInt! # uint256
timestamp: BigInt!
blockNumber: BigInt!
}
```

Use `event.transaction.hash.toHex() + "-" + event.logIndex.toString()` as the id for events

```typescript
export function handleTransfer(event: TransferEvent): void {
let entity = new Transfer(
event.transaction.hash.toHex() + "-" + event.logIndex.toString()
);
entity.blockNumber = event.block.number;
entity.timestamp = event.block.timestamp;
entity.from = event.params.from;
entity.to = event.params.to;
entity.tokenId = event.params.tokenId;
entity.save();
let entity = new Transfer(
event.transaction.hash.toHex() + "-" + event.logIndex.toString()
);
entity.blockNumber = event.block.number;
entity.timestamp = event.block.timestamp;
entity.from = event.params.from;
entity.to = event.params.to;
entity.tokenId = event.params.tokenId;
entity.save();
}
```

### Store logical entities

- Identify the important entities: Token, Owner, Contract
- Link them
- Identify the important entities: Token, Owner, Contract
- Link them

```graphql
type Transfer @entity(immutable: true) {
id: ID!
from: Owner!
to: Owner!
token: Token!
timestamp: BigInt!
blockNumber: BigInt!
id: ID!
from: Owner!
to: Owner!
token: Token!
timestamp: BigInt!
blockNumber: BigInt!
}

type Token @entity {
id: ID!
owner: Owner
uri: String
transfers: [Transfer!]! @derivedFrom(field: "token")
contract: Contract
id: ID!
owner: Owner
uri: String
transfers: [Transfer!]! @derivedFrom(field: "token")
contract: Contract
}

type Owner @entity {
id: Bytes! # Use bytes as ID
ownedTokens: [Token!]! @derivedFrom(field: "owner")
balance: BigInt
id: Bytes! # Use bytes as ID
ownedTokens: [Token!]! @derivedFrom(field: "owner")
balance: BigInt
}

type Contract @entity {
id: ID!
name: String
symbol: String
totalSupply: BigInt
mintedTokens: [Token!]! @derivedFrom(field: "contract")
id: ID!
name: String
symbol: String
totalSupply: BigInt
mintedTokens: [Token!]! @derivedFrom(field: "contract")
}
```

## Other resources

- https://github.com/schmidsi/hackathon-starterkit
- https://github.com/scaffold-eth/scaffold-eth#-scaffold-eth
- https://soulbound.xyz
- https://github.com/Developer-DAO/resources
- https://dev.to/dabit3/the-complete-guide-to-full-stack-ethereum-development-3j13
- https://github.com/itsjerryokolo/CryptoPunks
- https://github.com/dabit3/building-a-subgraph-workshop
- https://thegraph.com/docs/developer/quick-start
- https://thegraph.com/discord
- https://protean-labs.github.io/subgrounds/
- https://github.com/schmidsi/hackathon-starterkit
- https://github.com/scaffold-eth/scaffold-eth#-scaffold-eth
- https://soulbound.xyz
- https://github.com/Developer-DAO/resources
- https://dev.to/dabit3/the-complete-guide-to-full-stack-ethereum-development-3j13
- https://github.com/itsjerryokolo/CryptoPunks
- https://github.com/dabit3/building-a-subgraph-workshop
- https://thegraph.com/docs/developer/quick-start
- https://thegraph.com/discord
- https://protean-labs.github.io/subgrounds/
Binary file added slide1how3marcus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.