見出し画像

【NFT実装】7つの罠がある!ERC-1155とERC-721の違いによる実装の注意点

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

最近よく耳にするNFTですが、さまざまな規格があるのはご存知かと思います。
王道なERC-721、OpenSeaで採用されているERC-1155、レンタルができるERC4907など種類がたくさんあります。
この記事では、ERC-1155とERC-721の違いを解説しつつも、実際の実装において罠が7つあったのでその罠について書いていきたいと思います。

NFTとは

非代替性トークン(ひだいたいせいトークン、英: non-fungible token、略称: NFT)とは、ブロックチェーン上に記録される一意で代替不可能なデータ単位である[1]。NFTは、画像・動画・音声、およびその他の種類のデジタルファイルなど、容易に複製可能なアイテムを一意なアイテムとして関連づけられる[2]。代替可能性(英: fungibility)がないという点で、NFTはビットコインなどの暗号通貨とは異なる。(引用: Wikipedia NFT)

ERC-721の特徴

世界初のNFT標準規格。「CryptoPunks」や「Bored Ape Yacht Club」「CryptoKitties」など多くの著名なNFTが採用している規格となる。

ERC721では、ひとつひとつのトークンに「トークンID」を割り振ることで、容易にトークン同士の区別が付けられるようになっている。また、NFTのタイプ情報(たとえばCryptoPunksでは「男性」「宇宙人」「女性」「猿」「ゾンビ」といった区分がある)や名前、画像のURLなどのメタデータをNFTに付与することができる。メタデータは外部サーバーに保存されるケースが多く、保存先からデータを呼び出す方法などが定義されている。(引用: Metaverse Style)

ERC-1155の特徴

ERC1155は、2019年6月に採択された比較的新しい標準規格である。村上隆氏の「Murakami.Flowers」やadidasの「Into The Metaverse」といったNFTコレクションで採用されている。

ERC1155は、ゲーム・分散型アプリのプラットフォームを展開するenjin社のCTO、Witek Radomski氏により提案された。通常の暗号資産とNFTのハイブリッドのような規格で、ゲームアイテムの取引などを想定している。(引用: Metaverse Style)

ERC-1155とERC-721の違い

ERC-1155とERC-721の違いの1つとして、ERC1155は1回のトランザクションで複数個のNFTを操作することができます、例えば

  • batchTransfer(複数個を一気に移動)

  • mintBatch(複数個を一気に発行)

というbatchで一気に操作できる機能が備わっています。(他にもあります)
今までのERC-721では複数個のNFTを発行しようとした場合、毎回Transactionが走ってしまい、ガス代がかかってしまいますが、ERC-1155ではこれらのガス代や手間を節約できるメリットがあります。

ERC-1155のbatchの罠

ERC-1155のBatch機能は実際便利でいろいろなところで使われていますが、実装上ではある点においては罠になる場合があります。

  • NFT所有者を把握したい場合(だれがこのNFTを持っているのか)

この場合について考えていきましょう

ERC-721でNFT所有者を把握したい場合の実装

ERC-721でNFT所有者を把握したい場合はとても簡単です

  • ownerOf関数を呼ぶだけ

ownerOf(uint256 tokenId) → address owner

戻り値として、NFT所有者のWalletAddressが返ってきます
とても簡単ですね。

ERC-1155でNFT所有者を把握したい場合の実装

ERC-1155でNFT所有者を把握したい場合、とても罠があります!!!!!!!!!!!!!!!!!!!

罠1: ERC-1155にはownerOf関数がない

ERC-1155のドキュメントを見るとownerOf関数がありません。

罠2: 罠1の解決案としてownerOf関数の代わりにbalanceOf関数 と balanceOfBatch関数がある

  • balanceOf関数は誰が何個持っているかがわかる関数になります

  • しかしbalanceOf関数は引数にウォレットアドレスを取るため、目的であるNFT所有者を把握したい場合には使用できません

  • 対策としては、BatchTransferとSingleTransferという関数を呼び出し、Transaction履歴を追跡すると所有者情報を取得できます

罠3: 罠2の解決策をしても、SingleとBatchの2つを気にしないといけない

  • 目的のNFTがBatchでTransferされたのかSingleでTransferされたのかを意識する必要があります

罠4: 罠3の解決策をしてもメモリに乗り切れない

  • OpenSeaなどの巨大NFTコントラクト(1コントラクトにたくさんのTransaction履歴がある)場合、大体のサーバーではメモリに乗り切れずクラッシュが発生します

  • 解決策としては、サーバーで処理できる数でページネーションを行い、分けて処理を記述しましょう

罠5: 罠4が解決してもマルチチェーン対応でつまる

  • 別のネットワークのNFTの情報も欲しくなってバッチが終わらなくなってきます

    • さあだいぶ辛くなってきました

罠6: 罠5を解決してもデータとCPUとメモリを圧迫が激しい

  • めちゃめちゃ圧迫されます

罠7: クラウドサービスやコスト問題

もうお気づきでしょうがここまで対応してくるといろいろなコストがかかり始めます

  • 複数ネットワークを対応し出すとノードを立てる必要がある

  • 頻繁にくる対応必須のノードのアップデート

  • ノードを立てるには何百GBものストレージが必要

  • メンテナンスコストがかかる

  • サーバーコストがかかる

もう自前この実装を持つのがバカらしくなる!!

  • ぴえん

そんな時の救世主!!

TIUS APIの特徴

  • NFTの所有者情報をAPIで提供しています

    • 7つの罠が全て解決します

  • 規格

    • ERC-721, ERC-1155

  • Chain

    • Ethereum

    • Polygon

    • ASTER(beta)

    • SHIDEN(beta)

実装も簡単

import {createClient} from "@urql/core";
import fetch from 'cross-fetch';

const client = createClient({
    url: GRAPHQL_ENDPOINT,
    fetch,
    requestPolicy: 'network-only',
    fetchOptions: () => {
        return { headers: { 'X-API-KEY': GRAPHQL_API_KEY } };
    },
});

const getOwner = async () => {
    const results = await client.query<
    GetOwnerQuery,
    GetOwnerQueryVariables
    >(GetOwnerDocument,
       {
        address: "0xC52d9642260830055c986a97794B7b27393Edf5e"
      }).toPromise();

    results?.data?.erc721ByContractAddress?.tokens
    .forEach(token => {
        console.log(token.tokenId);
        console.log(token.ownerAddress)
    });
}

これだけで解決します!!

まとめ

  • 自前でNFT所有者を把握したい(だれがこのNFTを持っているのか)とき罠が7つある

    • 特にERC-721とERC-1155を使う時の差分に注意

  • TIUS APIは無料で使えます

no plan株式会社について

この記事が気に入ったらサポートをしてみませんか?