Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
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
190
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
260
世界最速でArbitrumで NFTを作って震えたい!!!!/ I want to make NFT with Arbitrum in the fastest way in the world and tremble !!!!
serinuntius
0
630
なぜフラッシュローンという概念が俺達の魂を震えさせるのか / Why does the concept of flash loans make our souls tremble?
serinuntius
0
980
Why does the concept of DeFi make our souls tremble? / なぜDeFiという概念が俺達の魂を震えさせるのか ~DEX(AMM)まで~
serinuntius
0
1.3k
NotionがCMS代わりに!? / Notion replaces CMS!?
serinuntius
0
950
ont hackathon
serinuntius
0
88
Golangでリクエストごとのクエリログが見たい!! kamakura.go #4 / go-query-and-request-logger
serinuntius
1
890
新卒Rubyistが1ヶ月で Perl Mongerになった話
serinuntius
0
530
Other Decks in Technology
See All in Technology
CI/CD/IaC 久々に0から環境を作ったらこうなりました
kaz29
1
150
製造業からパッケージ製品まで、あらゆる領域をカバー!生成AIを利用したテストシナリオ生成 / 20250627 Suguru Ishii
shift_evolve
PRO
1
120
IIWレポートからみるID業界で話題のMCP
fujie
0
770
ハノーバーメッセ2025座談会.pdf
iotcomjpadmin
0
160
Node-RED × MCP 勉強会 vol.1
1ftseabass
PRO
0
140
Oracle Audit Vault and Database Firewall 20 概要
oracle4engineer
PRO
3
1.7k
Microsoft Build 2025 技術/製品動向 for Microsoft Startup Tech Community
torumakabe
2
250
MySQL5.6から8.4へ 戦いの記録
kyoshidaxx
1
170
Claude Code Actionを使ったコード品質改善の取り組み
potix2
PRO
6
2.1k
変化する開発、進化する体系時代に適応するソフトウェアエンジニアの知識と考え方(JaSST'25 Kansai)
mizunori
1
200
Node-REDのFunctionノードでMCPサーバーの実装を試してみた / Node-RED × MCP 勉強会 vol.1
you
PRO
0
110
rubygem開発で鍛える設計力
joker1007
2
190
Featured
See All Featured
Documentation Writing (for coders)
carmenintech
71
4.9k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Speed Design
sergeychernyshev
32
1k
How to Think Like a Performance Engineer
csswizardry
24
1.7k
It's Worth the Effort
3n
185
28k
The Invisible Side of Design
smashingmag
299
51k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.8k
The Cost Of JavaScript in 2023
addyosmani
51
8.4k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
107
19k
Automating Front-end Workflow
addyosmani
1370
200k
Being A Developer After 40
akosma
90
590k
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
ご静聴ありがとうございました🙌