4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【僕が作ったスマコン最強ちゅーとりある】自作通貨でNFTを購入できるようにしたいにゃあ🐱

Last updated at Posted at 2022-08-12

記事を書いたきっかけ

にゃあ。猫になりたいです。大学生をやったり渋谷でエンジニアをやったりしてます、lowzzyです。最近は友達とNFTをせかせか作っております。

NFTを作っている人なら一度は思うでしょう
「NFTを自分たちが発行した通貨で買えるようにしたい、、、!」

はい。僕も思いました。調べるとそれっぽいやつはちょこちょこ出てきますが、大体英語だったり、コードが微妙だったりと、もう少しわかりやすい日本語版書けばNFT挑戦するハードル下がるよなあ。。。

と思ったので書いた所存です。

使用する言語とかの説明

いわゆるスマートコントラクトを書きます。solidity。
スマートコントラクトは「契約を締結して自動で処理が走る〜」みたいな説明されることが多いけど、あんまり好きじゃないです。分かりにくいので。誰かが言ってたんですけど、スマートコントラクトは「ちっちゃいプログラム」みたいに思ってくれたら多分大丈夫です。

NFTを生成することを「mint」すると言います。

NFTはERC721とかERC1155とかいろんな規格がありますが、今回はERC1155を採用します。
また、通貨はERC20という規格を採用します。

今回はETHのテストネットであるRinkebyを使います。
rinkebyはテスト環境なのでここでのネイティブ通貨ETHは金銭的価値を持ちません。
https://rinkebyfaucet.com/
faucetというところでETHが貰えるので「rinkeby faucet」みたいに調べてもらってきてください。

NFTはLowzzy, 通貨はLWZという名前で発行します。LWZはとりあえず1000枚発行します。

余談ですが、2021年の終わりにAdidasとコラボしてたBoredApeYachtClub通称BAYCは10億枚発行しているみたいです。

コード

コードはこちら

NFT

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract Lowzzy is ERC1155, Ownable{
    string baseMetadataURIPrefix;
    string baseMetadataURISuffix;

    uint256 constant SampleTokenId = 0;

    constructor() ERC1155("") {

        // メタデータが取得できるURIをここで定義している
        // URI -> baseMetadataURIPrefix + トークンID + baseMetadataURISuffix

        baseMetadataURIPrefix = "https://staging--goldfish-japan.netlify.app/.netlify/functions/tokenURI/";
        baseMetadataURISuffix = "";
    }

  // 使用する通貨と、1個当たりの価格を定義してる
    struct TokenInfo {
        IERC20 paytoken;
        uint256 costvalue;
    }

    // publicにしてることで変数callできる
    TokenInfo[] public AllowedCrypto;
    using Strings for uint256;

  // tokenInfo追加する関数
    function addCurrency(
        IERC20 _paytoken,
        uint256 _costvalue
    ) public onlyOwner {
        AllowedCrypto.push(
            TokenInfo({
                paytoken: _paytoken,
                costvalue: _costvalue
            })
        );
    }

    // uri確かめる関数。
    function uri(uint256 _id) public view override returns (string memory) {
        return string(abi.encodePacked(
            baseMetadataURIPrefix,
            Strings.toString(_id),
            baseMetadataURISuffix
        ));
    }
      // お金払わずにNFTを生成することができる関数です。
     // onlyOwnerとあるように、ownerしか使用できないようにしてます。
   //  いらなかったら消してください
    function ownerMint(uint256 _amount) public onlyOwner() {
        _mint(msg.sender, SampleTokenId, _amount, "");
    }

  // この記事の1番理解して欲しいところ
  // 第1引数 -> _mintAmount : 生成する数
  // 第2引数 -> _pid : 使用する通貨
    function publicMint(uint256 _mintAmount, uint256 _pid) public payable {
        TokenInfo storage tokens = AllowedCrypto[_pid];
        IERC20 paytoken;
        paytoken = tokens.paytoken;
        uint256 cost;
        cost = tokens.costvalue;
        require(!paused); // pausedされてたら(paused == trueだったら)エラー吐かせる
        require(_mintAmount > 0);// 0以上かどうか確かめてる(じゃないならエラー)

        // paytoken(この記事だとLWZ)のコントラクトに生えている関数「allowance」を呼び出し
        // おろす許可があるLWZはどれくらいあるかを取得している
        uint256 allowCost = paytoken.allowance(msg.sender,address(this));

        // 許可されているLWZがNFTをmintするのに必要分足りているかを確認している(足りなかったらエラー吐く)
        require(allowCost >= cost * _mintAmount, "Not enough balance to complete transaction.");

        // ここでLWZをこのスマコンのアドレスにtransferしてもらっている(支払い処理)
        paytoken.transferFrom(msg.sender, address(this), cost * _mintAmount);
        // msg.senderのアドレスに_mintAmount個のSampleTokenId番目のトークンをmint(生成)している
        _mint(msg.sender, SampleTokenId, _mintAmount, "");
    }
  // この関数を使うとトークンのURIが変更できます。
    function setBaseMetadataURI(string memory _prefix, string memory _suffix) public onlyOwner(){
        baseMetadataURIPrefix = _prefix;
        baseMetadataURISuffix = _suffix;
    }
}

通貨

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract LWZ is ERC20 {

    constructor(
        string memory name,
        string memory symbol,
        uint256 totalSupply_
    ) ERC20(name, symbol) {
        _mint(msg.sender, totalSupply_);
    }

}

コードは以上です。

次はRinkebyチェーンへのデプロイについて書きます。

デプロイ

RemixってIDEを使います。

コード書く~デプロイ~関数呼び出し
など、色々できます。これできればNFTコレクション作れる。

2つのファイルのコードコピペする
 2022-08-13 1.47.12.png

左のタブで、上から4番目を押す
 2022-08-13 1.47.55.png

environmentとか色々ぽちぽち
 2022-08-13 1.48.01.png

Deployボタン押すとメタマスクが発火するので確認してお金を払う。
 2022-08-13 1.48.18.png

右上からConfirmed transactionってきたので成功。
 2022-08-13 1.48.37.png

次は通貨をデプロイするために、LWZを選択。
 2022-08-13 1.48.58.png

Deployする時に、1000枚しかLWZ発行しないって言ってたのに、0がめちゃめちゃ多いやん!まちがっているやん!と言われそうですが、これは違います。10^18をつけるのがERC20では一般的です。なので発行総量が1000枚の場合は1000x10^18、つまり1000 000000000000000000をtotal supplyに入れましょう。NameとかSymbolとかはなんでも好きなので良きです。

メタマスクが発火するのでまた同じように確認ボタンを押す。
 2022-08-13 3.45.03.png

 2022-08-13 3.46.29.png

成功。
 2022-08-13 1.50.05.png

そしたら、左の方にデプロイされたコントラクトが2つあるはず。Lowzzyって方がNFTで、LWZが通貨。
タブを開くと、生えている関数が見れたりしますね。

 2022-08-13 3.48.38.png

デプロイが終わったら今度はpublicMint(通貨を使用してmint)をしてみましょう。

コントラクトアドレスをコピーして

 2022-08-13 3.49.38.png

AddCurrencyをします。価格(costValue)を10^18するのをお忘れなく(今回は30x10^18にしてる)。第一引数は通貨のコントラクトアドレス(コピーしたやつ)です。

 2022-08-13 3.50.08.png

Approveします。お金使っていいよ〜って許可出す処理です。今回は面倒なので全部(1000x10^18)を入力しました。

 2022-08-13 3.50.59.png

そしたらついにpublicMintです。
先ほど追加した通貨は配列のindex = 0(pid = 0)だと思うので、第一引数に0を入力。
なんとなく5枚欲しいので第二引数には5を入力。

 2022-08-13 3.51.24.png

わーい、5枚mintできていました。https://testnets.opensea.io/assets/rinkeby/0x55b9e5c2880c9d7bd31efc385ca6f664df009fa5/0

 2022-08-13 3.52.18.png

1000枚あったLWZ、850枚になっているはずだなあ、確認するか〜ってなったので、トークンをメタマスクにimportして、、

 2022-08-13 2.05.25.png
わあ!850枚になっている!

 2022-08-13 2.05.30.png

ってことでmint成功ですにゃ

間違えてたりしたら教えてください〜

それでは!

4
3
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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?