|
48 | 48 | //! ## Example: Defining and Implementing a Trait |
49 | 49 | //! |
50 | 50 | //! ``` |
51 | | -//! use soroban_sdk::{contract, contractimpl, contracttrait, Env}; |
| 51 | +//! use soroban_sdk::{contract, contractimpl, contracttrait, Address, Env}; |
| 52 | +//! |
| 53 | +//! const ADMIN: &str = "admin"; |
| 54 | +//! const PAUSED: &str = "paused"; |
52 | 55 | //! |
53 | 56 | //! // Define a trait with default implementations |
54 | 57 | //! #[contracttrait] |
55 | 58 | //! pub trait Pausable { |
56 | 59 | //! fn is_paused(env: &Env) -> bool { |
57 | | -//! env.storage().instance().has(&"paused") |
| 60 | +//! env.storage().instance().has(&PAUSED) |
58 | 61 | //! } |
59 | 62 | //! |
60 | 63 | //! fn pause(env: &Env) { |
61 | | -//! env.storage().instance().set(&"paused", &true); |
| 64 | +//! let admin: Address = env.storage().instance().get(&ADMIN).unwrap(); |
| 65 | +//! admin.require_auth(); |
| 66 | +//! env.storage().instance().set(&PAUSED, &true); |
62 | 67 | //! } |
63 | 68 | //! |
64 | 69 | //! fn unpause(env: &Env) { |
65 | | -//! env.storage().instance().remove(&"paused"); |
| 70 | +//! let admin: Address = env.storage().instance().get(&ADMIN).unwrap(); |
| 71 | +//! admin.require_auth(); |
| 72 | +//! env.storage().instance().remove(&PAUSED); |
66 | 73 | //! } |
67 | 74 | //! } |
68 | 75 | //! |
|
75 | 82 | //! |
76 | 83 | //! #[contractimpl] |
77 | 84 | //! impl MyContract { |
| 85 | +//! pub fn __constructor(env: &Env, admin: Address) { |
| 86 | +//! env.storage().instance().set(&ADMIN, &admin); |
| 87 | +//! } |
| 88 | +//! |
78 | 89 | //! pub fn do_something(env: &Env) { |
79 | 90 | //! if Self::is_paused(env) { |
80 | 91 | //! panic!("contract is paused"); |
|
90 | 101 | //! Contracts can override specific functions while keeping the defaults for others: |
91 | 102 | //! |
92 | 103 | //! ``` |
93 | | -//! use soroban_sdk::{contract, contractimpl, contracttrait, Env}; |
| 104 | +//! use soroban_sdk::{contract, contractimpl, contracttrait, Address, Env}; |
| 105 | +//! |
| 106 | +//! const ADMIN: &str = "admin"; |
| 107 | +//! const PAUSED: &str = "paused"; |
94 | 108 | //! |
95 | 109 | //! // Define a trait with default implementations |
96 | 110 | //! #[contracttrait] |
97 | 111 | //! pub trait Pausable { |
98 | 112 | //! fn is_paused(env: &Env) -> bool { |
99 | | -//! env.storage().instance().has(&"paused") |
| 113 | +//! env.storage().instance().has(&PAUSED) |
100 | 114 | //! } |
101 | 115 | //! |
102 | 116 | //! fn pause(env: &Env) { |
103 | | -//! env.storage().instance().set(&"paused", &true); |
| 117 | +//! let admin: Address = env.storage().instance().get(&ADMIN).unwrap(); |
| 118 | +//! admin.require_auth(); |
| 119 | +//! env.storage().instance().set(&PAUSED, &true); |
104 | 120 | //! } |
105 | 121 | //! |
106 | 122 | //! fn unpause(env: &Env) { |
107 | | -//! env.storage().instance().remove(&"paused"); |
| 123 | +//! let admin: Address = env.storage().instance().get(&ADMIN).unwrap(); |
| 124 | +//! admin.require_auth(); |
| 125 | +//! env.storage().instance().remove(&PAUSED); |
108 | 126 | //! } |
109 | 127 | //! } |
110 | 128 | //! |
|
116 | 134 | //! impl Pausable for MyContract { |
117 | 135 | //! // Override is_paused with custom logic that returns false when not set |
118 | 136 | //! fn is_paused(env: &Env) -> bool { |
119 | | -//! env.storage().instance().get(&"paused").unwrap_or(false) |
| 137 | +//! env.storage().instance().get(&PAUSED).unwrap_or(false) |
120 | 138 | //! } |
121 | 139 | //! // pause() and unpause() use the default implementations |
122 | 140 | //! } |
123 | 141 | //! |
124 | 142 | //! #[contractimpl] |
125 | 143 | //! impl MyContract { |
| 144 | +//! pub fn __constructor(env: &Env, admin: Address) { |
| 145 | +//! env.storage().instance().set(&ADMIN, &admin); |
| 146 | +//! } |
| 147 | +//! |
126 | 148 | //! pub fn do_something(env: &Env) { |
127 | 149 | //! if Self::is_paused(env) { |
128 | 150 | //! panic!("contract is paused"); |
|
138 | 160 | //! The generated `{TraitName}Client` can be used to call any contract that implements the trait: |
139 | 161 | //! |
140 | 162 | //! ``` |
141 | | -//! use soroban_sdk::{contract, contractimpl, contracttrait, Env}; |
| 163 | +//! use soroban_sdk::{contract, contractimpl, contracttrait, Address, Env}; |
| 164 | +//! |
| 165 | +//! const ADMIN: &str = "admin"; |
| 166 | +//! const PAUSED: &str = "paused"; |
142 | 167 | //! |
143 | 168 | //! // Define a trait with default implementations |
144 | 169 | //! #[contracttrait] |
145 | 170 | //! pub trait Pausable { |
146 | 171 | //! fn is_paused(env: &Env) -> bool { |
147 | | -//! env.storage().instance().has(&"paused") |
| 172 | +//! env.storage().instance().has(&PAUSED) |
148 | 173 | //! } |
149 | 174 | //! |
150 | 175 | //! fn pause(env: &Env) { |
151 | | -//! env.storage().instance().set(&"paused", &true); |
| 176 | +//! let admin: Address = env.storage().instance().get(&ADMIN).unwrap(); |
| 177 | +//! admin.require_auth(); |
| 178 | +//! env.storage().instance().set(&PAUSED, &true); |
152 | 179 | //! } |
153 | 180 | //! |
154 | 181 | //! fn unpause(env: &Env) { |
155 | | -//! env.storage().instance().remove(&"paused"); |
| 182 | +//! let admin: Address = env.storage().instance().get(&ADMIN).unwrap(); |
| 183 | +//! admin.require_auth(); |
| 184 | +//! env.storage().instance().remove(&PAUSED); |
156 | 185 | //! } |
157 | 186 | //! } |
158 | 187 | //! |
|
165 | 194 | //! |
166 | 195 | //! #[contractimpl] |
167 | 196 | //! impl MyContract { |
| 197 | +//! pub fn __constructor(env: &Env, admin: Address) { |
| 198 | +//! env.storage().instance().set(&ADMIN, &admin); |
| 199 | +//! } |
| 200 | +//! |
168 | 201 | //! pub fn do_something(env: &Env) { |
169 | 202 | //! if Self::is_paused(env) { |
170 | 203 | //! panic!("contract is paused"); |
|
178 | 211 | //! # } |
179 | 212 | //! # #[cfg(feature = "testutils")] |
180 | 213 | //! # fn main() { |
| 214 | +//! use soroban_sdk::testutils::Address as _; |
181 | 215 | //! let env = Env::default(); |
182 | | -//! let contract_id = env.register(MyContract, ()); |
| 216 | +//! env.mock_all_auths(); |
| 217 | +//! let admin = Address::generate(&env); |
| 218 | +//! let contract_id = env.register(MyContract, (&admin,)); |
183 | 219 | //! let client = PausableClient::new(&env, &contract_id); |
184 | 220 | //! |
185 | 221 | //! assert!(!client.is_paused()); |
|
0 commit comments