@@ -96,58 +96,106 @@ Documentation of all methods provided by the derived implementation of `FullAcce
96
96
Allow contracts to implement an emergency stop mechanism that can be triggered by an authorized account. Pauses can be
97
97
used granularly to only limit certain features.
98
98
99
- Contract example using _ Pausable_ plugin. Note that it requires the contract to be Ownable .
99
+ Contract example using _ Pausable_ plugin. Note that it requires the contract to be _ AccessControllable _ .
100
100
101
101
``` rust
102
102
103
+ /// Define roles for access control of `Pausable` features. Accounts which are
104
+ /// granted a role are authorized to execute the corresponding action.
105
+ #[derive(AccessControlRole , Deserialize , Serialize , Copy , Clone )]
106
+ #[serde(crate = " near_sdk::serde" )]
107
+ pub enum Role {
108
+ /// May pause and unpause features.
109
+ PauseManager ,
110
+ /// May call `increase_4` even when it is paused.
111
+ Unrestricted4Increaser ,
112
+ /// May call `decrease_4` even when `increase_4` is not paused.
113
+ Unrestricted4Decreaser ,
114
+ /// May always call both `increase_4` and `decrease_4`.
115
+ Unrestricted4Modifier ,
116
+ }
117
+
118
+ #[access_control(role_type(Role ))]
103
119
#[near_bindgen]
104
- #[derive(Ownable , Pausable )]
120
+ #[derive(Pausable )]
121
+ #[pausable(manager_roles(Role :: PauseManager ))]
105
122
struct Counter {
106
123
counter : u64 ,
107
124
}
108
125
109
126
#[near_bindgen]
110
127
impl Counter {
111
- /// Specify the owner of the contract in the constructor
128
+ /// Initialize access control in the constructor.
112
129
#[init]
113
130
fn new () -> Self {
114
- let mut contract = Self { counter : 0 };
115
- contract . owner_set (Some (near_sdk :: env :: predecessor_account_id ()));
131
+ let mut contract = Self {
132
+ counter : 0 ,
133
+ __acl : Default :: default (),
134
+ };
135
+
136
+ // Make the contract itself access control super admin. This enables
137
+ // granting roles below.
138
+ near_sdk :: require! (
139
+ contract . acl_init_super_admin (near_sdk :: env :: predecessor_account_id ()),
140
+ " Failed to initialize super admin" ,
141
+ );
142
+
143
+ // Grant access control roles.
144
+ let grants : Vec <(Role , near_sdk :: AccountId )> = vec! [
145
+ (Role :: PauseManager , " anna.test" . parse (). unwrap ()),
146
+ (Role :: Unrestricted4Increaser , " brenda.test" . parse (). unwrap ()),
147
+ (Role :: Unrestricted4Decreaser , " chris.test" . parse (). unwrap ()),
148
+ (Role :: Unrestricted4Modifier , " daniel.test" . parse (). unwrap ()),
149
+ ];
150
+ for (role , account_id ) in grants {
151
+ let result = contract . acl_grant_role (role . into (), account_id );
152
+ near_sdk :: require! (Some (true ) == result , " Failed to grant role" );
153
+ }
154
+
116
155
contract
117
156
}
118
157
119
158
/// Function can be paused using feature name "increase_1" or "ALL" like:
120
159
/// `contract.pa_pause_feature("increase_1")` or `contract.pa_pause_feature("ALL")`
121
160
///
122
- /// If the function is paused, all calls to it will fail. Even calls started from owner or self.
161
+ /// If the function is paused, all calls to it will fail. Even calls
162
+ /// initiated by accounts which are access control super admin or role
163
+ /// grantee.
123
164
#[pause]
124
165
fn increase_1 (& mut self ) {
125
166
self . counter += 1 ;
126
167
}
127
168
128
- /// Similar to `#[pause]` but use an explicit name for the feature. In this case the feature to be paused
129
- /// is named "Increase by two". Note that trying to pause it using "increase_2" will not have any effect.
169
+ /// Similar to `#[pause]` but use an explicit name for the feature. In this
170
+ /// case the feature to be paused is named "Increase by two". Note that
171
+ /// trying to pause it using "increase_2" will not have any effect.
130
172
///
131
- /// This can be used to pause a subset of the methods at once without requiring to use "ALL".
173
+ /// This can be used to pause a subset of the methods at once without
174
+ /// requiring to use "ALL".
132
175
#[pause(name = " Increase by two" )]
133
176
fn increase_2 (& mut self ) {
134
177
self . counter += 2 ;
135
178
}
136
179
137
- /// Similar to `#[pause]` but owner or self can still call this method. Any subset of {self, owner} can be specified.
138
- #[pause(except(owner, self))]
180
+ /// Similar to `#[pause]` but roles passed as argument may still
181
+ /// successfully call this method.
182
+ #[pause(except(roles(Role :: Unrestricted4Increaser , Role :: Unrestricted4Modifier )))]
139
183
fn increase_4 (& mut self ) {
140
184
self . counter += 4 ;
141
185
}
142
186
143
- /// This method can only be called when "increase_1" is paused. Use this macro to create escape hatches when some
144
- /// features are paused. Note that if "ALL" is specified the "increase_1" is considered to be paused.
187
+ /// This method can only be called when "increase_1" is paused. Use this
188
+ /// macro to create escape hatches when some features are paused. Note that
189
+ /// if "ALL" is specified the "increase_1" is considered to be paused.
145
190
#[if_paused(name = " increase_1" )]
146
191
fn decrease_1 (& mut self ) {
147
192
self . counter -= 1 ;
148
193
}
149
194
150
195
/// Custom use of pause features. Only allow increasing the counter using `careful_increase` if it is below 10.
196
+
197
+ /// Custom use of pause features. Only allow increasing the counter using
198
+ /// `careful_increase` if it is below 10.
151
199
fn careful_increase (& mut self ) {
152
200
if self . counter >= 10 {
153
201
assert! (
0 commit comments