💬

[Astar]コントラクト備忘録26(psp22 Cappedについて)

2023/03/04に公開

こちらの知見がたまったので、備忘録として残します。

1 概要

  1. psp22 Cappedについて

2 内容

本日は、こちらのOpenBrushのexample(psp22 Capped)に沿って見ていこうと思います。

#![cfg_attr(not(feature = "std"), no_std)]
#![feature(min_specialization)]

#[openbrush::contract]
pub mod my_psp22_capped {
    use openbrush::{
        contracts::psp22::extensions::{
            capped::*,
            mintable::*,
        },
        traits::{
            Storage,
            String,
        },
    };

    #[ink(storage)]
    #[derive(Default, Storage)]
    pub struct Contract {
        #[storage_field]
        psp22: psp22::Data,
        #[storage_field]
        cap: capped::Data,
    }

    impl PSP22 for Contract {}

    impl PSP22Capped for Contract {}

    impl PSP22Mintable for Contract {}

    impl psp22::Transfer for Contract {
        fn _before_token_transfer(
            &mut self,
            _from: Option<&AccountId>,
            _to: Option<&AccountId>,
            _amount: &Balance,
        ) -> Result<(), PSP22Error> {
            // `is_none` means that it is minting
            if _from.is_none() && self._is_cap_exceeded(_amount) {
                return Err(PSP22Error::Custom(String::from("Cap exceeded")))
            }
            Ok(())
        }
    }

    impl Contract {
        /// Constructor which mints `initial_supply` of the token to sender
        /// Will set the token's cap to `cap`
        #[ink(constructor)]
        pub fn new(inital_supply: Balance, cap: Balance) -> Self {
            let mut instance = Self::default();

            assert!(instance._init_cap(cap).is_ok());
            assert!(instance.mint(Self::env().caller(), inital_supply).is_ok());

            instance
        }
    }
}

こちらの「_init_cap」関数について見ていきましょう。

Githubを見てみると、このように実装されていることがわかります。

https://github.dev/727-Ventures/openbrush-contracts

そして、capという値はこちらでBalance型として定義されています。

ここまでで、初期値として、Cap(上限の値)を設定していることがわかりました。

続いて、こちらの「_before_token_transfer」関数を見てみましょう。

このようにoverrideしています。

「_is_none()」と「_is_cap_exceeded()」が共にtrueの時にエラーとしているようです。

ちなみに、「_is_none」はOption型で「None」の時に「true」を返すことがわかります。

https://doc.rust-lang.org/std/option/enum.Option.html#method.is_none

一方、「is_cap_exceeded」はミントした後の合計量がcapを超えると「true」となるようです。

では、実際にやってみましょう。

下のように、「cap」が発行量を超えるのは問題ありません。

一方、「cap」は上限なので、発行量より下回ると、エラーが発生します。

その後、ミントを行う場合も、「cap」以内であれば問題なくできます。

一方、「cap」を超えると、このようにエラーが発生します。

今回は以上です。

Discussion