💡

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

2023/02/27に公開

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

1 概要

  1. psp22 pausableについて

2 内容

こちらのメッセージを作成しました。

OpenBrushのexampleの中身そのままです。

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

#[openbrush::contract]
pub mod my_psp22_pausable {
    use openbrush::{
        contracts::{
            pausable::*,
            psp22::*,
        },
        modifiers,
        traits::Storage,
    };

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

    impl PSP22 for Contract {}

    impl Transfer for Contract {
        /// Return `Paused` error if the token is paused
        #[modifiers(when_not_paused)]
        fn _before_token_transfer(
            &mut self,
            _from: Option<&AccountId>,
            _to: Option<&AccountId>,
            _amount: &Balance,
        ) -> Result<(), PSP22Error> {
            // TODO logic for before token transfer
            Ok(())
        }
    }

    impl Pausable for Contract {}

    impl Contract {
        #[ink(constructor)]
        pub fn new(total_supply: Balance) -> Self {
            let mut instance = Self::default();

            assert!(instance._mint_to(Self::env().caller(), total_supply).is_ok());

            instance
        }

        /// Function which changes state to unpaused if paused and vice versa
        #[ink(message)]
        pub fn change_state(&mut self) -> Result<(), PSP22Error> {
            self._switch_pause()
        }
    }
}

1) useについて

まずはuseを見てみましょう。

pausableがありますが、それ以上に、modifiersが設定されていることが注目ポイントです。

後でmodifiers(修飾子)は出てきます。

2) storage_fieldについて

次に、こちらのstorage_fieldを見てみましょう。

確認すると、下のように、①pausedと②_reservedという二つのデータがあることがわかりました。


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

3) #[modifiers(when_not_paused)]について

そして、今回着目すべきところが、こちらのmodifiersになります。

Transferの「_before_token_transfer」をオーバーライドし、トランスファーされる前に「when_not_paused」が実行されるようになっています。

具体的には、「paused」がtrueの時にトランスファーをしようとすると、エラーになるようになっています。

そして、こちらのGithubで確認すると、#[modifier_definition]で定義がされていることがわかりました。

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

4) newについて

次はこちらです。

「Self::default()」は新しいインスタンスを作成し、デフォルト値で設定しています。

一方、「is_ok()」はResult型に対し、OKならtrue、Errならfalseを返しています。

5) _switch_pause()について

最後に、こちらで_switch_pause()を実装しています。

最後に、実装はこのようにされていました。

その名の通り、pausedのtrueとfalseを入れ替えるものです。

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

Shibuya

XkTVWBjxej4BDkcRhWGZVgon9QLqssUPbQWyU8PkRV4mM1E

今回は以上です。

Discussion