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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
serinuntius
July 12, 2022
Technology
0
210
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
660
なぜフラッシュローンという概念が俺達の魂を震えさせるのか / 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
1k
ont hackathon
serinuntius
0
90
Golangでリクエストごとのクエリログが見たい!! kamakura.go #4 / go-query-and-request-logger
serinuntius
1
950
新卒Rubyistが1ヶ月で Perl Mongerになった話
serinuntius
0
550
Other Decks in Technology
See All in Technology
LINEヤフーにおけるAI駆動開発組織のプロデュース施策
lycorptech_jp
PRO
0
380
大規模な組織におけるAI Agent活用の促進と課題
lycorptech_jp
PRO
5
7.6k
「使いにくい」も「運用疲れ」も卒業する UIデザイナーとエンジニアが創る持続可能な内製開発
nrinetcom
PRO
1
770
技術的負債の泥沼から組織を救う3つの転換点
nwiizo
4
700
全自動で回せ!Claude Codeマーケットプレイス運用術
yukyu30
3
160
類似画像検索モデルの開発ノウハウ
lycorptech_jp
PRO
0
300
Snowflake Night #2 LT
taromatsui_cccmkhd
0
310
AWS CDK の目玉新機能「Mixins」とは / cdk-mixins
gotok365
2
320
社内ワークショップで終わらせない 業務改善AIエージェント開発
lycorptech_jp
PRO
1
450
Lookerの最新バージョンv26.2がやばい話
waiwai2111
1
150
バクラクのSREにおけるAgentic AIへの挑戦/Our Journey with Agentic AI
taddy_919
2
960
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.1k
Featured
See All Featured
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
360
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Everyday Curiosity
cassininazir
0
150
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
1
140
Building the Perfect Custom Keyboard
takai
2
700
Agile that works and the tools we love
rasmusluckow
331
21k
Building an army of robots
kneath
306
46k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
130
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
250
Automating Front-end Workflow
addyosmani
1370
200k
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
ご静聴ありがとうございました🙌