@@ -42,31 +42,29 @@ test test::bad_data - should panic ... ok
4242#[derive(Clone )]
4343#[contracttype]
4444pub enum DataKey {
45- Acc (Identifier ),
45+ SavedNum (Identifier ),
4646 Nonce (Identifier ),
4747 Admin ,
4848}
4949
5050fn read_nonce (e : & Env , id : Identifier ) -> BigInt {
5151 let key = DataKey :: Nonce (id );
52- if let Some (nonce ) = e . contract_data (). get (key ) {
53- nonce . unwrap ()
54- } else {
55- BigInt :: zero (e )
56- }
52+ e . contract_data ()
53+ . get (key )
54+ . unwrap_or_else (|| Ok (BigInt :: zero (e )))
55+ . unwrap ()
5756}
58- struct WrappedAuth (Signature );
57+ struct NonceForSignature (Signature );
5958
60- impl NonceAuth for WrappedAuth {
59+ impl NonceAuth for NonceForSignature {
6160 fn read_nonce (e : & Env , id : Identifier ) -> BigInt {
6261 read_nonce (e , id )
6362 }
6463
6564 fn read_and_increment_nonce (& self , e : & Env , id : Identifier ) -> BigInt {
6665 let key = DataKey :: Nonce (id . clone ());
6766 let nonce = Self :: read_nonce (e , id );
68- e . contract_data ()
69- . set (key , nonce . clone () + BigInt :: from_u32 (e , 1 ));
67+ e . contract_data (). set (key , & nonce + 1 );
7068 nonce
7169 }
7270
@@ -75,12 +73,11 @@ impl NonceAuth for WrappedAuth {
7573 }
7674}
7775
78- pub struct AuthContract ;
76+ pub struct ExampleContract ;
7977
80- #[cfg_attr(feature = " export" , contractimpl)]
81- #[cfg_attr(not(feature = " export" ), contractimpl(export = false))]
82- impl AuthContract {
83- // Sets the admin identifier
78+ #[contractimpl]
79+ impl ExampleContract {
80+ /// Set the admin identifier. May be called only once.
8481 pub fn set_admin (e : Env , admin : Identifier ) {
8582 if e . contract_data (). has (DataKey :: Admin ) {
8683 panic! (" admin is already set" )
@@ -89,41 +86,41 @@ impl AuthContract {
8986 e . contract_data (). set (DataKey :: Admin , admin );
9087 }
9188
92- // Saves data that corresponds to an Identifier, with that Identifiers authorization
93- pub fn save_data (e : Env , auth : Signature , nonce : BigInt , num : BigInt ) {
94- let auth_id = auth . get_identifier (& e );
89+ /// Save the number for an authenticated [Identifier].
90+ pub fn save_num (e : Env , sig : Signature , nonce : BigInt , num : BigInt ) {
91+ let auth_id = sig . get_identifier (& e );
9592
9693 check_auth (
9794 & e ,
98- & WrappedAuth ( auth ),
95+ & NonceForSignature ( sig ),
9996 nonce . clone (),
100- Symbol :: from_str ( " save_data " ),
101- (auth_id . clone () , nonce , num . clone () ). into_val (& e ),
97+ symbol! ( " save_num " ),
98+ (& auth_id , nonce , & num ). into_val (& e ),
10299 );
103100
104- e . contract_data (). set (DataKey :: Acc (auth_id ), num );
101+ e . contract_data (). set (DataKey :: SavedNum (auth_id ), num );
105102 }
106103
107104 // The admin can write data for any Identifier
108- pub fn overwrite (e : Env , auth : Signature , nonce : BigInt , id : Identifier , num : BigInt ) {
109- let auth_id = auth . get_identifier (& e );
105+ pub fn overwrite (e : Env , sig : Signature , nonce : BigInt , id : Identifier , num : BigInt ) {
106+ let auth_id = sig . get_identifier (& e );
110107 if auth_id != e . contract_data (). get_unchecked (DataKey :: Admin ). unwrap () {
111108 panic! (" not authorized by admin" )
112109 }
113110
114111 check_auth (
115112 & e ,
116- & WrappedAuth ( auth ),
113+ & NonceForSignature ( sig ),
117114 nonce . clone (),
118- Symbol :: from_str (" overwrite" ),
119- (auth_id , nonce , id . clone (), num . clone () ). into_val (& e ),
115+ symbol! (" overwrite" ),
116+ (auth_id , nonce , & id , & num ). into_val (& e ),
120117 );
121118
122- e . contract_data (). set (DataKey :: Acc (id ), num );
119+ e . contract_data (). set (DataKey :: SavedNum (id ), num );
123120 }
124121
125- pub fn nonce (e : Env , to : Identifier ) -> BigInt {
126- read_nonce (& e , to )
122+ pub fn nonce (e : Env , id : Identifier ) -> BigInt {
123+ read_nonce (& e , id )
127124 }
128125}
129126```
@@ -182,7 +179,7 @@ pub struct AccountSignatures {
182179}
183180```
184181
185- A Stellar account identity can provide authorization by signing an appropripate
182+ A Stellar account identity can provide authorization by signing an appropriate
186183message with the private keys associated with the signers of that Stellar
187184account. The total signing weight of the signers must exceed the medium
188185threshold of that Stellar account. The authorization is a vector, where each
@@ -249,31 +246,30 @@ below that we have a `DataKey` for the nonce tied to an `Identifier`, and this
249246#[derive(Clone )]
250247#[contracttype]
251248pub enum DataKey {
252- Acc (Identifier ),
249+ SavedNum (Identifier ),
253250 Nonce (Identifier ),
254251 Admin ,
255252}
256253
257254fn read_nonce (e : & Env , id : Identifier ) -> BigInt {
258255 let key = DataKey :: Nonce (id );
259- if let Some (nonce ) = e . contract_data (). get (key ) {
260- nonce . unwrap ()
261- } else {
262- BigInt :: zero (e )
263- }
256+ e . contract_data ()
257+ . get (key )
258+ . unwrap_or_else (|| Ok (BigInt :: zero (e )))
259+ . unwrap ()
264260}
265- struct WrappedAuth (Signature );
266261
267- impl NonceAuth for WrappedAuth {
262+ struct NonceForSignature (Signature );
263+
264+ impl NonceAuth for NonceForSignature {
268265 fn read_nonce (e : & Env , id : Identifier ) -> BigInt {
269266 read_nonce (e , id )
270267 }
271268
272269 fn read_and_increment_nonce (& self , e : & Env , id : Identifier ) -> BigInt {
273270 let key = DataKey :: Nonce (id . clone ());
274271 let nonce = Self :: read_nonce (e , id );
275- e . contract_data ()
276- . set (key , nonce . clone () + BigInt :: from_u32 (e , 1 ));
272+ e . contract_data (). set (key , & nonce + 1 );
277273 nonce
278274 }
279275
@@ -284,32 +280,32 @@ impl NonceAuth for WrappedAuth {
284280```
285281
286282### Check authorization in contract function
287- The ` save_data ` function stores data in a ` DataKey::Acc ` tied to an ` Identifier `
283+ The ` save_num ` function stores a number in a ` DataKey::SavedNum ` tied to an ` Identifier `
288284with it's authorization.
289285
290286The ` check_auth ` method in the SDK is used for signature verification, and here
291287are the important authorization takeaways from the example below -
2922881 . The ` nonce ` is included in the list of parameters for the contract function.
293- 2 . The ` Signature ` is passed into ` check_auth ` wrapped in ` WrappedAuth ` .
289+ 2 . The ` Signature ` is passed into ` check_auth ` wrapped in ` NonceForSignature ` .
2942903 . The ` function ` parameter to ` check_auth ` is the name of the invoked function.
2952914 . The last argument passed to ` check_auth ` is a list of arguments that are
296292 expected in the signed payload. The interesting thing to note here is that it
297- includes the ` Identifier ` from the ` auth ` and the nonce.
293+ includes the ` Identifier ` from the ` sig ` and the nonce.
298294
299295``` rust
300- // Saves data that corresponds to an Identifier, with that Identifiers authorization
301- pub fn save_data (e : Env , auth : Signature , nonce : BigInt , num : BigInt ) {
302- let auth_id = auth . get_identifier (& e );
296+ /// Save the number for an authenticated [Identifier].
297+ pub fn save_num (e : Env , sig : Signature , nonce : BigInt , num : BigInt ) {
298+ let auth_id = sig . get_identifier (& e );
303299
304300 check_auth (
305301 & e ,
306- & WrappedAuth ( auth ),
302+ & NonceForSignature ( sig ),
307303 nonce . clone (),
308- Symbol :: from_str ( " save_data " ),
309- (auth_id . clone () , nonce , num . clone () ). into_val (& e ),
304+ symbol! ( " save_num " ),
305+ (& auth_id , nonce , & num ). into_val (& e ),
310306 );
311307
312- e . contract_data (). set (DataKey :: Acc (auth_id ), num );
308+ e . contract_data (). set (DataKey :: SavedNum (auth_id ), num );
313309}
314310```
315311
@@ -329,22 +325,22 @@ pub fn set_admin(e: Env, admin: Identifier) {
329325 e . contract_data (). set (DataKey :: Admin , admin );
330326}
331327
332- // The admin can write data for any Identifier
333- pub fn overwrite (e : Env , auth : Signature , nonce : BigInt , id : Identifier , num : BigInt ) {
334- let auth_id = auth . get_identifier (& e );
328+ // The admin can write the number for any [ Identifier]
329+ pub fn overwrite (e : Env , sig : Signature , nonce : BigInt , id : Identifier , num : BigInt ) {
330+ let auth_id = sig . get_identifier (& e );
335331 if auth_id != e . contract_data (). get_unchecked (DataKey :: Admin ). unwrap () {
336332 panic! (" not authorized by admin" )
337333 }
338334
339335 check_auth (
340336 & e ,
341- & WrappedAuth ( auth ),
337+ & NonceForSignature ( sig ),
342338 nonce . clone (),
343- Symbol :: from_str (" overwrite" ),
344- (auth_id , nonce , id . clone (), num . clone () ). into_val (& e ),
339+ symbol! (" overwrite" ),
340+ (auth_id , nonce , & id , & num ). into_val (& e ),
345341 );
346342
347- e . contract_data (). set (DataKey :: Acc (id ), num );
343+ e . contract_data (). set (DataKey :: SavedNum (id ), num );
348344}
349345```
350346
0 commit comments