casper_contract_sdk/contrib/ownable.rs
1//! This module provides an implementation of the Ownable pattern for smart contracts.
2//!
3//! The Ownable pattern is a common design pattern in smart contracts that allows for
4//! a single owner to control the contract. This module provides a simple implementation
5//! of this pattern, allowing for ownership to be transferred or renounced.
6use borsh::{BorshDeserialize, BorshSerialize};
7use casper_contract_macros::CasperABI;
8
9#[allow(unused_imports)]
10use crate as casper_contract_sdk;
11use crate::{casper::Entity, macros::casper};
12
13/// The state of the Ownable contract, which contains the owner of the contract.
14#[casper(path = crate)]
15pub struct OwnableState {
16 owner: Option<Entity>,
17}
18
19impl Default for OwnableState {
20 fn default() -> Self {
21 Self {
22 owner: Some(crate::casper::get_caller()),
23 }
24 }
25}
26
27/// Represents the possible errors that can occur during ownership operations.
28#[derive(CasperABI, BorshSerialize, BorshDeserialize)]
29#[casper(path = crate)]
30pub enum OwnableError {
31 /// The caller is not authorized to perform the action.
32 NotAuthorized,
33}
34
35/// The Ownable trait provides a simple ownership model for smart contracts.
36/// It allows for a single owner to be set, and provides functions to transfer or renounce
37/// ownership.
38#[casper(path = crate, export = true)]
39pub trait Ownable {
40 #[casper(private)]
41 fn state(&self) -> &OwnableState;
42 #[casper(private)]
43 fn state_mut(&mut self) -> &mut OwnableState;
44
45 /// Checks if the caller is the owner of the contract.
46 ///
47 /// This function is used to restrict access to certain functions to only the owner.
48 #[casper(private)]
49 fn only_owner(&self) -> Result<(), OwnableError> {
50 let caller = crate::casper::get_caller();
51 match self.state().owner {
52 Some(owner) if caller != owner => {
53 return Err(OwnableError::NotAuthorized);
54 }
55 None => {
56 return Err(OwnableError::NotAuthorized);
57 }
58 Some(_owner) => {}
59 }
60 Ok(())
61 }
62
63 /// Transfers ownership of the contract to a new owner.
64 #[casper(revert_on_error)]
65 fn transfer_ownership(&mut self, new_owner: Entity) -> Result<(), OwnableError> {
66 self.only_owner()?;
67 self.state_mut().owner = Some(new_owner);
68 Ok(())
69 }
70
71 /// Returns the current owner of the contract.
72 fn owner(&self) -> Option<Entity> {
73 self.state().owner
74 }
75
76 /// Renounces ownership of the contract, making it no longer owned by any entity.
77 ///
78 /// This function can only be called by the current owner of the contract
79 /// once the contract is deployed. After calling this function, the contract
80 /// will no longer have an owner, and no entity will be able to call
81 /// functions that require ownership.
82 #[casper(revert_on_error)]
83 fn renounce_ownership(&mut self) -> Result<(), OwnableError> {
84 self.only_owner()?;
85 self.state_mut().owner = None;
86 Ok(())
87 }
88}