💬
[Astar]コントラクト備忘録26(psp22 Cappedについて)
こちらの知見がたまったので、備忘録として残します。
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