📌

[Astar]コントラクト備忘録24(Ownableについて)

2023/03/02に公開

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

1 概要

  1. Ownableについて

2 内容

本日は、こちらのOwnableのコントラクトを見ていきましょう。
OpenBrushのexample基本そのままです。

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

#[openbrush::contract]
pub mod psp37 {
    use ink_prelude::vec::Vec;
    use openbrush::{
        contracts::{
            ownable::*,
            psp37::extensions::{
                burnable::*,
                mintable::*,
            },
        },
        modifiers,
        traits::Storage,
    };

    #[ink(storage)]
    #[derive(Default, Storage)]
    pub struct Contract {
        #[storage_field]
        psp37: psp37::Data,
        #[storage_field]
        ownable: ownable::Data,
    }

    impl Contract {
        #[ink(constructor)]
        pub fn new() -> Self {
            let mut instance = Self::default();
            instance._init_with_owner(Self::env().caller());
            instance
        }
    }

    impl Ownable for Contract {}

    impl PSP37 for Contract {}

    impl PSP37Mintable for Contract {
        #[ink(message)]
        #[modifiers(only_owner)]
        fn mint(&mut self, to: AccountId, ids_amounts: Vec<(Id, Balance)>) -> Result<(), PSP37Error> {
            self._mint_to(to, ids_amounts)
        }
    }

    impl PSP37Burnable for Contract {
        #[ink(message)]
        #[modifiers(only_owner)]
        fn burn(&mut self, from: AccountId, ids_amounts: Vec<(Id, Balance)>) -> Result<(), PSP37Error> {
            self._burn_from(from, ids_amounts)
        }
    }
}

では、こちらの、「_init_with_owner」関数から見ていきましょう。

Githubを見てみると、このように定義されていることが確認できます。

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

なお、こちらのchatGPTにあるように、<T: Storage<Data>>という部分では、型Tに対して、Storage<Data>を実装していることを要求しています。

chatGPT

また、ownerはAccountIdの型として、定義されています。

次に、「only_owner」というmodifier(修飾子)を見てみましょう。

まず、whereキーワードで型の制約を行っています。

そして、ownerと呼び出し元が異なれば、エラーを返しています。

せっかくなので、「OwnableError」も見てみましょう。

「CallerIsNotOwner」と「NewOwnerIsZero」の2つがあることがわかります。

また、この機会に、Err(From::from())の部分も見ていきたいと思います。

下にあるように、From::fromはエラーを別のエラーに変換するために使われています。

chatGPT

せっかくなので、ownerを変える、「transfer_ownership」についても見てみましょう。

このように、「is_zero」という関数が使われています。

このように、「AccountIdExt」に「is_zero」が定義され、それが「AccountId」に実装されていることが確認できます。

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

「owner」を実施すると、コントラクトを作成したアカウントIDが表示されます。

この状態で、mintを行うと、「only_owner」のmodifierも問題ないので、mintができます。

では、「transferOwnership」でownerを「test2」に変更します。

すると、mintをしようとすると、ownerではないので、エラーになるようになりました。

shibuya

ZUtqcN4hfjhzq2c6GD7asXawvsbe9VPb27Wifw2n2spXF2e

今回は以上です。

Discussion