【NFT】素人でもミントサイトで独自コントラクトのジェネラティブを作る方法
ジェネラティブNFTコレクションを作ろうと思った理由
7歳のチビ画伯といっしょに、ジェネラティブNFTを作りました。
いわゆる独自コントラクトのジェネラティブNFTで、ミントサイトでミントするプログラムです。 これからも今の一点物のコレクションは続けていきます。
ではなぜジェネラティブに挑戦しようと思ったのか。
- 多くの方に気軽にチビ画伯のNFTを手にしてほしかった
- 独自コントラクトに挑戦したかった(新しもの好き)
- できることの幅が広がると思った
おかげさまでメインコレクションは新作を出品すると数日以内にはお迎えいただけるようになり、Volume Tradedも3.8ETHとなりました。
https://opensea.io/collection/chibi-main1
しかし現在のフロア価格は、気軽に買ってねといえる金額ではありません。
チビ画伯を応援してくださる方はホルダーさん以外にもたくさんいるので、そういったサポーターさんたちにも気軽に作品を手にとってもらえたらな、と思いました。
独自コントラクトにはいつか挑戦したいと思っていました。
かといって外注する予算もないので、まずは自分で作ってみようと思った次第です。
また、ジェネラティブコレクションを作れるようになったら、将来的にチャリティプロジェクトを始めたり、なんらかの企画の資金集めなど、挑戦できることの幅が広がると思いました。
素人でも作れるの?
結論からいうと、いろいろありましたがなんとかできました。
母はプログラミングほとんどできません。
VBAとかHTMLとかちょっと書いたことがあるぐらいです。
よくご存じない方からするといやいや書けるんじゃんと思う方もいるかもしれませんが、エンジニアの方からしたらそれはプログラミングじゃないですって突っ込まれるレベルです。
要するにド素人です。安心してください。
そんなド素人でも、なんとかそれっぽいものが作れましたので、自分自身のメモも兼ねてこの記事を作りました。学習のご参考用として公開しますので、この記事が、**手動じゃないジェネラティブに挑戦したい!**という方のお役に立てればと思います。
なお、繰り返しますがド素人のため、技術的に間違いなどもあるかもしれませんし、お金を扱うことなのでリスクを伴います。
また、もともとがガチャ要素のある構造のミントサイトなので、賭博法に引っかかる可能性もゼロではありません。
個人的には380円と安いし、レアリティもつけてないし、リビール機能もつけてないので、「得喪を争う」ことにならないのでは・・・と思ってます。
「得喪を争う」とは、勝者が財物を得て、敗者がこれを失うことを意味し、当事者の一方がこれを失うことがない場合は、「得喪を争う」ものには該当しないと解されています。
第6回 【弁護士が解説】 NFTを活用したブロックチェーンゲームと法規制
ただ、私は弁護士ではないですし、いずれにせよ参照いただく際はご自身の責任で実行いただくよう、お願いします。
予算が許すなら、信頼できるエンジニアさんにお願いするのがベストかと!いつかはなぎさん(@pote_pote_salad)にお願いしたいなぁと思ってます。
成果物(できあがったジェネラティブNFTコレクション)
最後にもご紹介しますが、先にちら見せ。
🎀販売スタート🎀
— CHIBI🇯🇵NFTチビ画伯8歳 crypto-artist-chibi.eth (@Artist7yChibi) March 3, 2022
7歳の女の子 #チビ画伯 とママがつくったジェネラティブNFTプロジェクト #チビジェネ忍者 販売スタート!
🌺限定1000枚
🌺2MATIC (380円) Polygon
🌺ミントサイトで購入
🌺どの子が出るかはOpenSeaのプロフィールでわかるよ(レア個体なし)
ミントサイトリンクや注意点は続く! pic.twitter.com/xdrTtViaZY
参考にした動画とサイト
今回はこちらのHashLipsというYouTubeをもとにジェネラティブNFTのプログラムを作りました。
神動画なんですが、いかんせん2時間半と長いのと、公式のテキストの情報がないんですよね・・・それが非常にきつい。
日本語情報としては、
ユウキさんのnote
(保存版)10,000種類のジェネレイティブNFTの作り方
大海さんひげくまさんご夫妻のブログ
クリエイターがHashlipsを使ってmintジェネレイティブNFTを作る
を参照させていただきました!ありがとうございました!
めっちゃおおまかな流れ
- HashLipsの**「hashlips_art_engine」**でイラストとメタデータ(○○が○%とか)をジェネレートする
- IPFSサーバであるPinataに参照用のイラストとjson(メタデータ)をアップロードする
- **「hashlips_nft_contract」**のSolidityファイルを、オンラインSolidityコンパイラであるRemixにコピペしてコントラクトを作る
- **「hashlips_nft_minting_dapp」**でミントサイトを作る
準備
HashLipsのレジストリをダウンロードする
HashLipsというプロジェクトの「ジェネラティブNFT制作キット」みたいなものをダウンロードします。\ これのおかげでちまちまコード打たなくて済みます。神です。
各レジストリのReleasesのLatestから最新版をダウンロードして、PCに保存します。\ なお、保存先のフォルダに「デスクトップ」などの日本語が含まれてると動かないので注意。
node.jsをインストールする
あんまよくわかってないんですが、Javascriptを動かすやつらしいです。
左のをダウンロードしてインストールします。
Visual Studio Codeをインストールする
これは必須ではないですが、プログラミングエディタなんて持ってないという方はインストールしましょう。
HashLipsの動画でも使っているし、結構使いやすかったです。
https://azure.microsoft.com/ja-jp/products/visual-studio-code/
レイヤー画像を作成・保存する
ジェネラティブなのでレイヤーが必要です。
私たちはProcreateというiPadソフトで作りました。顔以外は4~8種類ずつ作ってます。
これを、「hashlips_art_engine-1.1.2_patch_v5」フォルダの下の「layers」フォルダに種類別に分けて保存します。
ファイルの名前は「○○#10.png」で統一しました。2など小さい数字を混ぜると、レア度が変わりますが、賭博法だかなんかで逮捕されるのも嫌なのですべて同じ確率にしています。
ここまでが準備です。
ジェネラティブ画像とメタデータを作成する
まずはジェネラティブの画像とメタデータを作成しましょう。
VS Codeでファイル>フォルダを開く>hashlips_art_engine-1.1.2_patch_v5フォルダを開きます。
Ctrl+@でターミナルを開きます。
この動作はコマンドを実行するときによく使うので覚えてください。
npm install
と打ち込んでEnter。よくわかんないけど必要な操作らしい。
config.jsを修正する
- namePrefix:OpenSeaでいうコレクション名
- description:作品のDescription
- growEditionSizeTo:最大ミント数。1000にしました。
- layerのフォルダ名を書き換えます。レイヤーは順番が大事で、コードで一番上のフォルダのレイヤーが、実際は一番下になります。
- uniqueDnaTorrance:まったく同じ組み合わせを何枚まで許容するか。
1枚も許容したくないんだけど、これ入れとかないと途中で止まる。
組み合わせの通りは十分なはずなのに、こんな感じ(DNA exists!)で同じのが存在してしまいます。ごめんなさい。
Ctrl+@でターミナルを開き、 node index.js と打ち込んでEnter。
これで画像がbuild>imagesフォルダに
メタデータ(jsonファイル)がbuild>jsonフォルダに入ります。
imagesデータを IPFSに上げる
PinataというIPFSサービスを使います。
https://app.pinata.cloud/pinmanager
build>imagesのフォルダをアップロード。
「CID」というのがこのIPFSの識別番号なので、これをコピーします。
config.jsファイルに戻って、ここを書き換えます。
baseUriの「ipfs://」の後ろに先ほどのCIDを貼り付けます。
config.jsをCtrl+Sでセーブして、Ctrl+@でターミナルを出し、次のコマンドを実行します。 node utils/update_info.js
これで1000のjsonファイルの情報がアップデートされ、IPFSの画像ファイルを見に行くようになりました。 試しに適当なjsonファイルを開いてみると、ちゃんと参照しています。
JSONデータを IPFSにアップロードする
書き換わったjsonファイルたちを、画像データと同じようにフォルダごとPinataにアップロードします。
アップロードできました。
画像とメタデータはこれで完成。
NFT作成用のコントラクトを修正する
VS Codeでファイル>フォルダを開く>「hashlips_nft_contract-1.0.1」フォルダを選択して開きます。
その中の「SimpleNFT_flat.Sol」ファイルを開いておきます。あとでコピーします。
RemixでNFT作成用のコントラクトをデプロイする
Remixはオンライン上でSolidityを動かすシステムです。
開いたら、左上の+アイコンをクリックします。
contractsフォルダの中のこの3つのファイルをすべて削除します。
contractsフォルダが空になったら、その中に新規ファイルを作ります。
「CHIBIgene.sol」としました。
VS Codeで開いている「SimpleNFT_flat.Sol」の中身を、Remixの「CHIBIgene.sol」にコピペします。 1235行目の「NFT」の文言を、「CHIBIgene」に変更します。
こんな感じ。
同じカタマリの部分を以下のように修正します。
- uint256 public cost = 0.05 ether; ←価格 たぶんこのままだとほぼタダなので、3MATICの場合は「3 ether」もしくは単位をつけず「3000000000000000000」にしておくことを推奨 ※修正しました!
- uint256 public maxSupply = 1000;←全体のNFTの数
- uint256 public maxMintAmount = 20;←1度にミントできる最大数
- bool public paused = false;←trueにしとくとミントできないので、アナウンス後にfalseに変えるなどできるらしいですが私はfalseのままにしておきます
- bool public revealed = true;←リビール機能つけない場合はtrueで!
注意
私はMATICのときの書き方がわかってなくて、価格をタダみたいな状態でPolygonチェーンにアップしてしまいました。
それが原因で、見知らぬ人にほぼタダで(0.02MATIC?)直コン叩いて80枚以上ミントされるという悲しい事件が裏では起きてました(長くなるので別の記事で書きます)
変換はこちらのサイトでできます。
HashLipsへのお布施をしない場合
1344行目に「一次売上の5%をHashLipsに渡します」とさらっと書いてあります。
このままにしておくとWithdraw(売上を引き出す)するときに5%がHashLipsに入ってしまうので、自分のウォレットアドレスに書き換えました。
(//でコメントアウトするだけでもいいのかも)
Ctrl+Sでセーブします。 COMPILER CONFIGURATIONの「Auto compile」「Enable optimization」にチェックを入れます。
テストネットでコントラクトをデプロイする
動画で紹介されていたRinkebyというテストネットを使いました。
ただ、これはイーサリアムのテストネットなので、Polygonでやりたい方はPolygonのテストネットで試してみてください。
ぱんさん、教えてくれてありがとうございます!
https://mumbai.polygonscan.com/
Polygonのテストネット教えていただいたときにはすでに本番環境にしちゃってたので、ここからはRinkebyのやり方です。
まず、テストネットにイーサを入れます。このサイトでウォレット接続すればもらえます。
https://faucets.chain.link/rinkeby
無事もらえました。
Rinkebyテストネットどうやって追加するの?という方、非表示になってるだけです。
左端のメニューの一番下のイーサリアムアイコンみたいな「Deploy & Run transactions」をクリックします。
ENVIRONMENTは「Injected Web3」を選び、テストなのでRinkebyが下に表示されるようにします。(メタマスクでRinkebyを選べばOK)
CONTRACTで「○○ - contracts/○○.sol」を選びます。
オレンジ色のDeployの右端の矢印をクリック。
ここには一度だけ実行するコンストラクタの処理について書くそうです。(よくわかってない)
今回はこんな感じ。
- _NAME: CHIBIgeneNinja(適当)
- _SYMBOL: CGN(適当)
- _INTBASEURI: ipfs://QmTj4ZdiSzxTrJ9h8WW5Qp9C5ymMYQJXWD6TS9UMwsF2YG/(PinataのメタデータファイルのCIDを ipfs://○○/ のように書く)
- _INITNOTREVEALEDURI:(リビールしないので空欄にしたいんですが、次のコピペがうまくいかないので_INTBASEURIと同じ内容にしました)
大事なのは_INTBASEURIの最後にスラッシュを入れることだそうです。
TRANSACTボタンを押す前に、コピーアイコンをクリックします。
VS Codeに戻り、「info」フォルダを作ってその下に「ethereum test」「polygon」ファイルを作ります。
コピーしたデータは「ethereum test」に貼り付けておきます。あとでVerifyするのに使います。(って動画で言ってたけど、テスト版はVerifyしなくていいと思う。違ったらすみません)
テストネットでデプロイする transactボタンを押すとメタマスクが出てくるので、確認を押します。
「Deployed Contracts」の下をクリックするとずらっとコントラクトのコマンドみたいなのが出てきます。
テストでミントしてみます。mintに2と入れてmintを押すと、メタマスクが起動します。\ 確認を押して、下の方の青いtotal supplyをクリックすると2になっています。
OpenSeaのテストサイトで見てみよう
テストサイトで見てみると、おおおー、無事ミントされてます。感動。(その後追加したので4個ミントされてます)
本物のPolygonチェーンでデプロイする
本来はミントサイトまで作ってから本物のチェーンでデプロイするのかな?
ちょっとわかってませんが、HashLipsの動画ではここで本番環境に換えてたので換えます。
メタマスクのチェーンをPolygonに変えると、ENVIRONMENTの下に「Custom (137)network」と出てきます。
TRANSACTボタンを押す前に、コピーアイコンをクリックします。
VS Codeに戻り、「info」フォルダの下の「polygon」ファイルに貼り付けておきます。あとでVerifyするのに使います。
オレンジ色のtransactをクリックします。
メタマスクが立ち上がりますが、ガス代の設定が低くて詰んだので、参考までに成功したときの情報を貼っておきます。 これは別の処理(Pause:一時停止)ですが、ガス代設定ミスるとこんな感じで詰まるんですよ・・・
これを避けるには、この編集のところから
このくらいに設定するとつまらなくなりました。
確認すると成功したようです。
コントラクトアドレスをコピーします。
VS Codeのpolygonファイルに貼り付けます。(単なるメモなので、txtファイルにしましたがどちらでも)
Remixの下から2番めのSOLIDITY COMPILERに戻り、CONTRACTで「○○(○○.sol)」を選択し、ABIをコピーします。
コピーしたABIはVSのpolygon.txtに貼り付けます。
コントラクトをVerifyする
VS Codeにメモしておいたコントラクトアドレスをコピーして、Polygonscanを開いて検索します。
https://polygonscan.com/Contractタブを開いてここをクリック
次に出てくる画面のスクショを撮るのを忘れてしまったのですが、ユーザー名とパスワードを求められました。アカウントを持っていなかったので登録して、再度Verifyをクリックするとこの画面になりました。
入力する値はRemixのここを参照します。
次のページでは、
- Optimization:Yes
- Contract Code:RemixのSOLIDITY COMPILERの○○.solの中身(コントラクト)
- Constructor Arguments ABI-encoded:ABIをコピペしたものの、大量の0の始まりから終わりまでの部分
ABIはこういうことね。
ここまで入れたら、Verify & Publish!成功しました。
おおお、Verify関係ないと思うけど、コントラクトアドレスに名前がついてる!感動。
Contractのところから、Remixみたいに操作もできるようになります。
おまけ:Remixを閉じてしまったら
動画では2:02のところで説明されてます。
Remixはブラウザベースなので、スマートコントラクトのファイルを保存しておくことをおすすめします。
左上の青いアイコン▶Download Backupでファイルを保存できます。
- 「CHIBIgene.sol」の中身を左上の上から3番目の「SOLIDITY COMPILER」にコピペしてセーブして、メタマスク接続。
- VS Codeに保存していたコントラクトアドレスを青い「At Address」の部分に貼り付けます。
- CONTRACTで「○○ - contracts/○○.sol」を選びます。
- 「At Address」をクリック
で復活します。オレンジ色のDeployは押しちゃダメだよ!
ミントサイト(Dapps)を作る
NFTをミントする特設サイトを作ります。
VS Codeに戻り、フォルダを開く>「hashlips_nft_minting_dapp-1.0.1」を開きます。
Ctrl+@でターミナルを開き、 npm install と入力してEnterを押します。
次に npm run start と入力してEnterすると、ブラウザでこのページが立ち上がりました。
URLのところを見ると「localhost:3000」とあります。
これはまだインターネット上に公開されたサイトではないです。
VSのターミナルの表示はこんな感じ。
このサイト(Dapps)をカスタマイズしていきます。
ミントサイトの見た目を変える
public>config>imagesの中に画像ファイルがあるので、これを置き換えていきます。
Procreateなどのお絵かきソフトで同じサイズ・同じ名前のファイルを作るとファイル置き換えるだけで反映されるのでかんたんです。
ブラウザを更新するとこんな感じ。(背景うまく反映できなかったので無視)
黄土色の背景をピンクにします。
public>config>theme.cssのprimaryのところをピンクにしました。
ファイルをCtrl+Sでセーブして、ブラウザを更新。
うん、かわいい!(背景のbg.pngを透過するとこうなりました)
ミントサイトのHTMLをいじる
VSのpublic>index.htmlを開き、以下を適当に変更してCtrl+Sでセーブします。
- 25行目:Title
- 26行目:content
ミントサイトのアイコンを変更する
VS Codeのpublic>manifest.jsonを開きます。
よくわかんないけど3種類あるので、好きなアイコンで作り直します。
- logo192.png:192ピクセル
- logo512.png:512ピクセル
- favicon.ico:bmpファイルで64×64 で保存したのち、拡張子だけ.icoにする
ミントサイトとスマートコントラクトを紐付ける
次に、このミントサイトとスマートコントラクトを紐付けていきます。 VSのpublic>config>config.jsonを開いて修正します。
- CONTRACT_ADDRESS:デプロイしたコントラクトアドレス
- SCAN_LINK:末尾のところをコントラクトアドレスに置き換える
- NAME/SYMBOL/ID:PolygonのMATICで売るならこのまま
- NFT_NAME:RemixのCHIBIgene.solファイル1235行目のコントラクト名をコピペしてみたけど、コントラクトのトークン名のほうかな・・・(CHIBIgeneNinja)
- SYMBOL:コントラクトの略称
- MAX_SUPPLY:最大ミント数
- WEI_COST:たぶん3MATICの場合は「3000000000000000000」
- DISPLAY_COST:3MATICなので「3」
- GAS_LIMIT:285,000のまま
- MARKETPLACE:そのまま
- MARKETPLACE_LINK:OpenSeaのコレクションリンク(ミントすると検索できて見つけられる)
- SHOW_BACKGROUND:bg.pngは透過した画像だと、trueにしたときに映えます
MATICの価格の書き方は、このサイトでコンバートしてコピペがいいかも。 3MATICならWeiの「3000000000000000000」です。難しい。
ABI.jsonの書き換え Remixの「SOLIDITY COMPILER」を開き、CONTRACTで「○○(○○.sol)」を選び、ABIをコピーして、VSのpublic>config>abi.jsonの中身を上書き。
ほかはこのままでもいいのですが、VS Codeのsrc>App.jsでも以下のような項目を修正できます。
- 一度にミントできる枚数の上限(プログラム上の上限はスマートコントラクトで決めていますが、ここで修正できるのはDapps上の上限です)
- ミントサイトに書かれてる文言(特定商取引法の表記を入れたかったので適当に書き換えました
ミントサイトを公開する
さて、とうとう実装です。
VS Codeのターミナルで npm run build と打ち込んで、サーバーにアップするbuildフォルダを作ります。
buildフォルダができてました。
これをPinataにアップロードしてもいいそうですが、私はブログやチビ画伯のサイト用のレンタルサーバーがあるのでXサーバーにアップしてみようと思います。
サブドメインを設定する
Xサーバーのサブドメイン設定についてはこちら。
Xサーバーのサーバーパネルにログインして、自分の持っているドメイン(今回はchibi-nft.com)にサブドメインを設定します。
ファイルマネージャーにミントサイトのデータをアップロードする サブドメインを設定したら、ファイルマネージャーにログインします。
chibigeneninjaサブフォルダができてました。
この中に「hashlips_nft_minting_dapp-1.0.1」のbuildフォルダをZIPしたものをアップロードして、展開します。
ZIPファイルを展開するとフォルダの階層が増えてしまったので、この画像のように中身をコピペ移動させました。
また、もともとあったindex.htmlのせいでindex.htmlのファイル名が変わってしまったので、buildフォルダにあったindex.htmlを活かすためにもともとあったやつをindex2.htmlにしました。
しばらくしてからこのアドレスに行くと・・・できてました!
ちなみにメタマスク接続すると「something went wrong」と出て詰んでたのですが、ownerのウォレットアドレスだとそのエラーが出るそうです。 サブ垢だと出ませんでした!
いやぁ・・・長かった。ここまでお読みいただき、ありがとうございました!
そして実は無料で何者かにミントされるという事件が開発中に起こりました。
助けてくださったsyouさん、edyさん、ありがとうございました!!
その事件については別途記事にしますね。
売上の出金方法
売上の出金はRemixでもできるようですが、だいぶ時間がたってしまったので、Polygonscanで試してみました。
Polygonscanでチビジェネ忍者のコントラクトアドレスを表示。 https://polygonscan.com/address/0xb0726ef4dee513dfa09e8f9a5581c979be565b36#code
Contractタブ→Write→Connect to Web3から、ウォレットを接続します。
withdrawに0を入力してWrite!
メタマスクで承認します。
2000MATIC分あるはずなんですが、なんか分割してる・・・
よくわかんないけど、メタマスクのMATICはたぶん増えたような。
チビジェネ忍者について
7歳の女の子 チビ画伯とママがつくったジェネラティブNFTプロジェクトです。
CryptoNinjaのくの一たちと、パートナーの動物たちをモチーフにしています。
一部オリジナル忍者とオリジナルパートナーも含まれています。
どんな子がでてくるかは、ミントしたあとにOpenSeaのご自身のプロフィールページでわかります。
- 最大発行数:1000枚
- ミント価格:2 Matic (Polygon) *なんと約380円!
レイヤーはこんな感じで作っています。
購入時のガス代はこのくらいの設定にするとつまりづらいです。(せいぜい数円です)
MATIC持ってないよ~という方は、PolygonのイーサをDfynのガスレスモードでスワップしてください。ガス代不要です。
おもちさんのこのブログがわかりやすいです。(記事内のUSDCをETHにすればOK)
【ガス代なし】スワップ手数料が無料|Dfynガスレスモードの使い方
二次流通はOpenSeaで、Polygonのイーサで購入できます。
ぜひ多くの方にお楽しみいただきたいです。