casperlabs_ownable/
ownable.rs1use crate::alloc::string::ToString;
2use crate::data::{self};
3use alloc::collections::BTreeMap;
4use alloc::{string::String, vec::Vec};
5use casper_contract::contract_api::runtime;
6use casper_contract::contract_api::storage;
7use casper_types::{ApiError, ContractHash, ContractPackageHash, Key, URef};
8use casperlabs_contract_utils::{ContractContext, ContractStorage};
9#[repr(u16)]
12pub enum Error {
13 OwnableNotOwner = 11501,
15 OwnableNewOwnerAddressZero = 11502,
17}
18
19impl From<Error> for ApiError {
20 fn from(error: Error) -> ApiError {
21 ApiError::User(error as u16)
22 }
23}
24
25pub enum OwnableEvent {
26 OwnershipTransferred { previous_owner: Key, new_owner: Key },
27}
28
29impl OwnableEvent {
30 pub fn type_name(&self) -> String {
31 match self {
32 OwnableEvent::OwnershipTransferred {
33 previous_owner: _,
34 new_owner: _,
35 } => "OwnershipTransferred",
36 }
37 .to_string()
38 }
39}
40pub trait OWNABLE<Storage: ContractStorage>: ContractContext<Storage> {
41 fn init(&mut self, contract_hash: ContractHash, package_hash: ContractPackageHash) {
42 data::set_owner(self.get_caller());
43 data::set_hash(contract_hash);
44 data::set_package_hash(package_hash);
45 self.ownable_emit(&OwnableEvent::OwnershipTransferred {
46 previous_owner: data::zero_address(),
47 new_owner: data::get_owner(),
48 });
49 }
50 fn owner(&self) -> Key {
52 return data::get_owner();
53 }
54 fn only_owner(&self) {
56 if !(self.is_owner()) {
57 runtime::revert(ApiError::from(Error::OwnableNotOwner));
58 }
59 }
60 fn is_owner(&self) -> bool {
62 return self.get_caller() == data::get_owner();
63 }
64 fn renounce_ownership(&mut self) {
70 self.only_owner();
71 self.ownable_emit(&OwnableEvent::OwnershipTransferred {
72 previous_owner: data::get_owner(),
73 new_owner: data::zero_address(),
74 });
75 data::set_owner(data::zero_address());
76 }
77 fn transfer_ownership(&mut self, new_owner: Key) {
80 self.only_owner();
81 self._transfer_ownership(new_owner);
82 }
83 fn _transfer_ownership(&mut self, new_owner: Key) {
84 if !(new_owner != data::zero_address()) {
85 runtime::revert(ApiError::from(Error::OwnableNewOwnerAddressZero));
86 }
87 self.ownable_emit(&OwnableEvent::OwnershipTransferred {
88 previous_owner: data::get_owner(),
89 new_owner: new_owner,
90 });
91 data::set_owner(new_owner);
92 }
93
94 fn ownable_emit(&mut self, ownable_event: &OwnableEvent) {
95 let mut events = Vec::new();
96 let package = data::get_package_hash();
97 match ownable_event {
98 OwnableEvent::OwnershipTransferred {
99 previous_owner,
100 new_owner,
101 } => {
102 let mut event = BTreeMap::new();
103 event.insert("contract_package_hash", package.to_string());
104 event.insert("event_type", ownable_event.type_name());
105 event.insert("previous_owner", previous_owner.to_string());
106 event.insert("new_owner", new_owner.to_string());
107 events.push(event);
108 }
109 };
110 for event in events {
111 let _: URef = storage::new_uref(event);
112 }
113 }
114}