はじめに

初めまして。 CryptoGamesというブロックチェーンゲーム企業でエンジニアをしている cardene(かるでね) です! スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

代表的なゲームはクリプトスペルズというブロックチェーンゲームです。

以下でも情報発信しているので、興味ある記事があればぜひ読んでみてください!

今回はRemixという、ブラウザ上でスマートコントラクトの開発を行うことができるツールで、WalletConnectを使用して開発を行う手順を紹介します。 できる限り噛み砕いて非エンジニアでも実行できるよう解説していきます。

今回の記事は非エンジニアでも読めるようにしています。 そのため、言葉の定義が正確ではないところがあります。 これは正確性よりもわかりやすさを重視しているためです。 この前提を踏まえた上で読んでいただけると幸いです。

Remixにアクセス

まずはRemixのページを開きましょう。

URLの末尾にコンパイラのバージョンなど含まれているので、上記のURLから開いてください。

Remixにアクセスの図

開くと上記のようなページが表示されます。

Remixにアクセスの図

ページの左側にあるサイドメニューに注目してください。 図の赤枠はそれぞれ以下のことができる場所です。

  1. スマートコントラクトを開発をする場所。
  2. コンピューターが読みやすい形式に変換する「コンパイル」を行うタブ。
  3. コントラクトを公開する「デプロイ」を行うタブ。

Solidityファイルの作成

では、次にSolidityのファイルを作成していきましょう。

Solidityファイルの作成の図

上記の「contracts」という部分にカーソルを合わせるとファイルアイコンが出てくるのでクリックします。 そうするとファイルが作成されて、ファイル名を設定できるようになります。

ファイル名を設定でできたら、ファイルをクリックして開きましょう。 ファイルを開くと中身が空になっているので、以下のようにコードを書いていきましょう。

Solidityファイルの作成の図

今回は1からかかず、以下に書かれているコードをコピペしてください。 1行目から最後の行までコピーして、先ほど作成したファイルにペーストしてください。

これでSolidityでかかれた、スマートコントラクトの作成ができました。

スマートコントラクトの解説

コントラクトの作成ができたところで、コントラクトの中身を見ていきましょう。

この章はコントラクトの細かい説明をしているため、手を動かしたい方は次の章に進んでください。

ライセンスとバージョン

solidity
// SPDX-License-Identifier: MIT

この部分ではライセンスについて定義しています。

MITライセンスとは、使用、コピー、修正、マージ、公開、配布を自由に行うことができるライセンスです。

solidity
pragma solidity 0.8.25;

ここではSolidityのバージョンを定義しています。 今回は0.8.25というバージョンを使用しています。

ライブラリのインポート

solidity
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {ERC721Burnable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Base64} from "@openzeppelin/contracts/utils/Base64.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";

様々なライブラリを読み込んでいます。

  • ERC721
    • Openzeppelinが開発をしているERC721コントラクトを読み込んでいます。
    • ERC721形式のNFTを作成するときは、基本的にこのコントラクトを読み込みます。
  • ERC721Burnable
    • ERC721形式のNFTをburnできる拡張機能です。
    • burnとは、NFTを削除して以降使えなくする機能です。
  • Ownable
    • コントラクトの所有権を管理するコントラクトです。
  • Base64
    • データを他の形式に変換するコントラクトです。

すべてのデータを「a~z」「A~Z」「0~9」「+」「/」の64文字と「=」の組み合わせに変換するやり方

  • Strings
    • 特定のデータを文字列に変換するコントラクトです。

コントラクト定義

solidity
contract JBANFT is ERC721, ERC721Burnable, Ownable {

上記でコントラクト名の定義と複数のコントラクトを継承しています。 継承とは、他のコントラクトの機能を引き継いで、継承先のコントラクトで使えるようにすることです。 今回でいえば、JBANFTというコントラクトを作成し、ERC721・ERC721Burnable・Ownableの3つのコントラクトを継承して、JBANFTからも3つのコントラクトの機能を使用できるようにしています。

変数

solidity
uint256 private _nextTokenId;

_nextTokenIdという変数を定義しています。 変数とは値が入る「箱」のようなものです。 今回は_nextTokenIdという名前の「箱」を用意して、ここに任意の値を格納できるようにしています。 uint256というのはデータの種類を表していて型と呼ばれます。 uint256は00から2256−12^256 - 1までの値を定義できる型です。 値が入っていないように見えるのは定義しているだけだからです。 ただ、Solidityの場合は0という値が入っています。

constructor

solidity
constructor(address initialOwner)
    ERC721("JBANFT", "JBAN")
    Ownable(initialOwner)
{}

constructorと呼ばれる、コントラクトをデプロイ(公開)した時に一度だけ実行される関数(一連の処理を一まとめにしたもの)を定義しています。 initialOwnerというアドレスを引数(関数実行時に渡される値)で受け取り、Ownableコントラクトの機能を実行してコントラクトの所有者をinitialOwnerに設定しています。 initialOwnerには、0xabc123...というようなアドレスが渡されます。 ERC721("JBANFT", "JBAN")という部分では、継承しているERC721コントラクトの機能を使用して、NFTの名前とシンボル名を設定しています。

mint関数

solidity
function safeMint(address to) public {
    uint256 tokenId = _nextTokenId++;
    _safeMint(to, tokenId);
}

この関数では、NFTをmint(新規発行)する処理を定義しています。 関数名はsafeMintで、toというアドレスを引数で受け取っています。 publicというのは関数のアクセス範囲を定義しています。

アクセス範囲 説明
external コントラクトの外部からのみ実行可能。
public コントラクトの外部・内部から実行可能。
internal コントラクトの内部からのみ実行可能。

上記3つのパターンがあり、データを更新する関数ではいずれかのパターンで定義する必要があります。 externalの場合は、コントラクト内に定義されている他の関数から呼び出されることができないですが、フロントエンドアプリケーションなど外部から実行することはできます。 publicの場合は、コントラクト内に定義されている他の関数から呼び出すことができ、フロントエンドアプリケーションなど外部からも実行できます。 internalの場合は、コントラクト内に定義されている他の関数からのみ呼び出すことができ、フロントエンドアプリケーションなど外部から実行することはできません。

では次に処理の内容を見ていきましょう。 tokenIdという変数を定義して、_nextTokenId++という値を格納しています。 _nextTokenId++というのは、_nextTokenIdに格納されている値に1を足す処理(インクリメント)をしています。 _nextTokenIdが仮に2だった場合、tokenIdには3が格納されます。 そしてこのtokenIdこそ、NFTのユニーク性を示す要素の1つである値です。 NFTがmintされるたびに値が1ずつ増えるため、同じtokenIdを持つNFTは存在しません。

次に_safeMintという関数を実行して、引数で受け取っているtoというアドレスと先ほど定義したtokenIdという値を渡しています。 この_safeMintという関数は、継承しているERC721コントラクトに定義されています。

_safeMint関数

ではせっかくなので、_safeMintの中身を見ていきましょう。

_safeMint関数の図

上記の赤枠の部分を「commandキー」を押しながらクリックしてください。

_safeMint関数の図

そうすると、上記のようにERC721というコントラクトが開きます。 これが継承しているERC721のコントラクトです。

304行目あたりに先ほど呼び出した_safeMintという関数が定義されています。

solidity
function _safeMint(address to, uint256 tokenId) internal {
    _safeMint(to, tokenId, "");
}

さらに別の関数を呼んでいますね。 Solidityでは、同じ関数名でも渡される引数が異なると別の関数扱いになります。 関数内で呼んでいる_safeMintは引数が3つで、先ほど実行した_safeMintは引数が2つなので別の関数扱いになります。

solidity
function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {
    _mint(to, tokenId);
    _checkOnERC721Received(address(0), to, tokenId, data);
}

上記が先ほど実行していた、引数が3つの方の_safeMint関数です。 _mintという関数を呼んでいるのが確認できます。

_checkOnERC721Received(address(0), to, tokenId, data);の説明は省きます。

solidity
function _mint(address to, uint256 tokenId) internal {
    if (to == address(0)) {
        revert ERC721InvalidReceiver(address(0));
    }
    address previousOwner = _update(to, tokenId, address(0));
    if (previousOwner != address(0)) {
        revert ERC721InvalidSender(address(0));
    }
}

上記の関数が先ほど実行されていた_mint関数です。 処理の中身を見ていきましょう。

solidity
if (to == address(0)) {
    revert ERC721InvalidReceiver(address(0));
}

上記では条件分岐を行なっています。 条件分岐とは、条件によって別の処理をするということです。 今回はto == address(0)というのが条件です。 これは、mintしたNFTを渡すアドレスがaddress(0)かどうかを確認しています。 ==は値が等しいかの記号です。 address(0)はゼロアドレスと呼ばれ、誰の所有でもないアドレスです。 よって、このゼロアドレスに送ってしまうと誰も取り出せなくなります。

burnするときはこのaddress(0)に送られます。

もしこのゼロアドレスがtoとして引数で渡された場合は、ERC721InvalidReceiverというエラーを返して処理を中断します。

solidity
address previousOwner = _update(to, tokenId, address(0));

次に_updateという別の関数を実行しています。

solidity
function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {
    address from = _ownerOf(tokenId);

    // Perform (optional) operator check
    if (auth != address(0)) {
        _checkAuthorized(from, auth, tokenId);
    }

    // Execute the update
    if (from != address(0)) {
        // Clear approval. No need to re-authorize or emit the Approval event
        _approve(address(0), tokenId, address(0), false);

        unchecked {
            _balances[from] -= 1;
        }
    }

    if (to != address(0)) {
        unchecked {
            _balances[to] += 1;
        }
    }

    _owners[tokenId] = to;

    emit Transfer(from, to, tokenId);

    return from;
}

ちょっと長いですね...。 まず引数で「to(NFTを受け取るアドレス)」、「tokenId(mintするNFTのトークンID)」、「auth(tokenIdのNFTの操作権限を持つアドレス)」を渡しています。 authには、現在のNFTの保有者からNFTの操作権限を付与されたアドレスが渡されますが、今回は新規発行のためゼロアドレスが格納されています。

solidity
address from = _ownerOf(tokenId);

上記では、_ownerOfという関数を実行して、引数で渡されたtokenIdのNFTの保有者を取得しています。 今回は新規発行のためゼロアドレスが返ってきます。 このようにゼロアドレスは値がないときなどにも使用されます。

solidity
if (auth != address(0)) {
    _checkAuthorized(from, auth, tokenId);
}

ここではauthの値がゼロアドレス以外の場合に、本当に現在のNFTの保有者からNFTの操作権限を付与されているかをチェックしています。

solidity
if (from != address(0)) {
    // Clear approval. No need to re-authorize or emit the Approval event
    _approve(address(0), tokenId, address(0), false);

    unchecked {
        _balances[from] -= 1;
    }
}

上記では、NFTのtrasnfer(アドレスAからアドレスBへNFTを送るなど)の処理が行われます。

solidity
if (to != address(0)) {
    unchecked {
        _balances[to] += 1;
    }
}

今回は新規発行(mint)なので、上記がメインの処理になります。 引数で渡されたtoには、NFTを受け取るアドレスが渡されているため、address(0)とは異なります。 !=は値が同じではないことを示す記号です。 その後、_balances[to] += 1;でtoが保有しているNFTの数の合計数を1足しています。 +=は左側の値に右側の値を足す処理をします。

solidity
mapping(address owner => uint256) private _balances;

_balancesというのは、マッピング配列と言われ上記のように定義されていています。 簡単に説明すると、ownerというアドレスごとにuint256の値が管理されています。

  • 0x123abc... -> 2
  • 0x456def... -> 5
  • 0x789hij... -> 1

上記のようにアドレスごとに、現在保有しているNFTの数が管理されていて、_balances[to](toには0x456def...などのアドレスが格納されています)というようにすることで5などのデータが取得できます。

今回はNFTを新規発行(mint)しているため、保有しているNFTの数を1増やしています。

solidity
_owners[tokenId] = to;

上記では特定のtokenIdに紐づくNFTの保有アドレスを取得しています。

solidity
mapping(uint256 tokenId => address) private _owners;

先ほどの_balances同様、上記のようにマッピング配列でデータが管理されています。

  • 1 -> 0x123abc...
  • 2 -> 0x456def...
  • 3 -> 0x789hij...
  • ...

上記のようにtokenIdに紐づくNFTの現在の保有者を管理しています。

今回はNFTを新規発行(mint)しているため、引数で渡されているtokenIdの保有者をtoのアドレスに設定しています。

solidity
emit Transfer(from, to, tokenId);

最後にTransferというイベントを発行して、フロントエンドアプリケーションなどにmint処理が成功したことを通知しています。

だいぶ長かったですが、これがmint処理の全貌です。

tokenURI

tokenURIという関数は、NFTのメタデータを返す関数です。

メタデータとは、NFTのより詳細な情報が定義されたデータです。 各NFTの名前や説明、画像データ、動画データ、様々なパラメータ(属性など)が定義されています。

tokenURIの図

tokenURIの図

Openseaでいう上記データを管理しているのがメタデータです。

solidity
function tokenURI(uint256 tokenId)
        public
        view
        override
        returns (string memory)
    {

引数でtokenIdという値を受け取り、他に色々な値が設定されているのが確認できます。 publicはmint関数でも説明したように、コントラクトの内外からアクセスできるということです。 viewは読み取り専用関数(データの更新をせずに、データを取得するだけの関数)を示しています。 overrideというのは、コントラクトを継承しているときに、継承元のコントラクト(今回の場合はERC721)に定義されている同じ名前の関数(今回の場合はtokenURI)を上書きすることを示しています。 上書きをすることで関数の処理を自分の好きなように書き換えられます。

returns (string memory)の部分では、この関数が返すデータの型を定義しています。 今回は文字列を返すため、stringという値が型として設定されています。 memoryというのは、関数実行時に一時的にデータを保存することを指します。 通常であればブロックチェーン上にデータを書き込みますが、memoryを使用すると一時的な保存場所にデータを保存するためガス代もかかりません。

solidity
require(
    tokenId <= _nextTokenId,
    "ERC721Metadata: URI query for nonexistent token"
);

ここでは、引数で渡されたtokenIdが既にmintされているものかチェックをしています。 もしまだmintされていないようであればエラーを返して処理を中断します。

solidity
// string memory uri = "https://ipfs.io/ipfs/QmXbBSeMWZd3wSxAKMhMSs5m5ZzJJDUHdSimnUmEx8BuEp?filename=JBAN.png";
        string memory uri = "https://arweave.net/pP9Rw4hx-Ki8m1R1A5EotbpZW2MAJlenmXbAtTa93Gc"; // ここに好きな画像を入れることも可能

ここではNFTの画像のURLを設定しています。 通常であればNFTの画像はtokenIdごとに異なりますが、今回は全部同じにしています。

solidity
return
            string(
                abi.encodePacked(
                    "data:application/json;base64,",
                    Base64.encode(
                        bytes(
                            abi.encodePacked(
                                '{"name": "JBANFT #',
                                Strings.toString(tokenId),
                                '", "description": "JBA NFT", "image": "',
                                uri,
                                '"}'
                            )
                        )
                    )
                )
            );

最後にメタデータを組み立てています。

json
{
	"name": "JBANFT #0",
	"description": "JBANFT NFT",
	"image": "https://arweave.net/pP9Rw4hx-Ki8m1R1A5EotbpZW2MAJlenmXbAtTa93Gc"
}

詳細は省きますが、上記のようなデータになるように組み立てて、最終的な出力はbase64形式で変換した以下の値になります。

bash
data:application/json;base64,eyJuYW1lIjogIkpCQU5GVCAjMCIsICJkZXNjcmlwdGlvbiI6ICJKQkEgTkZUIiwgImltYWdlIjogImh0dHBzOi8vYXJ3ZWF2ZS5uZXQvcFA5Unc0aHgtS2k4bTFSMUE1RW90YnBaVzJNQUpsZW5tWGJBdFRhOTNHYyJ9

メタデータがなぜbase64形式で変換されるのがデフォルトなのかの理由は定かではないですが、以下のメリットがあるようです。

  • base64形式で変換した値をコントラクトに保存するときに効率よく保存される。
  • ほとんどのデータをbase64形式で変換できる。
  • 変換したデータだけをEtherum上でやり取りすれば良いため、無駄な処理をしなくて良い。

これでコントラクト内に定義されている関数を一通り解説できました。 次にコントラクトをコンパイルしていきましょう。

コントラクトのコンパイル

次にコントラクトをコンパイルしていきます。 Solidityで書かれたコントラクトは人間が読みやすいように作られていますが、コンピューターからは読みにくい状態です。 コンパイルをすることで、コンピューターが読みやすいデータに変換することができます。

では早速そのコンパイルをしてみましょう。

コントラクトのコンパイルの図

サイドメニューの真ん中のアイコンをクリックして、「Compile Nft.sol」というボタンをクリックします。 サイドメニューのアイコンの右下がくるくるして、サイドチェックマークになればコンパイル成功です。 これだけの単純な処理でコンパイルができます。

コントラクトのコンパイルの図

コントラクトのデプロイ

では次にコントラクトのデプロイをしていきましょう。 デプロイとは、コントラクトを公開して他の人が実行したりできるようにすることです。 また、この章ではEthereumのメインネットやテストネットではなく、Remixが提供している環境にデプロイします。 そのため、他の人が触ったりはできませんが動作の確認などはできるため、作成したコントラクトの挙動を確認していきましょう。

コントラクトのデプロイの図

  1. サイドメニューの下から2つ目のアイコンをクリック。
  2. アドレス横にあるコピーボタンをクリック。
    • ここにあるアドレスは仮のアドレスになります。
  3. 上記でコピーしたアドレスを貼り付けてください。
  4. 「Deploy」ボタンをクリックするとコントラクトがデプロイされます。

上記の手順に沿ってデプロイしていきましょう。

コントラクトのデプロイの図

デプロイが成功すると、上記のようにデプロイしたコントラクトの関数などが見れるようになります。

コントラクトのデプロイの図

一番上にコントラクトアドレスがあり、オレンジ色のボタンがデータを更新する関数、青色のボタンがデータを取得する関数です。

関数実行

ではデプロイしたコントラクトの関数を実行してみましょう!

前提

今回実行に使用するアドレスは、以下の部分でコピーしたものを使います。

前提の図

NFT情報

まずはNFTの情報を取得してみましょう。

NFT情報の図

上記の3つの関数を実行してそれぞれ正しい情報が表示されているか確認してください。

  • name
    • NFTコントラクトの名前。
    • JBANFT
  • owner
    • デプロイボタンを押すときに設定したアドレス。
  • symbol
    • NFTのシンボル名。
    • JBAN

safeMint

次にNFTをmintしていきましょう。

safeMintの図

上記の右の赤枠にコピーしたアドレスを貼り付けて、左の「safeMint」というボタンをクリックしてください。

safeMintの図

実行後、上記の画像のように右下のコンソールと呼ばれる部分に出力がされていれば実行成功です。

balanceOf

では、次にbalanceOf関数を実行して、特定のアドレスが保有しているNFTの数を確認しましょう。

balanceOfの図

上記の右側に先ほどNFTを取得したアドレスを入力し、「balanceOf」というボタンをクリックしてください。 「1」と出力されれば成功です。 再度safeMint関数を実行して、「balanceOf」というボタンをもう一度クリックしてみてください。 balanceOfはNFTの保有数を取得する関数であるため、「2」と出力されれば成功です。

ownerOf

では、次にownerOfを実行して、特定のtokenIdに紐づくNFTの保有アドレスを確認しましょう。

ownerOfの図

tokenIdを入力する部分に入れます。 まずは0を入れて「ownerOf」をクリックしてください。 先ほどsafeMintを実行してNFTを受け取ったアドレスが出力されていれば正しいです。 次に1を入れてみてください。 こちらも先ほど同様のアドレスが出力されるはずです。

2以降を入力して実行すると以下のようにエラーがコンソールに出力されます。

ownerOfの図

これは存在しないtokenIdにアクセスしたためです。

tokenURI

最後に、tokenURI関数を実行して、メタデータを取得しましょう。

tokenURIの図

0と入力して、上記のようにやたら長いランダムな文字が出力されていれば成功です。 これはbase64という形式に変換されたデータなので、元の形式に戻す必要があります。

上記にアクセスして、「data:application/json;base64,」以降のデータをコピーしてください。

tokenURIの図

上記のように入力して、「変換」をクリックしてください。 そうすると以下のように出力されます。

json
{
	"name": "JBANFT #0",
	"description": "JBANFT NFT",
	"image": "https://arweave.net/pP9Rw4hx-Ki8m1R1A5EotbpZW2MAJlenmXbAtTa93Gc"
}
  • name
    • JBANFT #0というNFTの名前が出力されます。
  • description
    • JBANFT NFTというNFTの説明が出力されます。
  • image
    • NFTの画像が出力されます。

imageの以下のURLにアクセスしてみてください。

tokenURIの図

上記のように画像が表示されるはずです。

これで一通りの実行は完了です。

WalletConnectでテストネットにデプロイ

では次のWalletConnectを使用してテストネットにコントラクトをデプロイしてみましょう。

WalletConnectとは、PCやスマートフォンのウォレットアプリケーションに接続することができるサービスです。 WalletConnectを使用することで、スマホしか使用できないユーザーでも簡単にDappsと接続することができるため非常に便利です。

前提

デプロイしたコントラクトの削除

まずは、先ほどデプロイしたコントラクトを削除しましょう。

デプロイしたコントラクトの削除の図

上記のようにゴミ箱アイコンをクリックすることで、デプロイしたコントラクトを削除できます。

テストネットトークンの取得

0.5 Sepolia ETHくらいあると十分です。

今回はSepoliaテストネットを使用するため、Sepoliaテストネットトークンの取得が必要になります。

Sepoliaテストネットトークンを保有していない方は以下のサイトから取得してください。

テストネットトークンの取得の図

「Connect Wallet」からウォレットを接続し、Githubアカウントを保有している方はGithubアカウントを連携してください。

テストネットトークンの取得の図

上記の「Ethereum Sepolia」がSepoliaテストネットトークンなので、「Claim your test ETH」に取得したいアドレスを入力し、「Ethereum Sepolia」右にあるボタンをクリックしてください。 しばらくするとウォレットにSepoliaテストネットトークンが入ってきます。

もし、Githubアカウントを持っていない場合は以下のサイトから0.05 ETHを取得することができます。

WalletConnectでの接続

では、WalletConnectを使用してウォレットと接続していきましょう。

WalletConnectでの接続の図

上記のように「ENVIRONMENT」の部分をクリックして「WalletConnect」を選択してください。

WalletConnectでの接続の図

そうすると上記のように「Wallet Connect」というタブが開くので、「Connect Wallet」というボタンをクリックしてください。

Wallet ConnectとConnect Walletがこんがらがってくると思いますが、頑張ってついてきてください。

WalletConnectでの接続の図

ここで2つのパターンがあります。

今回はスマホの方で進めます。 PCでもやっていることは変わらないので同じように進めてください。

PC

PCの場合は青枠の方の「Metamask」と「Browser Wallet」のどちらかを選択してください。

PCの図

そうすると上記のように接続したいウォレットを選択して、ページ下部までスクロールして「Next」をクリックしてください。

PCの図

その後、「Connect」をクリックしてください。

PCの図

remixのページに戻るので、上記の赤枠部分に接続したアドレスが表示されていれば成功です。

スマホ

スマホの場合は赤枠の「WalletConnect」をクリックしてください。 今回はMetamaskアプリを使用していきます。

スマホの図

スマホのカメラアプリで上記のように表示されたQRコードを読み込んでください。 Metamaskアプリに誘導されるので移動してください。

スマホの図

上記のように表示されるので、右下の「接続」をクリックしてください。

スマホの図

接続が完了すると、上記のように赤枠部分に接続したアドレスが表示されます。

スマホの図

もし接続がうまくいかない場合は、上記のようにページ上部にあるネットワークの中から「Sepolia Test Network」を選択してください。 それでもうまくいかない場合はカメラアプリやMetamaskアプリの再起動やremixページのリロードなどをしてみてください。

ウォレットの資産確認

今回はSepoliaテストネットを使用します。 そのため、先ほど接続したウォレットにSepliaテストネットトークンがない場合は、トークンを接続したウォレットに送付してください。

ウォレットの資産確認の図

送付した後ページをリロードすると上記の赤枠に、ウォレット内のSepoliaテストネットトークンの保有量が表示されます。

ウォレットの資産確認の図

コントラクトのデプロイ

では、前章で試した手順で今後はSepoliaテストネットにコントラクトをデプロイしてみましょう。

コントラクトのデプロイの図

上記のように接続したウォレットアドレスをコピーして、「Deploy」ボタンの右に貼り付けてください。 貼り付けるたら「Deploy」というボタンをクリックしてください。

コントラクトのデプロイの図

スマホのMetamaskアプリに上記のように表示されるので、右下の「確定」を押してください。

コントラクトのデプロイの図

上記のように赤枠部分が表示されていればデプロイ成功です。 「view on etherscan」をクリックすると、Sepoliaテストネットにコントラクトをデプロイした時のトランザクションを確認できます。

NFTのMint

では、次にNFTをMintしていきましょう。

NFTのMintの図

上記のように接続したウォレットアドレスを入力して「safeMint」というボタンを押してください。

NFTのMintの図

スマホのMetamaskで上記のように表示されるので、「確定」を押します。

NFTのMintの図

NFTのMintの図

その後上記のようにページ下部にトランザクションの状態が表示され、「トランザクション〇〇が完了しました」と出力されれば成功です。

NFTのMintの図

remixでも上記のようにコンソールに出力されていれば成功を確認できます。

コンソール内の「view on etherscan」をクリックすることで、Mintのトランザクションを確認できます。

NFTのMintの図

わかりづらいのですが、上記にコントラクトアドレスが記載されています。 右側のコピーアイコンをクリックして、コントラクトアドレスをコピーしてください。

コピーできたら上記のリンクを開いてください。 これはOpenseaといって、NFTのマーケットプレイスです。 NFTの売買ができる場所と覚えてもらえれば問題ないです。 今回はTestnetにコントラクトをデプロイしているため、Testnet用のOpenseaサイトを開いています。

NFTのMintの図

上記の赤枠部分に、先ほどコピーしたコントラクトアドレスを貼り付けください。 そうすると「コレクション」という部分に、先ほどデプロイしたコントラクトが「JBANFT」と表示されているのでクリックします。

NFTのMintの図

上記のような画面が開き、「JBANFT #0」という名前のNFTが表示されているのでクリックします。

NFTのMintの図

そうすると上記のように表示されます。 これが先ほどMintしたNFTです。

NFTのチェック

では最後にbalanceOf、ownerOf、tokenURIの関数を実行してデータをチェックしましょう。

NFTのチェックの図

上記のように、balanceOfにはウォレットのアドレス、ownerOfとtokenURIには0という値を入れて実行してください。

  • balanceOf
    • 1
  • ownerOf
    • ウォレットのアドレス。
  • tokenURI
    • data:application/json;base64,eyJuYW1lIjogIkpCQU5GVCAjMCIsICJkZXNjcmlwdGlvbiI6ICJKQkEgTkZUIiwgImltYWdlIjogImh0dHBzOi8vaXBmcy5pby9pcGZzL1FtWGJCU2VNV1pkM3dTeEFLTWhNU3M1bTVaekpKRFVIZFNpbW5VbUV4OEJ1RXA/ZmlsZW5hbWU9SkJBTi5wbmcifQ==

上記のように出力されていれば成功です!

tokenURIの中身の確認方法は、以下のtokenURIの章を確認してください。

最後に

今回はRemixでWallet Connectを使用してNFTコントラクトをデプロイする手順を紹介してきました。 できる限り噛み砕いて非エンジニアでもデプロイできるように解説してきましたがいかがだったでしょうか?

以下でも情報発信しているので、興味ある記事があればぜひ読んでみてください!