# Base Functionality

For implementation details on the Asset Library base functionality please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/asset/asset/base/index.html).

## Importing the Asset Library Base Functionality

In order to use base functionality the Asset Library, the Asset Library and the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Asset Library and the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add asset@0.26.0
forc add src20@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Asset Library Base Functionality and [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use asset::base::*;
use src20::*;
```

## Integration with the SRC-20 Standard

The [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) definition states that the following abi implementation is required for any Native Asset on Fuel:

```sway
abi SRC20 {
    #[storage(read)]
    fn total_assets() -> u64;
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64>;
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String>;
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String>;
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8>;
}
```

The Asset Library has the following complimentary functions for each function in the `SRC20` abi:

- `_total_assets()`
- `_total_supply()`
- `_name()`
- `_symbol()`
- `_decimals()`

The following ABI and functions are also provided to set your [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard storage values:

```sway
abi SetAssetAttributes {
    #[storage(write)]
    fn set_name(asset: AssetId, name: String);
    #[storage(write)]
    fn set_symbol(asset: AssetId, symbol: String);
    #[storage(write)]
    fn set_decimals(asset: AssetId, decimals: u8);
}
```

- `_set_name()`
- `_set_symbol()`
- `_set_decimals()`

> **NOTE** The `_set_name()`, `_set_symbol()`, and `_set_decimals()` functions will set the attributes of an asset *unconditionally*. External checks should be applied to restrict the setting of attributes.

## Setting Up Storage

Once imported, the Asset Library's base functionality should be available. To use them, be sure to add the storage block below to your contract which enables the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard.

```sway
storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}
```

## Implementing the SRC-20 Standard with the Asset Library

To use the Asset Library's base functionly, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard in combination with the Asset Library with no user defined restrictions or custom functionality.

```sway
use asset::base::{_decimals, _name, _symbol, _total_assets, _total_supply};
use src20::SRC20;
use std::{hash::Hash, storage::storage_string::*, string::String};

// The SRC-20 storage block
storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

// Implement the SRC-20 Standard for this contract
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        // Pass the `total_assets` StorageKey to `_total_assets()` from the Asset Library.
        _total_assets(storage.total_assets)
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        // Pass the `total_supply` StorageKey to `_total_supply()` from the Asset Library.
        _total_supply(storage.total_supply, asset)
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        // Pass the `name` StorageKey to `_name_()` from the Asset Library.
        _name(storage.name, asset)
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        // Pass the `symbol` StorageKey to `_symbol_()` function from the Asset Library.
        _symbol(storage.symbol, asset)
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        // Pass the `decimals` StorageKey to `_decimals_()` function from the Asset Library.
        _decimals(storage.decimals, asset)
    }
}
```

## Setting an Asset's SRC-20 Attributes

To set some the asset attributes for an Asset, use the `SetAssetAttributes` ABI provided by the Asset Library. The example below shows the implementation of the `SetAssetAttributes` ABI with no user defined restrictions or custom functionality. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetAttributes` ABI to ensure only a single user has permissions to set an Asset's attributes.

The `_set_name()`, `_set_symbol()`, and `_set_decimals()` functions follows the SRC-20 standard for logging and will emit their respective log when called.

```sway
use asset::base::*;
use std::{hash::Hash, storage::storage_string::*, string::String};

storage {
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SetAssetAttributes for Contract {
    #[storage(write)]
    fn set_name(asset: AssetId, name: String) {
        _set_name(storage.name, asset, name);
    }

    #[storage(write)]
    fn set_symbol(asset: AssetId, symbol: String) {
        _set_symbol(storage.symbol, asset, symbol);
    }

    #[storage(write)]
    fn set_decimals(asset: AssetId, decimals: u8) {
        _set_decimals(storage.decimals, asset, decimals);
    }
}
```

> **NOTE** The `_set_name()`, `_set_symbol()`, and `_set_decimals()` functions will set the attributes of an asset *unconditionally*. External checks should be applied to restrict the setting of attributes.
