🐷

[Astar]RMRKコントラクト備忘録④(「mint」「mint_many」を細かく見てみよう!)

2023/03/31に公開

この記事は下の記事の続きです。
https://zenn.dev/yuki2020/articles/eb76f1c8aa688a

本日は、RMRKの関数をさらに細かく見ていきたいと思います。

1 mint 関数について

まずは、こちらの「mint」関数から見ていきます。

下のように、「only_role」というmodifier(修飾子)がついていることがわかります。

ちなみに、CONTRIBUTORはRoleTypeという型で、1という値になっています。

では、次の処理である、_check_amountについて見ていきましょう。

その名の通り、mintするamount(量)をチェックしており、下のように分かれています。

最初で、mint量が0であれば、エラーになるようにしています。

なお、「into」はエラー型からエラー値を生成するために使われているようです。

なお、エラー型とエラー値についてはこちらになります。

エラー型がエラーの種類を表し、それをインスタンス化して、エラーの詳細情報を含むのがエラー値です。

次にこちらを確認します。

「last_token_id」に対して、checked_add(mint_amount)を行っているので、オーバーフローのチェックをしつつ、mint量を合計しています。

また、下にあるように、if let構文を使い、checked_addの結果がsomeであれば、その結果をamountに入れ、Noneであれば、エラーを返しています。

そして、こちらは、mint後の量が、max_supply以下であればOKを返しています。

なお、エラーについては、commonの中にこのように定義されています。

max_supplyを超える場合には、このように、「CollectionIsFull」というエラーが発生します。

では、次にこちらの、「_mint」を見てみましょう。

下のように、先ほどと同様にchecked_addが行われています。

ここで、ok_orが使われていますね。

こちらにあるように、Option型をResult型に変換しています。

では、次にこちらの「_mint_to」についてです。

こちらはOpenBrushのpsp34::psp34::Internalのものが使われています。

最後に、ストレージの「MintingData」のlast_token_idにtoken_idが入れられています。

2 mint_many 関数について

では、mint_many関数について見てみましょう。

こちらは「non_reentrant」というmodifierがついていますね。

solidityで出てくるものと同様、再入を防ぐもので、このような構成になっています。

簡単に見てみると、入る時に「ENTERED」であれば入るのを拒否します。

入った後、「ENTERED」にし、出る際に、「NOT_ENTERED」にします。

「ink::env::set_contract_storage」も見てみましょう。

その名の通り、コントラクトのストレージを更新しています。

そして、第一引数にKeyのデフォルト値を渡しています。

下のように、空のキーにデータを割り当てることで、新しいキーを動的に生成しているようです。

また、こちらのbodyの部分も見てみましょう。

こちらはクロージャであるようです。

では、戻ってみましょう。

_check_amountは先ほどと同じなので、「_mint_many」を見てみましょう。

このように、「next_to_mint」にlast_token_idの次の値を入れ、「mint_offset」にnext_to_mintとmint_amountの合計を入れます。

そして、forで回しています。

ここで、_となっているのは、繰り返しの中でここに相当する変数を使用しないためです。

最後に、OKが返されます。

2つ入っているので、タプルとして返されることになります。

では、どのように返ってくるかを見てみましょう。

0個をミントしようとすると、「CannnotMintZeroTokens」のエラーが返ってきます。

問題ない場合は、このようにタプルが返ってきます。

上限を超える場合は、「CollectionIsFull」のエラーが返ってきます。

今回は以上です。

Discussion