最低価格を絶対に保証するNFTの作り方 (Remix編)
概要
- Remixを用いてNFTをmintできるコントラクトを作成・デプロイする
- コントラクト作成→rinkebyテストネットにデプロイまで行う。
- ブロックチェーン、Solidityの解説は省略
前提
- Solidity v0.8.0系
- Metamask利用
- Remix
- オンラインIDE。環境構築不要で簡単にコントラクトをコンパイル、作成、デプロイ、テスト、デバッグまでできるサービス
https://remix.ethereum.org/
- オンラインIDE。環境構築不要で簡単にコントラクトをコンパイル、作成、デプロイ、テスト、デバッグまでできるサービス
最低価格を絶対に保証する とは?
※仮にmint価格を0.1ETHとする
NFTをmint時(作成)に0.1ETHをプールし、burn時(焼却)にプールからユーザーの手元に0.1ETHを返す仕組みをコントラクトで定義する
コントラクトに定義した処理はデプロイ後二度と変更することができないので、
最低価格を 絶対に 保証できる
実装
コントラクトの作成
Remixを開き、 /contracts
フォルダに Burnable.sol
ファイルを作成する
下記のように実装します。重要な部分はコメントに記述しています。
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.2/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.2/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.2/contracts/utils/Counters.sol";
contract Burnable is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
// mint価格をここで定義
// ここが最低価格になる。 0.01ETHではなく、1ETHでも可。
uint MINT_PRICE = 0.01 ether;
constructor () ERC721 ("Burnable", "BURN") {}
// mint処理
function mintBurnable(string memory tokenURI) public payable returns (uint256) {
// mint時に合わせて 0.01ether を送ってきているか確認
require(msg.value == MINT_PRICE);
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
// 実際のmint処理
_mint(msg.sender, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
// 換金burn処理
function burn(uint256 _tokenId) public {
// そのNFT所有者かどうか確認
require(ownerOf(_tokenId) == msg.sender);
// そのNFTを無に転送する (burn)
_transfer(msg.sender, 0x000000000000000000000000000000000000dEaD, _tokenId);
// mint時に払った0.01etherを返す処理
address payable receiver = payable(msg.sender);
receiver.transfer(MINT_PRICE);
}
}
コンパイルする
左側○印を選択し、下部の○印を押下しコンパイルする
下側にエラーがでなければ次のステップへ
デプロイする
Rinkebyテストネットにデプロイする
デプロイするためにはガス代を支払う必要があり、テストネット用のEthを多少持っておく必要があります。
Rinkebyテストネットにデプロイするためには、下記画面にて以下の手順を踏んでください
- RemixとMetamaskをconnect
- ENVIRONMENTは
Injected Web3
を設定- Metamask側で
Rinkebyネットワーク
に切り替える
- Metamask側で
- CONTRACTは先程コンパイルした
Burnable - contracts/Burnable.sol
を選択 - Deployボタンを押す
デプロイに成功すると、 Deployed Contracts
にデプロイしたコントラクトのアドレスとメソッド郡が表示されます。
試しに、rinkeby.etherscan.io
でコントラクトを覗いてみましょう。
https://rinkeby.etherscan.io/address/コントラクトID
コントラクトIDは下記の画像箇所のコピーボタンからコピーできます
参考例は以下。(今回の記事を元に作ったサンプル)
0xa2e6b0fa...
(私の開発用アドレス)からコントラクトが作られているということがログに出ていることがわかります。
動作確認
動きのおさらい
肝心のmintとburnをやっていきます。その前にコントラクトの全体的な動きをおさらいしておきます
- コントラクトの動き
- NFT mint時に0.01ETHをあわせて送る
- mintした側の残高は0.01ETH+ガス代減っていて、コントラクト側には0.01ETHがプールされる
- burn時にコントラクト側のプールから0.01ETH減り、burnした側に0.01ETHが送金される
mint
今回は呼び出し用のスクリプトやdApps等は作らず、Remixから該当メソッドを呼び出します。
- VALUEに10、単位はFinneyを選択
- 10Finney = 0.01ETH
- mintBurnableのTokenURIに適当なmetadata.jsonのURLを指定する
- 今回はコレとする
- mintBurnableボタンを押下する
成功したら、 rinkeby.etherscan.io
に該当コントラクトのトランザクションと残高を覗きに行ってみましょう。
残高が0.01ETHになっていることがわかります。
mintしたNFTは testnet.opensea.io
でも確認できるので見に行きます。
https://testnets.opensea.io/assets/コントラクトID/トークンID
参考例は以下。
burn
換金したい場合、用意した burn
メソッドを呼ぶことでNFTのburnとmint時に支払ったETHが戻ってきます。
mint時と同じようにこちらもRemixから該当メソッドを呼び出します。
先程の mintBurnable
の1つ上にある burn
ボタンの横に換金したいトークンIDを入力し、ボタンを押します。
成功したら、同じく rinkeby.etherscan.io
で覗きにいきましょう
0.01ETH分の残高がなくなっていることがわかります。これで動作確認ができました。
まとめ
- Remixを使いコントラクトの作成、テストネットへのデプロイを行った
-
rinkeby.etherscan.io
にてデプロイしたコントラクトの動きを確認した -
testnet.opensea.io
にてmintしたNFTを確認した
最後に
今回はrinkebyテストネットへのデプロイ方法を紹介しましたが、Metamaskの接続先ネットワークをMainnetに変更するだけでEthereumメインネットへのデプロイができます。
ただ、Ethereumメインネットの場合最低価格 0.01ETH
ではガス代のほうが高くて全然回収できないじゃん!となってしまうのでmint価格を 1ETH
等にあげるか、 Polygonチェーン
等のガス代が安いネットワークへのデプロイにしたほうが良さそうです。
最低価格を保証するNFTは、単価が安いNFTではメリットは薄いと個人的には思っていますが、フェラーリが半永久的に利用可能なNFT会員権 のような単価が高いものであれば、購入のハードルが下がる意味でも向いてるかもしれないですね
参考リンク集
Burnablesについての情報や、最低価格が保証されているということのメリット等について、丁寧に解説されています。必読!
ドキュメントって、大事だよね・・・。必読!
etc
Solidityについてワイワイ学ぶコミュニティ「solidity-jp」を作りました!
いまから学んでみたい/学習中だけどの日本語の情報が少ない/古くて時間がかかっているという方、一緒に学びましょう〜!!
また、TwitterにてSolidityについて技術的な部分を発信しています。良ければフォローお願いします!
Discussion