LoginSignup
5
2

More than 1 year has passed since last update.

「ユーザーがこのNFTを持ってるかどうか判定したい!」って時【ERC721/1155】

Last updated at Posted at 2022-12-09

これはno plan inc.の Advent Calendar 2022の10日目の記事です。

このNFTを買ってくれた人だけ来れる特設サイトを作りたい!って時ありますよね。。
そんな時にどうやって持ってるかどうか判定するかって話です。

結論から言うと、コントラクトのview関数叩くでもある程度作れますが、ちゃんとやるならAPI使った方がいいです。
view関数でやる場合、ERC721ならownerOf、ERC1155ならbalanceOfを使う事になります。
ただ、どっちのメソッドも引数にtokenIdをとります。ここで問題発生です。ユーザーが買ってきてくれたNFTのtokenIdが分かりません。

これの対処法としては、

  • ユーザーに買ってきたNFTのtokenIdを入力してもらう!
  • 全部のtokenIdでownerOf/balanceOfを呼ぶ...
    のどちらかですがどっちも辛いです...

前者はユーザーにとってめんどくさいですし、後者はリクエスト量がとんでもないことになって時間もお金もかかります。。
自前でデプロイしたNFTでない場合、全tokenIdを把握することすら難しいこともあります。
以下、無理矢理ownerOfでやろうとした場合のサンプルです、

全idにownerOfして所持判定する場合のサンプル

import { ethers } from "ethers";

const checkIfHaving = async () => {
  const provider = new ethers.providers.StaticJsonRpcProvider(
    "RPCエンドポイント"
  );

  const contract = new ethers.Contract(
    "所持確認したいNFTのコントラクトアドレス",
    "ABI",
    provider
  );

  //そのNFTの全tokenId
  const tokenIds = [1, 2, 3];

  const owners: { [key: string]: boolean } = {};

  await Promise.all(
    tokenIds.map(async (tokenId) => {
      const owner = await contract.ownerOf(tokenId);
      owners[owner] = true;
    })
  );

  if (owners["ユーザーのウォレットアドレス"] === true) {
    console.log("持ってる!");
  } else {
    console.log("持ってない!");
  }
};

そこで便利なのが~~~NFT APIです!

TIUSなどのNFT APIを使えば、
コントラクトアドレスからowner一覧を取得、ウォレットアドレスから所持しているNFT一覧取得など自由自在にできます。
TIUSは無料で使えます。

TIUSを使ったNFTの所持判定

import { createClient } from "@urql/core";
import fetch from "cross-fetch";
import {
  FindByContractAddressDocument,
  FindByContractAddressQuery,
  FindByContractAddressQueryVariables,
} from "./generated/graphql";

const client = createClient({
  url: "TIUSのエンドポイント",
  fetch,
  requestPolicy: "network-only",
  fetchOptions: () => {
    return { headers: { "X-API-KEY": "TIUSのAPIキー" } };
  },
});

const checkIfHaving = async () => {
      //この一回のリクエストだけで全tokenIdの情報取得!
  const results = await client
    .query<FindByContractAddressQuery, FindByContractAddressQueryVariables>(
      FindByContractAddressDocument,
      { contractAddress: "所持確認したいNFTのコントラクトアドレス" }
    )
    .toPromise();

  const owners: { [key: string]: boolean } = {};

  results.data?.erc721ByContractAddress.tokens.forEach((token) => {
    owners[token.ownerAddress] = true;
  });
  if (owners["ユーザーのウォレットアドレス"] === true) {
    console.log("持ってる!");
  } else {
    console.log("持ってない!");
  }
};

・TIUSを使った場合はこんな風に一回のリクエストだけで特定のNFTの所有全一覧を取得して判定することができます。
・詳しくはこちら

no plan株式会社について

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2