👌

ERC1155に準拠した独自コントラクトの作り方

2022/01/16に公開

前書き

  • この記事は特定のNFTや仮想通貨の購買を促進する記事ではありません。

はじめに

ERC1155はERC20、ERC721を特徴を併せ持ったハイブリッドな規格とも言われていて、マルチスタンダードトークンとも呼ばれています。
ERC721に準拠した独自コントラクトの作り方はWebに転がっていますが、ERC1155に準拠した独自コントラクトの作り方は探しても見当たらなかったので今回はその作り方を取り上げます。

https://gaiax-blockchain.com/erc1155

環境

開発

// SushiItems.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/ERC1155/ERC1155.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.2/contracts/utils/Counters.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.4.2/contracts/utils/Strings.sol";

contract SushiItems is ERC1155 {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenCounter;

    // わかりやすく数字を文字列で表している
    uint256 public constant TUNA = 0;
    uint256 public constant SALMON = 1;
    uint256 public constant TOROTAKU = 2;
    uint256 public constant TAMAGO = 3;
    uint256 public constant UNI = 4;

    string baseMetadataURIPrefix;
    string baseMetadataURISuffix;

    // コントラクトデプロイ時に1度だけ呼ばれる
    constructor() ERC1155("") {
        baseMetadataURIPrefix = "YOUR_METADATA_URI";
        baseMetadataURISuffix = "YOUR_METADATA_URI_SUFFIX";

        // TUNA -> 0
	// tokenID 0 を 100個 発行する。 
	// デフォルトの所有者は msg.sender (コントラクトをデプロイした人)
        _mint(msg.sender, TUNA, 100, "");
        _mint(msg.sender, SALMON, 10**9, "");
        _mint(msg.sender, TOROTAKU, 1, "");
        _mint(msg.sender, TAMAGO, 10**9, "");
        _mint(msg.sender, UNI, 10**9, "");
    }

    
    function uri(uint256 _id) public view override returns (string memory) {
        // "https://~~~" + tokenID + ".json" の文字列結合を行っている
	// OpenSeaはここのメタデータを読み取ることで画像等を表示している
        return string(abi.encodePacked(
            baseMetadataURIPrefix,
            Strings.toString(_id),
            baseMetadataURISuffix
        ));
    }

    function mint(uint256 _tokenId, uint256 _amount) public { 
        _mint(msg.sender, _tokenId, _amount, "");
    }

    function mintBatch(uint256[] memory _tokenIds, uint256[] memory _amounts) public { 
        _mintBatch(msg.sender, _tokenIds, _amounts, "");
    }

    function setBaseMetadataURI(string memory _prefix, string memory _suffix) public { 
        baseMetadataURIPrefix = _prefix;
        baseMetadataURISuffix = _suffix;
    }
}

YOUR_METADATA_URIYOUR_METADATA_URI_SUFFIX にはメタデータの保存先であるサーバーのURLを記述してください

今回は以下のようなサンプルURLを用意しました

  • YOUR_METADATA_URI -> https://firebasestorage.googleapis.com/v0/b/solidity-sandbox.appspot.com/o/erc1155example%2Fmetadata%2F
  • YOUR_METADATA_URI_SUFFIX -> .json?alt=media

トークンを発行すると、連番の場合以下のようなURIになります。

  • https://firebasestorage.googleapis.com/v0/b/solidity-sandbox.appspot.com/o/erc1155example%2Fmetadata%2F1.json?alt=media
  • https://firebasestorage.googleapis.com/v0/b/solidity-sandbox.appspot.com/o/erc1155example%2Fmetadata%2F2.json?alt=media
  • https://firebasestorage.googleapis.com/v0/b/solidity-sandbox.appspot.com/o/erc1155example%2Fmetadata%2F3.json?alt=media

動作確認

モノは試しで、できたら早速rinkebyテストネットにデプロイして確認します。
Remixからデプロイを行い、デプロイしたコントラクトのIDをコピーし、Openseaのtestnetを見に行きます。

URLは https://testnets.opensea.io/assets/コントラクトID/0

サンプルは以下

https://testnets.opensea.io/assets/0x1f70bddab0f207575ad1c03fa0e258f45680a4a6/0

tokenID 0の寿司が100個作られているのが確認できました。

追加でmint

追加でNFTをmintしたい場合は mintメソッドもしくは複数個発行したい場合は mintBatchメソッドを呼びましょう。

まとめ

  • Remixを使い、ERC1155に準拠した独自コントラクトをデプロイした
  • デプロイしたコントラクト、mintしたNFTをOpenseaのtestnetで確認した

参考リンク

最後に

Solidityについてワイワイ学ぶコミュニティ「solidity-jp」を作りました!
いまから学んでみたい/学習中だけどの日本語の情報が少ない/古くて時間がかかっているという方、一緒に学びましょう〜!!

https://solidity-jp.dev/

また、TwitterにてSolidityについて技術的な部分を発信しています。良ければフォローお願いします!

https://twitter.com/k0uhashi

Discussion