@@ -80,7 +80,7 @@ pub use TokenClient as Client;
8080/// There are no functions in the token interface for minting tokens. Minting is
8181/// an administrative function that can differ significantly from one token to
8282/// the next.
83- #[ contractspecfn( name = "StellarAssetSpec " , export = false ) ]
83+ #[ contractspecfn( name = "TokenSpec " , export = false ) ]
8484#[ contractclient( crate_path = "crate" , name = "TokenClient" ) ]
8585pub trait TokenInterface {
8686 /// Returns the allowance for `spender` to transfer from `from`.
@@ -230,11 +230,205 @@ pub trait TokenInterface {
230230 fn symbol ( env : Env ) -> String ;
231231}
232232
233+ /// Spec contains the contract spec of Token contracts.
234+ #[ doc( hidden) ]
235+ pub struct TokenSpec ;
236+
237+ pub ( crate ) const TOKEN_SPEC_XDR_INPUT : & [ & [ u8 ] ] = & [
238+ & TokenSpec :: spec_xdr_allowance ( ) ,
239+ & TokenSpec :: spec_xdr_approve ( ) ,
240+ & TokenSpec :: spec_xdr_balance ( ) ,
241+ & TokenSpec :: spec_xdr_burn ( ) ,
242+ & TokenSpec :: spec_xdr_burn_from ( ) ,
243+ & TokenSpec :: spec_xdr_decimals ( ) ,
244+ & TokenSpec :: spec_xdr_name ( ) ,
245+ & TokenSpec :: spec_xdr_symbol ( ) ,
246+ & TokenSpec :: spec_xdr_transfer ( ) ,
247+ & TokenSpec :: spec_xdr_transfer_from ( ) ,
248+ ] ;
249+
250+ pub ( crate ) const TOKEN_SPEC_XDR_LEN : usize = 4716 ;
251+
252+ impl TokenSpec {
253+ /// Returns the XDR spec for the Token contract.
254+ pub const fn spec_xdr ( ) -> [ u8 ; TOKEN_SPEC_XDR_LEN ] {
255+ let input = TOKEN_SPEC_XDR_INPUT ;
256+ // Concatenate all XDR for each item that makes up the token spec.
257+ let mut output = [ 0u8 ; TOKEN_SPEC_XDR_LEN ] ;
258+ let mut input_i = 0 ;
259+ let mut output_i = 0 ;
260+ while input_i < input. len ( ) {
261+ let subinput = input[ input_i] ;
262+ let mut subinput_i = 0 ;
263+ while subinput_i < subinput. len ( ) {
264+ output[ output_i] = subinput[ subinput_i] ;
265+ output_i += 1 ;
266+ subinput_i += 1 ;
267+ }
268+ input_i += 1 ;
269+ }
270+
271+ // Check that the numbers of bytes written is equal to the number of bytes
272+ // expected in the output.
273+ if output_i != output. len ( ) {
274+ panic ! ( "unexpected output length" , ) ;
275+ }
276+
277+ output
278+ }
279+ }
280+
233281/// Interface for admin capabilities for Token contracts, such as the Stellar
234282/// Asset Contract.
235283#[ contractspecfn( name = "StellarAssetSpec" , export = false ) ]
236284#[ contractclient( crate_path = "crate" , name = "StellarAssetClient" ) ]
237285pub trait StellarAssetInterface {
286+ /// Returns the allowance for `spender` to transfer from `from`.
287+ ///
288+ /// The amount returned is the amount that spender is allowed to transfer
289+ /// out of from's balance. When the spender transfers amounts, the allowance
290+ /// will be reduced by the amount transferred.
291+ ///
292+ /// # Arguments
293+ ///
294+ /// * `from` - The address holding the balance of tokens to be drawn from.
295+ /// * `spender` - The address spending the tokens held by `from`.
296+ fn allowance ( env : Env , from : Address , spender : Address ) -> i128 ;
297+
298+ /// Set the allowance by `amount` for `spender` to transfer/burn from
299+ /// `from`.
300+ ///
301+ /// The amount set is the amount that spender is approved to transfer out of
302+ /// from's balance. The spender will be allowed to transfer amounts, and
303+ /// when an amount is transferred the allowance will be reduced by the
304+ /// amount transferred.
305+ ///
306+ /// # Arguments
307+ ///
308+ /// * `from` - The address holding the balance of tokens to be drawn from.
309+ /// * `spender` - The address being authorized to spend the tokens held by
310+ /// `from`.
311+ /// * `amount` - The tokens to be made available to `spender`.
312+ /// * `expiration_ledger` - The ledger number where this allowance expires. Cannot
313+ /// be less than the current ledger number unless the amount is being set to 0.
314+ /// An expired entry (where expiration_ledger < the current ledger number)
315+ /// should be treated as a 0 amount allowance.
316+ ///
317+ /// # Events
318+ ///
319+ /// Emits an event with topics `["approve", from: Address,
320+ /// spender: Address], data = [amount: i128, expiration_ledger: u32]`
321+ fn approve ( env : Env , from : Address , spender : Address , amount : i128 , expiration_ledger : u32 ) ;
322+
323+ /// Returns the balance of `id`.
324+ ///
325+ /// # Arguments
326+ ///
327+ /// * `id` - The address for which a balance is being queried. If the
328+ /// address has no existing balance, returns 0.
329+ fn balance ( env : Env , id : Address ) -> i128 ;
330+
331+ /// Transfer `amount` from `from` to `to`.
332+ ///
333+ /// # Arguments
334+ ///
335+ /// * `from` - The address holding the balance of tokens which will be
336+ /// withdrawn from.
337+ /// * `to` - The address which will receive the transferred tokens.
338+ /// * `amount` - The amount of tokens to be transferred.
339+ ///
340+ /// # Events
341+ ///
342+ /// Emits an event with topics `["transfer", from: Address, to: Address],
343+ /// data = amount: i128`
344+ fn transfer ( env : Env , from : Address , to : Address , amount : i128 ) ;
345+
346+ /// Transfer `amount` from `from` to `to`, consuming the allowance that
347+ /// `spender` has on `from`'s balance. Authorized by spender
348+ /// (`spender.require_auth()`).
349+ ///
350+ /// The spender will be allowed to transfer the amount from from's balance
351+ /// if the amount is less than or equal to the allowance that the spender
352+ /// has on the from's balance. The spender's allowance on from's balance
353+ /// will be reduced by the amount.
354+ ///
355+ /// # Arguments
356+ ///
357+ /// * `spender` - The address authorizing the transfer, and having its
358+ /// allowance consumed during the transfer.
359+ /// * `from` - The address holding the balance of tokens which will be
360+ /// withdrawn from.
361+ /// * `to` - The address which will receive the transferred tokens.
362+ /// * `amount` - The amount of tokens to be transferred.
363+ ///
364+ /// # Events
365+ ///
366+ /// Emits an event with topics `["transfer", from: Address, to: Address],
367+ /// data = amount: i128`
368+ fn transfer_from ( env : Env , spender : Address , from : Address , to : Address , amount : i128 ) ;
369+
370+ /// Burn `amount` from `from`.
371+ ///
372+ /// Reduces from's balance by the amount, without transferring the balance
373+ /// to another holder's balance.
374+ ///
375+ /// # Arguments
376+ ///
377+ /// * `from` - The address holding the balance of tokens which will be
378+ /// burned from.
379+ /// * `amount` - The amount of tokens to be burned.
380+ ///
381+ /// # Events
382+ ///
383+ /// Emits an event with topics `["burn", from: Address], data = amount:
384+ /// i128`
385+ fn burn ( env : Env , from : Address , amount : i128 ) ;
386+
387+ /// Burn `amount` from `from`, consuming the allowance of `spender`.
388+ ///
389+ /// Reduces from's balance by the amount, without transferring the balance
390+ /// to another holder's balance.
391+ ///
392+ /// The spender will be allowed to burn the amount from from's balance, if
393+ /// the amount is less than or equal to the allowance that the spender has
394+ /// on the from's balance. The spender's allowance on from's balance will be
395+ /// reduced by the amount.
396+ ///
397+ /// # Arguments
398+ ///
399+ /// * `spender` - The address authorizing the burn, and having its allowance
400+ /// consumed during the burn.
401+ /// * `from` - The address holding the balance of tokens which will be
402+ /// burned from.
403+ /// * `amount` - The amount of tokens to be burned.
404+ ///
405+ /// # Events
406+ ///
407+ /// Emits an event with topics `["burn", from: Address], data = amount:
408+ /// i128`
409+ fn burn_from ( env : Env , spender : Address , from : Address , amount : i128 ) ;
410+
411+ /// Returns the number of decimals used to represent amounts of this token.
412+ ///
413+ /// # Panics
414+ ///
415+ /// If the contract has not yet been initialized.
416+ fn decimals ( env : Env ) -> u32 ;
417+
418+ /// Returns the name for this token.
419+ ///
420+ /// # Panics
421+ ///
422+ /// If the contract has not yet been initialized.
423+ fn name ( env : Env ) -> String ;
424+
425+ /// Returns the symbol for this token.
426+ ///
427+ /// # Panics
428+ ///
429+ /// If the contract has not yet been initialized.
430+ fn symbol ( env : Env ) -> String ;
431+
238432 /// Sets the administrator to the specified address `new_admin`.
239433 ///
240434 /// # Arguments
@@ -305,13 +499,13 @@ pub trait StellarAssetInterface {
305499 fn clawback ( env : Env , from : Address , amount : i128 ) ;
306500}
307501
308- /// Spec contains the contract spec of Token contracts, including the general
309- /// interface, as well as the admin interface, such as the Stellar Asset
310- /// Contract.
502+ /// Spec contains the contract spec of the Stellar Asset Contract.
503+ ///
504+ /// The Stellar Asset Contract is a superset of the Token Contract.
311505#[ doc( hidden) ]
312506pub struct StellarAssetSpec ;
313507
314- pub ( crate ) const SPEC_XDR_INPUT : & [ & [ u8 ] ] = & [
508+ pub ( crate ) const STELLAR_ASSET_SPEC_XDR_INPUT : & [ & [ u8 ] ] = & [
315509 & StellarAssetSpec :: spec_xdr_allowance ( ) ,
316510 & StellarAssetSpec :: spec_xdr_authorized ( ) ,
317511 & StellarAssetSpec :: spec_xdr_approve ( ) ,
@@ -330,14 +524,14 @@ pub(crate) const SPEC_XDR_INPUT: &[&[u8]] = &[
330524 & StellarAssetSpec :: spec_xdr_transfer_from ( ) ,
331525] ;
332526
333- pub ( crate ) const SPEC_XDR_LEN : usize = 6456 ;
527+ pub ( crate ) const STELLAR_ASSET_SPEC_XDR_LEN : usize = 6456 ;
334528
335529impl StellarAssetSpec {
336530 /// Returns the XDR spec for the Token contract.
337- pub const fn spec_xdr ( ) -> [ u8 ; SPEC_XDR_LEN ] {
338- let input = SPEC_XDR_INPUT ;
531+ pub const fn spec_xdr ( ) -> [ u8 ; STELLAR_ASSET_SPEC_XDR_LEN ] {
532+ let input = STELLAR_ASSET_SPEC_XDR_INPUT ;
339533 // Concatenate all XDR for each item that makes up the token spec.
340- let mut output = [ 0u8 ; SPEC_XDR_LEN ] ;
534+ let mut output = [ 0u8 ; STELLAR_ASSET_SPEC_XDR_LEN ] ;
341535 let mut input_i = 0 ;
342536 let mut output_i = 0 ;
343537 while input_i < input. len ( ) {
0 commit comments