ERC721トークンの実装とRinkebyデプロイ

ERC721トークンの実装とRinkebyデプロイ

どうもこじりょー(@kojiryoinvestor)です。

この記事ではERC721トークンの作成方法を解説していきます。

この記事は最低でもERC20トークンの作成を学習した人に向けて書いています。

初心者の方はまず下記のチュートリアルから、Ethereum開発の環境の構築とトークンの作成を学習してみてください。

【Truffle5.0対応】シンプルなERC20トークンを作成しよう!

このチュートリアルからは主に以下のことを学習することができます。

  • OpenZeppelinを利用したERC721トークンの作成方法
  • Rinkebyテストネットへのデプロイ手順
  • 「OpenSea」で作成したトークンの確認

またこの記事のチュートリアルは以下の開発環境で実装していきます。

  • Truffle@v5.0.0
  • openzeppelin-solidity@v2.1.1
  • ganache(GUI)@v1.2.2
  • solidity@v0.5.0

ERC721とは?

「代替不可能なもの」の所有権をEthereumで扱うための規格(ルール)がERC721です。

「代替不可能なもの」とは、例えば著作権等で保護されるようなコンテンツ(写真や絵に音楽)などが当てはまります。

ERC721を利用することで「代替不可能なもの」の所有権をトークン「Non Fungible Token(NFT)」として扱うことができます。

特に、ある主体が発行した代替不可能なもの(ゲームのアイテムなど)で移管・交換の性質を持つものとの相性が良いです。

ERC721の実装

EIP721

ERC721トークンの実装とは、EIP721の仕様で定められらた関数を実装することです。

EIP721は以下のリンクから確認することができます。

https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md

仕様を確認してみると実装する関数も多く脆弱性なく作るのは大変です。

そこでここでは「OpenZeppelin」で提供されているERC721のコントラクトを再利用することでERC721トークンを実装していきます。

OpenZeppelinのインストール:

$ npm i openzeppelin-solidity

コントラクト作成

それではERC721のコントラクトを実装していきます。

「OpenZeppelin」では、ERC721トークンを用途に合わせて拡張することができるようになっています。

https://github.com/OpenZeppelin/openzeppelin-solidity/tree/master/contracts/token/ERC721

openzeppelinの「ERC721」に関連するコード

ERC721の用途に合わせて必要なコントラクトを継承することで拡張していくことができます。

ここでは特に特別なことはせず、ERC721トークンとして最低限利用できるものを目指します。

それではコントラクトファイルを作成しましょう。

ここでは「Asset.sol」と名前をつけて作成しています。

続いて、ERC721トークンとして最低限必要なロジックを実装した「ERC721Full.sol」を継承します。

「Asset.sol」は以下のようになります:

コントラクト解説

「Asset.sol」はコントラクトがデプロイされる際に、以下のパラメーターをコンストラクタで受け取ります。

  • name: トークンの名前
  • symbol: トークンの単位
  • tokenId: アセットを識別する数字(例えば、クリプトゾンビで生成したゾンビには一体一体に固有の数字が付いている)
  • tokenURI: トークンの詳細情報を示すJSONファイルのパス(詳細後述)

その後「name」と「symbol」を「ERC721Full.sol」のコンストラクタに渡します。

ERC721Full.sol

ERC721Full.sol

「ERC721Full.sol」は受け取った「name」と「symbol」を「ERC721Metadata.sol」に渡します。

ERC721Metadata.sol

ERC721Metadata.solのコンストラクタ

続いて「ERC721.sol」の「_mint関数」を呼び出して、tokenId(アセットを識別する数字)に対してアカウントアドレス(トークンの所有者)を関連づけます。

ERC721.sol

ERC721.solの_mint関数

その後「ERC721Enumerable.sol」の「_addTokenToOwnerEnumeration関数」と「_addTokenToAllTokensEnumeration関数」を呼び出し、アカウントアドレスに対して「tokenId」の配列を関連づけます。

その結果、アカウントアドレスから「tokenId」を直接取得できるようになっています。

ERC721Enumerable.sol

ERC721Enumerable.solの_mint関数

アドレスとアセットの関連付けが完了した後は、「ERC721Metadata.sol」の「_setTokenURI関数」を呼び出し、「tokenId」と「tokenURI」の関連づけを行います。

ERC721Metadata.sol

「ERC721Metadata.sol」の_setTokenURI関数

「tokenURI」はERC721トークンに「名前」「詳細」「画像」といった情報をつけたJSONファイルのことです。

{"name":"kojiryo","description":"JSONTSET","image":"https://ipfs.io/ipfs/QmZZD344VHrsLuiaKMjbmdvRBhW8n5rZhqS62g3DCUde8y"}

「tokenURI」の設定はあくまでオプションですが、JSONを返すAPIサーバーのURLを渡すことでトークンの詳細な情報を伝えることできます。

例えば以下は上記の「tokenURI」を設定したERC721トークンを、アセットの取引所である「OpenSea(テストネット版)」で表示させたデモです。

「tokenURI」を返すAPIサーバーを構築するのが面倒であったため、ここでは分散ファイルストレージ「IPFS」を、画像とJSONを返すAPIサーバーとして利用しています。

https://ipfs.io/ipfs/QmYMYdJqSrTNB3iwXzmYfGdjAymuXvHAJuum9zzT7RV7N1

マイグレーションの作成

コントラクトを作成したらマイグレーションを作成していきます。

ここでは「2_deploy_asset.js」と名前をつけて作成します。

2_deploy_asset.js:

「2_deploy_asset.js」はERC721トークンに必要なパラメーターを定義してコントラクトをデプロイします。

「tokenURI」はIPFSを利用して作成するツールを用意しましたので、よければご利用ください!

https://kojimaro.github.io/tokenURI-creator/

テストの作成

作成したコントラクトの動作を確認するためにテストを作成します。

ここでは「Asset.js」と名前をつけて作成します。

Asset.js :

コントラクトをデプロイした後、トークンの名前とtokenIdに紐づいたアカウントアドレスを取得します。

その後、こちらが指定したトークンの名前と、tokenIdに紐づいたアドレスがトークン作成者のアカウントアドレスと一致しているかを検証しています。

続いてプライベートネットへ接続する設定を「truffle-config.js」に書き込んでおきます。

ここではGanacheの環境に合わせています。

truffle-config.js:

development: {
    host: "127.0.0.1",
    port: 7545,
    network_id: "*",
},

Ganacheを起動したら下記のコマンドを実行します。

$ truffle test

以下のように表示されればコントラクトは正常に動いています。

Rinkebyへのデプロイ

テストネット「Rinkeby」用のEtherを取得する

コントラクトを作成したらテストネットのひとつである「Rinkeby」へデプロイしていきます。

コントラクトのデプロイにはGasがかかるため、デプロイ用にEtherを入手しておく必要があります。

ここでは受け取るウォレットに「MetaMask」を利用していきます。

「Rinkeby」用のEtherは下記のサイトから無料で入手することができます。

Rinkeby Authenticated Faucet

サイトにアクセスしたら「Twitter」「Facebook」のいずれかで投稿します。

ここでは「Twitter」を利用していきます。

投稿の内容にはEtherを受け取るアドレスを記載します。

後々コントラクトのデプロイの際に、一番最初に作成したアカウントアドレスの残高からGasが引き落とされるため、受け取るアドレスはMetaMaskで一番最初に作成したアカウントアドレスにしておいてください。

次に投稿へのリンクをコピーしてフォームに貼り付け、欲しいEtherの量を選択します。

しばらく待つと記載したアドレスにEtherが送られます。

MetaMaskのネットワークをRinkebyに変更して確認してみてください!

INFURAへの登録

テストネットやメインネットへのデプロイするためには、イーサリアムクライアントを同期させる必要があります。

しかしイーサリアムクライアントを利用してブロックチェーンを同期すると、ディスク容量が大量に消費されます。

そこでイーサリアムクライアントを利用しなくてもコントラクトのデプロイができるサービス「INFURA」を使います。

無料で利用できますので、「GET STARTED FOR FREE」をクリックして必要事項を入力して登録をしましょう。

登録が完了したら「CREATE NEW PROJECT」をクリックしてプロジェクトを作成します。

プロジェクトを作成すると「PROJECT ID」が表示されます。

これはデプロイの際に必要となりますのでコピーしておきましょう。

Rinkebyへの接続設定

Rinkebyへデプロイするための設定を「truffle-config.js」に書いていきます。

まずはRinkebyへ接続するために必要な2つのキーを用意しましょう。

まずはプロジェクトディレクトリ直下に「.infurakey」と「.mnemonic」と名前をつけた2つのファイルを作成します。

「.infurakey」の中身は「INFURA」の「PROJECT ID」を貼り付けておきます。

「.mnemonic」の中身は「MetaMask」でアカウントを作成した際に表示された単語の羅列(パスフレーズ)をコピーして貼り付けておきます。

パスフレーズは「MetaMask」を開き「設定」→「パスフレーズを表示」で確認することが可能です。

Git等でソースコードを管理する際には、これらのファイルをGitから取り除いておくことでアクセスキーの漏洩を防ぐことができます。

続いて以下のコマンドを実行して「truffle-hdwallet-provider」をインストールします。

$ npm install truffle-hdwallet-provider

テストネットデプロイに必要なものが揃ったら「truffle-config.js」を以下のように修正します。

truffle-config.js :

まずテストネットへのデプロイに必要な格アクセスキーや「truffle-hdwallet-provider」の読み込みをする処理を追加します。

続いて「INFURA」のノードを利用して「Rinkeby」へデプロイする設定を記述しています。

それでは「Rinkeby」にアクセスできているか、コントラクトのテストを実行して検証してみましょう。

$ truffle test --network rinkeby

少し時間がかかりますが以下のように表示されれば「Rinkeby」への接続に成功しています。

デプロイ

「Rinkeby」への接続の成功が確認できたので、コントラクトをデプロイしていきましょう。

以下のコマンドを実行することで「Rinkeby」へデプロイすることができます。

$ truffle migrate --network rinkeby

特にエラーもなくデプロイに成功したら、トークンを確認するためにコントラクトアドレスをコピーしましょう。

ERC721トークンの確認

MetaMask

「MetaMask」を開き、ネットワークを「Rinkeby」へ変更します。

トークンは一番最初に作成したアドレスに付与されていますので、アカウントはそちらを選択しましょう。

次に左端のメニューアイコンをクリックします。

「トークンを追加」をクリックします。

「カスタムトークン」と表示された場所をクリックします。

「トークンアドレス」にデプロイ時に表示されたコントラクトアドレスを入力します。

最後に「次へ」をクリックすればトークンが確認できます。

OpenSea

ERC721トークンに設定した「metadata」も確認してみましょう。

「Rinkeby」テストネットで公開されている「OpenSea」を利用することで確認することができます。

以下のURLで「コントラクトアドレス」と「tokenId」を指定することで確認できます。

https://rinkeby.opensea.io/assets/コントラクトアドレス/tokenId

例: https://rinkeby.opensea.io/assets/0x993b7099d751e7744f2fde046c073c90dbfb3be9/1

おわりに

以上、ERC721トークン作成のチュートリアルでした。

OpenZeppelinを利用することでERC721トークンにも「mint」や「burn」などを追加することができますので、ぜひ色々試してみてください!

参考サイト

Dapps開発のチュートリアル動画

Dapps開発のチュートリアル動画をYoutubeで公開しています!

よろしかったらチャンネル登録をよろしくお願いします!

ERC721カテゴリの最新記事