フリー・オープンソース・ソフトウェアでNFTを作成する

2021年の夏、Linux Professional Institute(LPI)に珍しい教育の機会が訪れました。2人のインターン、広報の学生であるアレックスと、電気・コンピュータ工学を学ぶ私ロジリンは、学習のためのエクササイズとして、一連のNFTを作成することにしました。この記事では、Alexと私が使用したツールについて、自分で試せる程度に詳しく説明します。
インターンシップを始めるまで、Alexと私はNFTについて、新聞で何気なく読んだ程度の知識しかありませんでした。インターンシップでNFTのプロジェクトを行うことになったとき、私たちは暗号通貨、つまりNFTを通じてライセンスされるグラフィック、そしてNFTの契約について、すぐに理解を深める必要があったのです。この投稿では、1)アートワークを作成し、2)対応する画像のNFTを鋳造(つまり作成)できるスマートコントラクトを記述するために使用した技術について説明します。
LPIでは現在、このNFTを使用したり配布したりする予定はありませんが、着飾ったタックスペンギンの画像は、若いITプロフェッショナルが新しいテクノロジーについて学ぶための、魅力的で楽しい夏のプロジェクトになります。
開発プロセス
NFTやスマートコントラクトを開発するための便利なツールが存在し、技術的なスキルが低い人でも利用することができます。例えば、OpenSeaやRaribleは、NFTの作成とマーケティングを簡単に行うことができます。私たちの場合、技術を習得することが第一の目的だったので、オープンソースのツールを使い、より手作業でプロセスを進めることを選択しました。夏の終わりには、私たちは
Linuxを代表する人気ペンギンTuxのCCライセンス画像をもとにLPIのアートワークを作成しました。
カスタマイズされたSolidityのコントラクトでNFTを作成
公開テストネットワーク(testnet)での契約展開と検証
テスターが財布で管理できる造幣局のNFT
この記事の残りの部分では、完全にオープンソースのツールを使って一連のNFTを作成する方法を説明します。
画像の作成
アートワークには、既存の一般的なNFT(CryptoPunksやCryptoKittiesなど)に共通する方式を採用しました。ベースとなる画像をカスタマイズするために、属性のランダムな組み合わせを生成すること。このプロセスにより、共通のキャラクターやテーマで複数のバリエーションを作成し、一連のNFTを構成しています。
Alexは、GIMPとGraphicsMagickを使用して、基本的なTuxと追加属性の画像を作成しました。画像は、AlexがカスタマイズしたTuxの各エリア(シャツ、パンツ、帽子、くちばし、ヒレなど)ごとに指定のディレクトリ(図1)に整理されました。
図1:部品画像レイアウト(一部)
最終的な画像は、Bashスクリプトで作成しました。まず、複数のTuxのベース画像からランダムに1枚を選択する。そして、各属性ディレクトリから1つの属性をベース画像に重ね、最終的な合成画像を保存した。ランダムに属性を選んでいるので、スクリプトは新しい画像を保存する前に、新しい属性の組み合わせが既存の組み合わせと重複していないかどうかもチェックします。このプロセスを、希望する画像枚数が満たされるまで繰り返します。
The GraphicsMagick gm composite command combined the images. Since the gm command works with one base image and only one overlay image at a time, the script made wrapped calls to the command in a loop (Figure 2) to have the resulting image include multiple attributes.
GraphicsMagickのgm compositeコマンドで画像を合成した。gmコマンドは一度に1つのベース画像と1つのオーバーレイ画像しか扱えないため、スクリプトはループ内でコマンドを繰り返し呼び出し(図2)、結果の画像に複数の属性を含ませるようにしました。
図2:レイヤリング処理
スクリプトで使用した主なコマンドラインツールは以下の通りです。
sort: このコマンドは、あまり知られていない –random-sort または -R オプションと一緒に使用すると、各ディレクトリの属性を無作為な順序で返します。
head: このコマンドは、先に述べた、ランダムに並べられたリストの中から最初の画像を選択するものです。
sed: ストリーミングテキストエディタで、##TOKENNUM##と##TOKENURI##をスクリプトが現在生成している画像の番号とURIに置き換えて、テンプレート(下図)からメタデータファイルを作成するコマンドです。
Each NFT was supplemented by documentation specifying its title, description, and image URI (similar to an address). These details were implemented in our smart contract using a metadata file specified in the ERC-721 JSON standard for NFTs, as seen in the following sample:
各NFTには、タイトル、説明、画像URI(住所のようなもの)を指定した文書が添付されています。これらの詳細は、以下のサンプルに見られるように、NFTのERC-721 JSON標準に指定されたメタデータファイルを使用して、スマートコントラクトに実装されています。
{
    “title”: “MyToken”,
    “type”: “object”,
    “properties”: {
        “name”: {
            “type”: “string”,
            “description”: “MyToken ###TOKENNUM##”
        },
        “description”: {
            “type”: “string”,
            “description”: “MyToken ###TOKENNUM##”
        },
        “image”: {
            “type”: “string”,
            “description”: “##TOKENURI##”
        }
    }
}
例1:sedが変換するためのNFTテンプレートメタデータ・ファイル
私たちは、ERC-721規格で提供されるベースのみを含むメタデータファイルを選択しましたが、あなた自身のものに異なる独自の機能を含めることもできます。
 
NFT契約書の書き方
スマートコントラクトとは、ブロックチェーンネットワーク上に保存され、実行されるソフトウェアプログラムです。このソフトウェアは、ライセンシーがNFTを他の人に譲渡できるようにするなど、取引に追加機能を追加するために使用されます。スマートコントラクトは、ネットワーク上の取引情報の保存の促進、所有者の検証、トークンの譲渡など、考えられるさまざまな機能を提供することができます。
コントラクトの作成に使用した主なツールやリソースは以下の通りです。
OpenZeppellin: Zeppelinのウェブサイトで「安全なスマートコントラクトを構築するためのオープンソースフレームワーク」と説明されているこのプロジェクトは、分散型ブロックチェーンネットワーク上でスマートコントラクトを構築するためのドキュメント、ライブラリ、サポートを提供しています。
Solidity: 私たちのスマートコントラクトを作成するために使用したもので、サンプル作品とOpenZeppelinのコントラクトウィザードの両方で使用されているプログラミング言語です。また、一般的にスマートコントラクトの記述や実装に使用されていることでも知られています。
Truffle: Truffleは、「コントラクトのデプロイ、アプリケーションの開発、テストの実行に使用できるEthereum開発用のパーソナルブロックチェーン」と説明されており、アクティブなブロックチェーンに展開する前にスマートコントラクトをテストできる分離された環境を提供するものである。Truffleを使用して、ローカルシステム上でソフトウェアのコンパイル、デプロイ、およびインタラクションを行うことができます。
Ganache: Truffleエコシステムのサブセットで、ローカル(個人)Truffleブロックチェーンネットワーク上で安全な(つまりセキュアな)スマートコントラクトの開発、テスト、展開を支援する開発者環境およびコマンドラインツールです。Ganacheを使用する開発者は、個人的なテストやEthereumブロックチェーンで使用される暗号通貨である本物のイーサ(ETH)を必要としないという利点も得られます。イーサーの使用を避けることは、次のセクションで説明する理由で便利です。
Ropsten: 公開されているEthereumのテストネットです。Ethereumメインネットに最も似ているため、最終的なテストフェーズで使用しました。Ropstenは唯一のプルーフ・オブ・ワークのテストネットである。開発者は個人的にテスト用の暗号通貨を持っている必要があります。
Etherscan: Ethereum Mainnetやtestnetsに保存されているコントラクト、トークン、アカウント、トランザクション、ブロックを表示することができる検索エンジンです。Etherscanはスマートコントラクトを検索できるため、自分のコントラクトをデプロイした後に、コントラクトが正常にアクティブになったかどうかを確認するために使用することができます。
MetaMask: ブロックチェーンウォレットとは、現実世界のウォレットと同様に、資産にアクセスするための情報をデジタルで保管するものです(資産そのものはブロックチェーンに保管されます)。メタマスクは、イーサリアムのブロックチェーンに対応したウォレットで、ブラウザプラグインとモバイルアプリの形で、ユーザーがアセットの閲覧や送金(メインネット上ではスワップ)を行えるようになっています。
NFTのスマートコントラクトの作成と対話は、OpenZeppellinのスマートコントラクトのドキュメントとコントラクトウィザードを使えば、Solidityの知識があってもなくても、非常に管理しやすくなっています。しかし、Solidityの知識があれば、プログラマーは生成されたコントラクトに独自のカスタマイズを簡単に追加することができます。
例えば、ウィザードで作成されたコントラクトのコードには、トークンを鋳造するための関数、safeMintが含まれています。この関数は一度に1つのトークンしか造幣しません。したがって、10,000個のトークンを鋳造するには、10,000回mint関数を呼び出さなければなりません。私は、一度に複数のミントを処理するために、コントラクトに書かれた以下のコードを追加しました。
function mintMany(uint256 num, address to) public onlyOwner {
    for (uint256 i = 0; i < num; i++){         safeMint(to);     } } 例2:基本的なカスタム契約関数の例 コントラクトウィザードで注意すべき重要な機能の1つは、コントラクトのトークン標準を選択することです。トークンには、コントラクト同士の互換性を保ち、基本的な機能(造幣、所有、譲渡、追跡など)を確実に提供するための規格が策定されています。ERC-721は、非可溶性トークン、つまり互換性がなくそれぞれがユニークなトークンを作成する際の標準インターフェースで、ウィザードでコントラクトを作成する際に選択したものである。 ブロックチェーンネットワーク上の取引には、特定の暗号通貨によるコストがかかります。このコストは一般に「ガス」と呼ばれています。イーサリアムのブロックチェーンでは、イーサがガス料金の支払いに使用される通貨で、単位はgwei、10E-9イーサに相当します。 現在のイーサ(ETH、イーサリアムブロックチェーンで使用されるコイン)の市場価値では、コントラクトを展開するのは比較的高価なものとなっています。そのため、イーサリアムメインネットで行う場合、トランザクションをやり直さなければならないような問題やエラーがないことを確認したいと思うはずです。トランザクションが成功してもしなくても、ガスを支払うことになります。 金銭的なコストを考慮すると、ブロックチェーン・ネットワークの扱い方を学んだばかりであれば、メインネットで練習をしたいとは思わないでしょう。その代わり、実質的な価値のないテスト用エーテルでガス代を支払えるテストネットで行うことになるでしょう。 したがって、テストの順番としては、まず、ローカルで個人的なネットワークであるGanache上でOpenZeppellinが提供するサンプルコントラクトのデプロイと対話の基本を学びました。そして、いくつかの練習をした後、公共のテストネットワークであるRopstenに移動しました。 今回のテストネットはロプステンなので、ネットワーク上で使用する通貨が必要で、今回はロプステンエーテル(rETH)を使用しました。通常のETHとは異なり、rETHはrETH faucetsを使って無料で入手することができる。これらの蛇口は、通常24時間に1回、テストエーテルを転送したいアドレスを入力することができます。この遅延が、Ganache の待ち時間のないネットワークが最初の実験に理想的である理由の一部である。異なる時間間隔で異なる量を滴下する様々な蛇口があります。私たちが使用した蛇口は MyCrypto: 0.01RopstenETHを何度でもリクエストできます。 Dimensions Network Faucet: 24時間ごとに5RETHを要求可能 Ropsten Ethereum Faucet: 24時間ごとに1RETHを要求可能 ガス代をまかなうためのテスト用エーテルが手に入ったら、次に選んだパブリックテストネットへのデプロイを進めることができます。EtherscanとMetaMaskを使用して、デプロイメントレシートからコントラクトアドレスを使用して(次のコントラクトをデプロイしたときのJavascript出力を参照)コントラクトを検索し(図3)、トークンを自分のウォレットにインポートして(図4)、作業を確認することができます。 2_deploy.js ===========     Deploying ‘MyToken’     - - - - - - - -      > transaction hash:    0x1b2f67de68204ae3c137985379103ce8435a51a45452f624487e13b182ab2052
    > Blocks: 1            Seconds: 18
    > contract address:     0x3dd50Bcb9E125f1B7537f257fB6f4C165a02cB0f
    > block number:        10822250
    > block timestamp:        1628784232
    > account:            0x6dfA9B40F8a6AC500BcD0F09Bfa7709c6bD74dBC
    > balance:            16.44630489
    > gas used:            3171561 (0x3064e9)
    > gas price:        20 gwei
    > value sent:        0 ETH
    > total cost:        0.06343122 ETH
    > Saving artifacts 
    – – – – – – – – – – – – – – – – – – – – – 
    > Total cost:        0.06343122 ETH
例3: MyTokenコントラクトをデプロイした際のJS出力(デプロイメント受信)
図3:Etherscan上のMyTokenコントラクト
図4:MetaMaskウォレットで見たMyToken(MTK)と呼ばれるテストNFT
デプロイしたコントラクトはEtherscanで手動で確認することができますが、私たちのコントラクトはファイルをインポートしていたため、確認するのが困難でした。コマンドラインから以下のTruffleコマンドを実行することで、難なく成功しました。
truffle run verify –network
コントラクトを検証することで、Etherscan上でコードが公開され、ユーザーとの透明性が確保され、利用可能な公開関数への問い合わせや書き込みができるようになります。スマートコントラクトには様々な公開機能がありますが、私たちがテストコントラクトに含めたのは、非所有者がNFTを譲渡できるようにするための機能だけでした。
    
テスト中、トークンをある所有者から別の所有者に転送する方法として最初に見つかったのは、Etherscan上でMetaMaskまたはWalletConnect(いずれもWeb3ウォレット)を介してWeb3に接続し、NFT所有者のウォレットアカウント番号、転送先アカウント、NFTのIDを指定してsafeTransferFrom関数を使用する方法です。この方法でMTKトークンの送金に成功しました(0.00010114 rETHのガス代がかかった後)。 
より使いやすいと思われる別の方法として、MetaMask独自の「送信」機能があります。この機能は現在、モバイルアプリでのみ利用可能で、エクステンションでは利用できないことに留意してください。 
契約者だけが使用できるはずの機能が、一般に公開されていることに懸念を持ちました(特に所有権と鋳造の機能)。透明性を高めるためにすべての機能を公開することは可能ですし、そうすべきですが、特権的な機能にはNFTの所有者だけがアクセスできるようにすべきです。そこで、契約の所有者でないアカウントで前述のmintMany機能を使おうとしたところ、当然のことながら取引は成功しませんでした。MetaMaskは、「このトランザクションは失敗することが予想されます」と警告し、このトランザクションを試行しないよう助言した。実行しようとすると高くつくが失敗することが予想されるので、お勧めしない。”と警告した。とにかく続けてみたところ、トランザクションは確かに「Fail with error ‘Ownable: caller is not the owner’」と報告された。
結論
NFT、スマートコントラクト、テストネットに関する理解は大きく進みましたが、この作業はNFTの開発と実装に関する理解のほんの始まりにすぎません。NFTやその他のスマートコントラクトは非常に複雑で、欠陥は微妙で危険な場合があり、常に追加すべき機能が存在します。しかし、一度デプロイされたコントラクトを変更することは、かなり困難です。
このプロジェクトは、私たちインターンにとって楽しいものでした。  NFTにまつわる多くの専門用語や混乱を解き明かし、NFTの作り方を学ぶ機会を与えてくれたのです。暗号通貨やスマートコントラクトへの関心の高さを考えると、私たちが得た知識は、若いITプロフェッショナルとして成長する上で非常に有益なものだと思います。  LPIでのインターンから多くのことを学んだので、いつかまたこの分野のプロジェクトに参加したいと思います。

About developer:

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です