最近、eth 上のスマートコントラクト開発を学んでいます。この記事では、Lil Nouns コントラクトの学習のまとめを行います。Nouns オークションのプロセス、NFT svg をガスを節約する方法で完全にチェーン上に保存する方法、および次のオークションの前に Nouns の traits を事前に取得する方法について理解することができます(そして、次の lil Nouns traits をリアルタイムで取得できるツールを作成しました)。
オークションコントラクト#
Lil Nouns オークションに参加したことがある人は、各ラウンドのオークションが終了した後に手動で settle する必要があることを知っています。公式ウェブサイトの「Pick the next lil Noun」ボタンをクリックすると、NounsAuctionHouse コントラクトの settleCurrentAndCreateNewAuction () 関数を呼び出すためにウォレットが起動されます。この関数は 2 つの操作を行います。まず、_settleAuction () を呼び出して前のオークションを settle し、もし今回のオークションに入札がない場合は lil noun を破棄し、入札がある場合は lil noun を勝者のウォレットに転送します。最後に、bid の資金を lil nouns dao に転送します。
次に、createAuction の実装を見てみましょう。オークションを作成する際には、まず新しい noun を mint します(ここでは、10 番目と 11 番目の lil noun 以外はすべてオークションコントラクトに mint されます)。そして、返された noun id をパラメータとして現在のオークションの変数状態を更新し、開始時間と終了時間を更新し、settled 変数を false に設定します。
ユーザーが入札する際には、前の入札者の入札額以上である必要があります(第 4 の require)。まず、前の入札者に ETH を返し、次にオークションの変数に現在の入札者と入札額を記録します。最後に、オークションの終了前に 90 秒以内に入札が行われた場合、現在のオークションが 90 秒延長されます。
seed コントラクト#
次に、mint 時の nouns の traits がどのように決定されるかについて説明します。nouns は、前のブロックの blockhash と前の nounId をシードとして疑似乱数を生成し、その疑似乱数を各 trait の総量で割った余りをその trait id の値とします。もちろん、疑似乱数は右シフトされます。そうしないと、異なる trait の総量が同じ場合に生成される trait id が常に同じになってしまいます。
疑似乱数である以上、次の nouns の traits を予測することができます。上記のコードのアルゴリズムに従えば、正しい traits を得ることができます。皆さんの利便性のために、私は次の lil noun の見た目をリアルタイムで確認できるウェブサイトを作成しました。前のオークションの lil noun の番号を入力するだけで、次の lil noun の見た目を確認できます。ただし、自分の settle auction のトランザクションが現在のブロックにパッケージ化されていることを確認してください。
https://lil-nouns-predict.vercel.app
最後に、非常にクールなトリックを紹介します。みなさんは eth 上のストレージが非常に高価であることを知っていると思いますので、nft プロジェクトは多くの場合、nft メタデータを ipfs などのプラットフォームに保存することを選択します。Nouns は@0xsequenceの SSTORE2 コントラクトを使用してガスを最適化しています。SSTORE2 はデータをバイトコードとしてエンコードし、読み取り時には直接コントラクトの EXTCODECOPY を読み取ります(このようなトリッキーな操作を初めて知りました)。唯一の欠点は、状態変数のように変更できないことであり、静的なデータを保存するのに非常に適しています。これにより、データの書き込みと読み取りの両方のガスが大幅に最適化されます。