投稿者
Photo of author
|投稿日:

ジェネレーティブアートNFTの作り方!PythonとSolidityで一括大量作成  

ジェネレーティブアートNFTの作り方!PythonとSolidityで一括大量作成  

ブロックチェーンSAFEMOONトークンのフォークとNFTは参考サイトから実施したのみです。なので独自のジェネレーティブアートコレクションの作成と展開をしてみようと思います。検索で出てくるチュートリアルはERC721の部分でOpenSeaに上げるところがなくなっています、ただ単に私のように、ほとんどのチュートリアルは技術的に浅い(jpegをアップロードする)か、これらの大規模なコレクションが開発および展開される正確なプロセスを明確にできないことがあります。とりあえず参考の一部としての記事です。

始める前の準備

メタマスク

おなじみかおなじみでないかはわかりませんがよく付き合うメタマスクの説明ページ動画です。準備してください。

言葉の定義 オンチェーン(チェーン上)

ブロックチェーンで必要な認識ですね、ブロックチェーンなのでチェーン上に入らないとブロックチェーンとしてなしていない、NFTはその前にオフチェーンで準備されたものをコントラクトをデプロイしてオンチェーンにしているのですね。ここまでは私もわかります、笑。さて後ほど答えがでるのでしょうか。

ジェレーティブアート 

まずはここが重要ですね、開発者はどのようにして何千ものユニークな芸術作品をプログラムで生成するのでしょうか。まず第一に、ほとんどのNFTはチェーン上でまったく生成されないことを理解することが重要です。 Solidityは、スマートコントラクトの「ルールを設定」する手段を提供しますが、キャラクターアートを生成し、コントラクトを操作するには、Pythonなどのスクリプトツールが必要です。

アート自体に関しては、PNGとして互換性のある特性のレイヤーを作成する必要があります。ただし、設計に注意を払う限り、これらのレイヤーを生成して、チェーン上に展開できる最終的なランダムな文字にマージできます。

まず最初に、自分のデザインの基礎が必要でした。私は決してアーティストではないので、オリジナルのCryptoPunksに似た、非常にシンプルなピクセル化されたキャラクターアートを作成することを選択しました。 PNGファイルを生成するために、ここにある無料のツールであるPixlrを使用しました。目的の効果を実現するために、画像サイズを25×25に設定しました。

ほとんどのNFTコレクションは、通常は色を含む基本的なボディまたは形状を共有していることに気付いたと思います。その後、付属物からアクセサリー(武器、衣類、宝石、武器)に至るまでさまざまな特徴が続きます。私の場合、体、目、口、髪など、いくつかの必要なレイヤーから始めました。私はこれらにオプションの特性を付けました:顔の毛、宝石、帽子、眼鏡、マスクの順。各レイヤーはフォルダーで表され、各フォルダーにはさまざまな特性がPNGファイルとして含まれています。

NFT メタデータ

メタデータについては前に説明しましたが、これは意外なことかもしれませんが、NFT画像データは、非常にコストがかかるため、通常はチェーンに保存されません。これを解決するために、何らかの形式のストレージを指す各「トークン」/ NFTのURIまたはリンクを提供します。このストレージは、メタデータを.jsonファイルとしてホストします。さらに、このメタデータには、画像への2番目のURIまたは「リンク」が含まれています。
基本的に、JSONファイルは、画像の場所など、NFTについて知っておく必要のあるすべての情報を各マーケットプレイスに通知します。このアプローチはERC721標準に準拠しており、開発者と市場は、所有権の譲渡など、必要な機能について適切に合意することができます。

これらの標準に従って、OpenSeaはメタデータの期待と機能に関する追加の指示を提供します。 Solidity側で必要なものを確実に提供するために、OpenZeppelin ERC 721のようなライブラリをインポートできます。これにより、必要に応じて関数をオーバーロードする機能が追加され、必要なすべての機能を継承できます。これらの関数は、自分で実装したかのようにEtherscanに表示されます。 Solidityファイルには次のものが含まれている必要があります。

import “@openzeppelin/contracts/token/ERC721/ERC721.sol”;

OpenSeaは、「ブースト」や統計などの追加のUI機能を提供することで拡張します。グローバルのメタデータを見つけることができます、こちらがOpenSeaのドキュメントになります。

イメージデータの格納 & IPFS

あなたはおそらく考えているでしょう、これは私たちの分散型NFTが集中化されていることを意味しませんか?プロジェクトがどの程度分散化されるかは、ユースケースに完全に依存します。多くのNFTプロジェクトが一元化されたファイルシステムを指していることがわかります。これは推奨されていませんが、厳密には強制されていません。実際、いくつかの価値ある機能には、より集中化されたアプローチが必要な場合があります。
私の場合、作成直後にメタデータとイメージをプログラムでIPFSにアップロードしました。 IPFS、または惑星間ファイルシステムは、分散型インターネットです。データを保存するための不変の分散型手段を提供します。
この記事の最後にある「IPFS、A Deep Dive」の手順を含め、IPFSの詳細を確認できます。

Solidity スマートコントラクト

スマートコントラクトの詳細は非常に重要です。ほとんどの場合はコントラクトがチェーン上にあるとが不変でなければならず、最初から正しく契約(コントラクトをデプロイ)したいということです。
このプロジェクトは、NFT生成で使用されるツールと手法を探求するためのPOCであったため、OpenSea市場でNFTを入手するだけでなく、より詳細な概念を探求しなければならない。

遅延公開

参考の記事Generative Art NFTs With Python and Solidityには遅延公開でひきつけるという内容がしるされております。詳細なやり方はわからないですがこうです。

私が調査した最初のトピックは、遅延公開を実装する方法でした。これは、Adam BombSquadなどの他のプロジェクトで見たことがあるかもしれません。この場合、「ミント」は単に「保留中」の画像と空白のメタデータを残します。これは、希少性以外の要因での取引を促進するための優れた方法のようです。

ここでの問題は分散化にあります。ただし、スマートコントラクトからコマンドを受信して​​NFTを生成し、それをIPFSにアップロードし、新しいトークンを「ミント」することができる集中型アプリケーションが必要な場合は、展開前にこれをすべて実行する必要があります。

これを解決する方法はいくつかありますが、最も簡単な方法は、setBaseUri関数を介してbaseUri値を更新することです。次に、tokenUri呼び出し関数が返すtokenUri(保留中または最終)を決定するブール値の「reveal」値を使用します。 tokenUri呼び出し関数は、OpenSeaがURIをフェッチするために使用するものです。このメソッドは実行が「安価」ですが、単一のトランザクションですべてのトークンを「明らかに」するため、単一のトークンをターゲットにする機能が制限されます。これは、OpenZeppelinまたは同等のライブラリからこれをインポートした場合、erc721.solのtokenUri()関数をオーバーライドする必要があることも意味します。または、私が行ったように、tokenIdの対象となる各トークンのURIを更新する関数を作成できます。これは、トークンごとに実行する必要があるため「高価」ですが、公開プロセスをさらに制御できます。

私の場合、NFT画像とメタデータの生成を遅らせるのではなく、一般的なメタデータと以下に表示される画像を指すURIを最初に提供することで、公開を遅らせました。この保留中の画像は事前に手動でIPFSにアップロードされており、この単一のmetatdata / imageのペアは、遅延公開したいすべてのトークンに使用されます。

では、最終的なURIをどのように保存するのでしょうか。
コントラクトは通常、マッピングを使用して、あらゆる種類のものをtokenIdまで追跡します。これは、NFTの詳細を保存する方法があることを意味します。作成時に最終的なtokenURIを設定するのではなく、このマッピングを設定すると、後日、マッピングからURIを「設定」または「解決」することができます。
以下のマッピングtokenIdToURIに注意してください。これにより、NFTトークンのURI値が保存されます。
コンストラクターは、事前設定された保留中の画像とメタデータのURIである値loadingURIを想定しています。コンストラクターをトリガーするコントラクトをデプロイするときに、このURIを提供します。

contract DigiHomie is ERC721, Ownable, AccessControl {
    uint256 public MAX_TOKENS = 5000;
    uint256 public tokenCounter;
    uint256 public mappedCounter;
    string public LOADINGURI;
    bytes32 public constant RESOLVER_ROLE = keccak256("RESOLVER_ROLE");
    
    //Mapping to store URI data for delayed reveal
    mapping(uint256 => string) public tokenIdToURI;

    constructor(string memory loadingURI)
        public
        ERC721("DigiHomies", "DH")
        AccessControl()
        Ownable()
    {
        tokenCounter = 0;
        mappedCounter = 0;
        LOADINGURI = loadingURI;
        _setupRole(RESOLVER_ROLE, msg.sender);
    }

    //Creates token and set data & image to 'Pending' for delayed reveal
    function mintPending(string memory tokenURI)
        public
        onlyOwner
        returns (bytes32)
    {
        require((tokenCounter < MAX_TOKENS), "Exceeds maximum token supply.");

        //Map to track proper URI
        tokenIdToURI[tokenCounter] = tokenURI;
        
        _safeMint(msg.sender, tokenCounter);
        
        //Set URI to loading image & metadata (delayed)
        _setTokenURI(tokenCounter, LOADINGURI);
        
        tokenCounter = tokenCounter + 1;
        mappedCounter = mappedCounter + 1;
    }
mintPending関数はURIを受けいれることになりますが、tokenURI(_setTokenURI)を設定するのではなく、tokenIDに関連付けられたものをシンプルにトークンマッピングに格納するだけです。

ユーザMint

また、契約外の所有者であるユーザーが新しいNFTを作成できるようにしたかったのです。メタデータの生成とアップロードをトリガーする一元化されたアプリケーションが必要なかったため、事前にこれを行う方法が必要でした。
setTokenMapping()関数が必要でした。これにより、トークンの作成が完全にスキップされます。反復を追跡するために、2番目のカウンターmappedCounterを作成しました。これで、トークンの総数と、ミント(マップされた)の潜在的なトークンの総数を追跡する方法があります。
ミントの時点で、新しいトークンが作成され、マッピングからURIが設定されます。これは私たちの遅れた公開に似ていますが、実際の鋳造もここで遅れているという違いがあります。
他のミントと同様に、ミントをトリガーするユーザーアドレスは、以前に生成されたが新しくミントされたNFTの所有権を取得します。

Githubからツール利用

GithubよりNFT Collection Generatorを利用してジェネレーティブアートを実施しています。

※本記事にはアフィリエイト広告を含んでいる場合がございます。

コメントする

Item added to cart.
0 items - $0.00