Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
NFTのインデクシングとGraphQLのすゝめ / NFT indexing and GraphQL
serinuntius
July 12, 2022
Technology
0
15
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
6
世界最速でArbitrumで NFTを作って震えたい!!!!/ I want to make NFT with Arbitrum in the fastest way in the world and tremble !!!!
serinuntius
0
530
なぜフラッシュローンという概念が俺達の魂を震えさせるのか / Why does the concept of flash loans make our souls tremble?
serinuntius
0
570
Why does the concept of DeFi make our souls tremble? / なぜDeFiという概念が俺達の魂を震えさせるのか ~DEX(AMM)まで~
serinuntius
0
990
NotionがCMS代わりに!? / Notion replaces CMS!?
serinuntius
0
620
ont hackathon
serinuntius
0
54
Golangでリクエストごとのクエリログが見たい!! kamakura.go #4 / go-query-and-request-logger
serinuntius
1
490
新卒Rubyistが1ヶ月で Perl Mongerになった話
serinuntius
0
290
Other Decks in Technology
See All in Technology
hey BOOK
heyinc
26
290k
サイバー攻撃を想定したクラウドネイティブセキュリティガイドラインとCNAPP及びSecurity Observabilityの未来
syoshie
1
1.1k
Sysdig Secure/Falcoの活用術! ~Kubernetes基盤の脅威モデリングとランタイムセキュリティの強化~
owlinux1000
0
240
EKS AnywhereとIAM Anywhereを組み合わせてみた
regmarmcem
0
310
データをコネコネ!メール配信用データ生成の仕組み
kappezoro
0
120
Power Automate for desktopで 配信環境を改善してみた話
akiika
0
280
LINSTOR — это как Kubernetes, но для блочных устройств
flant
0
1.1k
テクニカルライティングの検定を受けてみた話 / "My Story About Taking the Technical Writing Exam
line_developers
PRO
1
210
質の良い”カイゼン”の為の質の良い「振り返り」
shirayanagiryuji
0
120
森林情報のオープンデータと QGISでの利用
kou_kita
0
220
ここが好きだよAWS管理ポリシー_devio2022/i_am_iam_lover
yukihirochiba
0
3.1k
テスト自動化を最速で軌道に乗せるために
nozomiito
0
140
Featured
See All Featured
The Pragmatic Product Professional
lauravandoore
19
3.1k
Six Lessons from altMBA
skipperchong
14
1.4k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
119
28k
Bootstrapping a Software Product
garrettdimon
296
110k
Practical Orchestrator
shlominoach
178
8.7k
Teambox: Starting and Learning
jrom
123
7.7k
Designing for humans not robots
tammielis
241
24k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
351
21k
Embracing the Ebb and Flow
colly
73
3.4k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
21
1.4k
Designing Experiences People Love
moore
130
22k
Automating Front-end Workflow
addyosmani
1351
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
ご静聴ありがとうございました🙌