Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
NFTのインデクシングとGraphQLのすゝめ / NFT indexing and GraphQL
Search
serinuntius
July 12, 2022
Technology
0
200
NFTのインデクシングとGraphQLのすゝめ / NFT indexing and GraphQL
no plan inc. CTO @_serinuntius
2022.07.12, TOKYO BLOCKCHAIN TECH MEETUP 2022 登壇資料
serinuntius
July 12, 2022
Tweet
Share
More Decks by serinuntius
See All by serinuntius
TauriとRustとSolidJSで作るEthereum Address生成機 / Ethereum Address Generator made by Tauri, Rust, SolidJS
serinuntius
0
280
世界最速でArbitrumで NFTを作って震えたい!!!!/ I want to make NFT with Arbitrum in the fastest way in the world and tremble !!!!
serinuntius
0
650
なぜフラッシュローンという概念が俺達の魂を震えさせるのか / Why does the concept of flash loans make our souls tremble?
serinuntius
0
1k
Why does the concept of DeFi make our souls tremble? / なぜDeFiという概念が俺達の魂を震えさせるのか ~DEX(AMM)まで~
serinuntius
0
1.3k
NotionがCMS代わりに!? / Notion replaces CMS!?
serinuntius
0
980
ont hackathon
serinuntius
0
90
Golangでリクエストごとのクエリログが見たい!! kamakura.go #4 / go-query-and-request-logger
serinuntius
1
920
新卒Rubyistが1ヶ月で Perl Mongerになった話
serinuntius
0
540
Other Decks in Technology
See All in Technology
モバイルゲーム開発におけるエージェント技術活用への試行錯誤 ~開発効率化へのアプローチの紹介と未来に向けた展望~
qualiarts
0
660
多様なデジタルアイデンティティを攻撃からどうやって守るのか / 20251212
ayokura
0
330
Microsoft Agent 365 を 30 分でなんとなく理解する
skmkzyk
1
1k
安いGPUレンタルサービスについて
aratako
2
2.6k
AI活用によるPRレビュー改善の歩み ― 社内全体に広がる学びと実践
lycorptech_jp
PRO
1
190
Ruby で作る大規模イベントネットワーク構築・運用支援システム TTDB
taketo1113
1
210
Oracle Technology Night #95 GoldenGate 26ai の実装に迫る1
oracle4engineer
PRO
0
150
モダンデータスタック (MDS) の話とデータ分析が起こすビジネス変革
sutotakeshi
0
430
AWS Trainium3 をちょっと身近に感じたい
bigmuramura
1
130
Sansanが実践する Platform EngineeringとSREの協創
sansantech
PRO
2
690
A Compass of Thought: Guiding the Future of Test Automation ( #jassttokai25 , #jassttokai )
teyamagu
PRO
1
250
RAG/Agent開発のアップデートまとめ
taka0709
0
140
Featured
See All Featured
Bash Introduction
62gerente
615
210k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
Java REST API Framework Comparison - PWX 2021
mraible
34
9k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
A better future with KSS
kneath
240
18k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
9
1k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
196
70k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.1k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.3k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
GitHub's CSS Performance
jonrohan
1032
470k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
Transcript
NFTのインデクシングと GraphQLのすゝめ Presentation by @_serinuntius 2022.07.12, TOKYO BLOCKCHAIN TECH MEETUP
2022
今日話すこと 自己紹介 NFTのインデクシングとは? なぜインデクシングが必要なのか? インデクシングの実装 GraphQLのすゝめ まとめ
自己紹介 芹川葵: @_serinuntius no plan inc. CTO JPYC 技術顧問 趣味:
キャンプ スノボ
興味ある技術とか、最近やってる技術とか(雑)
NFTのインデクシングとは? NFTが持つ情報や付随する情報を、検索し易いよ うにDBに格納すること tokenId address metadata 1 0xabc {"image": "ipfs://..."}
2 0x123 {"image": "ipfs://..."} 3 0x456 {"image": "ipfs://..."} 4 0x789 {"image": "ipfs://..."}
なぜインデクシングが必要なのか? 一般的にNFTの情報にアクセスするには、コントラクトに生えてるview関数を叩く function ownerOf(uint256 tokenId) public view virtual override returns
(address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: invalid token ID"); return owner; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; }
なぜインデクシングが必要なのか? 一般的にNFTの情報にアクセスするには、コントラクトに生えてるview関数を叩く function ownerOf(uint256 tokenId) public view virtual override returns
(address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: invalid token ID"); return owner; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; }
なぜインデクシングが必要なのか? 一般的にNFTの情報にアクセスするには、コントラクトに生えてるview関数を叩く function tokenURI(uint256 tokenId) public view virtual override returns
(string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: invalid token ID"); return owner; }
なぜインデクシングが必要なのか? 一般的にNFTの情報にアクセスするには、コントラクトに生えてるview関数を叩く function ownerOf(uint256 tokenId) public view virtual override returns
(address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: invalid token ID"); return owner; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; }
なぜインデクシングが必要なのか? 一般的にNFTの情報にアクセスするには、コントラクトに生えてるview関数を叩く 情報が欲しくなった時にview関数を叩きまくるのは色々と現実的ではない ノードの負担増🆙, Infura, Alchemy等のノードプロバイダーのコスト増🆙 時間もかかる function ownerOf(uint256 tokenId)
public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: invalid token ID"); return owner; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; }
なぜインデクシングが必要なのか? 一般的にNFTの情報にアクセスするには、コントラクトに生えてるview関数を叩く 情報が欲しくなった時にview関数を叩きまくるのは色々と現実的ではない ノードの負担増🆙, Infura, Alchemy等のノードプロバイダーのコスト増🆙 時間もかかる ERC1155対応の闇😈 function ownerOf(uint256
tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: invalid token ID"); return owner; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; }
ERC1155対応の闇😈
ERC1155対応の闇😈 ERC721みたいな ownerOf(tokenId) が生えてないので、 tokenId の所有者情報をview関数だけでは 調べることができない😇 ` ` `
`
ERC1155対応の闇😈 ERC721みたいな ownerOf(tokenId) が生えてないので、 tokenId の所有者情報をview関数だけでは 調べることができない😇 name() が生えてないのも地味にだるい ノードの情報だけでは何のコントラクトなのかわからない
ERC721は規格としてマストにはなってないものの、OpenZeppelinの ERC721Metadata が普及して いるため、大体取れる気がする ` ` ` ` ` ` ` `
どうやってインデクシングするのか?
闇の魔術😈に対する防衛術をお教えします👍
インデクシングの実装
インデクシングの実装 EVMには 「event」 という概念がある
インデクシングの実装 EVMには 「event」 という概念がある ノードに対してイベントをリッスンしておくことで、コントラクトからイベントが発火した時に何かを実行 できる
インデクシングの実装 EVMには 「event」 という概念がある ノードに対してイベントをリッスンしておくことで、コントラクトからイベントが発火した時に何かを実行 できる ex) ERC721 event Transfer(address
indexed from, address indexed to, uint256 indexed tokenId);
インデクシングの実装 EVMには 「event」 という概念がある ノードに対してイベントをリッスンしておくことで、コントラクトからイベントが発火した時に何かを実行 できる ex) ERC721 indexed というキーワードをつけると、その変数は検索できるようになる
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); ` `
インデクシングの実装 EVMには 「event」 という概念がある ノードに対してイベントをリッスンしておくことで、コントラクトからイベントが発火した時に何かを実行 できる ex) ERC721 indexed というキーワードをつけると、その変数は検索できるようになる
eth_getLogs というAPIを呼び出すことによってイベントを取得できる event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); ` ` ` `
インデクシングの実装 EVMには 「event」 という概念がある ノードに対してイベントをリッスンしておくことで、コントラクトからイベントが発火した時に何かを実行 できる ex) ERC721 indexed というキーワードをつけると、その変数は検索できるようになる
eth_getLogs というAPIを呼び出すことによってイベントを取得できる どのブロック高でそのイベントが発生したかがわかる event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); ` ` ` `
インデクシングの実装 - ERC721
インデクシングの実装 - ERC721 1ブロック目から、
インデクシングの実装 - ERC721 1ブロック目から、 event Transfer(address indexed from, address indexed
to, uint256 indexed tokenId);
インデクシングの実装 - ERC721 1ブロック目から、 これを順に追って行けば良い event Transfer(address indexed from, address
indexed to, uint256 indexed tokenId);
インデクシングの実装 - ERC721 1ブロック目から、 これを順に追って行けば良い 最後に同期したブロック高をdbに入れて、次回以降は差分更新で良い event Transfer(address indexed from,
address indexed to, uint256 indexed tokenId);
インデクシングの実装 - ERC1155
インデクシングの実装 - ERC1155 ERC1155の場合はイベントが2種類ある
インデクシングの実装 - ERC1155 ERC1155の場合はイベントが2種類ある event TransferSingle(address indexed operator, address indexed
from, address indexed to, uint256 id, uint256 value); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values );
インデクシングの実装 - ERC1155 ERC1155の場合はイベントが2種類ある event TransferSingle(address indexed operator, address indexed
from, address indexed to, uint256 id, uint256 value); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values );
インデクシングの実装 - ERC1155 ERC1155の場合はイベントが2種類ある event TransferBatch( address indexed operator, address
indexed from, address indexed to, uint256[] ids, uint256[] values ); event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
インデクシングの実装 - ERC1155 ERC1155の場合はイベントが2種類ある event TransferSingle(address indexed operator, address indexed
from, address indexed to, uint256 id, uint256 value); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values );
インデクシングの実装 - ERC1155 ERC1155の場合はイベントが2種類ある これらを順に追って行けば良い event TransferSingle(address indexed operator, address
indexed from, address indexed to, uint256 id, uint256 value); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values );
GraphQLのすゝめ (時間なかった) 先程行ったインデクシングでDBに保管してGraphQLで返すように実装してみました 型付のクライアントが自動生成できるのでオススメ🔥 Nestjs / PlanetScale / Prisma /
Cloud Run 辺りで実装しています
この辺りを全部気をつけて 実装するの面倒では?🤔🤔🤔
その通り!
面倒ごとを全部うちが引き受けて インデクシングするSaaS始めます!
NFT GraphQL API (仮)
NFT GraphQL API (仮) ⛓ 任意のEVM互換のチェーンに対応できる(サポートして欲しいチェーンがあればお気軽に連絡くださ い)
NFT GraphQL API (仮) ⛓ 任意のEVM互換のチェーンに対応できる(サポートして欲しいチェーンがあればお気軽に連絡くださ い) 💰 実装コストやら、ノードのメンテコストやら考えると圧倒的コスパ
NFT GraphQL API (仮) ⛓ 任意のEVM互換のチェーンに対応できる(サポートして欲しいチェーンがあればお気軽に連絡くださ い) 💰 実装コストやら、ノードのメンテコストやら考えると圧倒的コスパ ¥
ボラの高い草コインじゃなくて、日本円で払えます(円も実質草コイ・・・🤫
NFT GraphQL API (仮) ⛓ 任意のEVM互換のチェーンに対応できる(サポートして欲しいチェーンがあればお気軽に連絡くださ い) 💰 実装コストやら、ノードのメンテコストやら考えると圧倒的コスパ ¥
ボラの高い草コインじゃなくて、日本円で払えます(円も実質草コイ・・・🤫 🚀 もう少しでリリースするのでちぇけら
興味ある方はこちら
参考文献 EIP721 EIP1155 OpenZeppelin - IERC721.sol OpenZeppelin - IERC1155.sol
ご静聴ありがとうございました🙌