casperlabs_contract_utils/
admin_control.rs1use casper_contract::{
2 contract_api::{runtime, storage},
3 unwrap_or_revert::UnwrapOrRevert,
4};
5use casper_types::{ApiError, Key};
6
7use crate::{ContractContext, ContractStorage, Dict};
8
9const ADMINS_DICT: &str = "admins";
10
11pub trait AdminControl<Storage: ContractStorage>: ContractContext<Storage> {
12 fn init(&mut self) {
13 Admins::init();
14 }
15
16 fn add_admin(&mut self, address: Key) {
17 self.assert_caller_is_admin();
18 self.add_admin_without_checked(address);
19 }
20
21 fn disable_admin(&mut self, address: Key) {
22 self.assert_caller_is_admin();
23 Admins::instance().disable_admin(&address);
24 }
25
26 fn add_admin_without_checked(&mut self, address: Key) {
27 Admins::instance().add_admin(&address);
28 }
29
30 fn assert_caller_is_admin(&self) {
31 let caller = self.get_caller();
32 if !Admins::instance().is_admin(&caller) {
33 runtime::revert(ApiError::User(20));
34 }
35 }
36}
37
38struct Admins {
39 dict: Dict,
40}
41
42impl Admins {
43 pub fn instance() -> Admins {
44 Admins {
45 dict: Dict::instance(ADMINS_DICT),
46 }
47 }
48 pub fn init() {
49 storage::new_dictionary(ADMINS_DICT).unwrap_or_revert();
50 }
51
52 pub fn is_admin(&self, key: &Key) -> bool {
53 self.dict.get_by_key::<()>(key).is_some()
54 }
55
56 pub fn add_admin(&self, key: &Key) {
57 self.dict.set_by_key(key, ());
58 }
59
60 pub fn disable_admin(&self, key: &Key) {
61 self.dict.remove_by_key::<()>(key);
62 }
63}