# Abstract Contract in Sway

**URL:** <https://forum.fuel.network/t/abstract-contract-in-sway/5114>\
**Category:** Sway\
**Created:** [April 17, 2024, 6:54am UTC](https://forum.fuel.network/t/abstract-contract-in-sway/5114 "2024-04-17T06:54:11Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![cctdaniel](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/cctdaniel/32/2762_2.png) [@cctdaniel](https://forum.fuel.network/u/cctdaniel)\
**Post date:** [April 17, 2024, 6:54am UTC](https://forum.fuel.network/t/abstract-contract-in-sway/5114/1 "2024-04-17T06:54:11Z")

</div>

In Solidity you can do something like:

```auto
abstract contract Contract1 is
    Contract2,
    Contract3
{ ... }

```

and you can call functions in Contract2 or Contract3 directly in Contract1, is there an equivalent way of doing this in Sway and what’s the recommended way to do so? The purpose behind doing so is mainly for code reusability and modularity. I’ve searched the Sway Book beforehand but wasn’t able to find a solution, the closest one I could find was `Traits` but not sure if that’s the recommended way, would appreciate it if I can get some tips here, thanks!

---

<div class="post-metadata">

**Author:** ![nick](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/nick/32/2330_2.png) [@nick](https://forum.fuel.network/u/nick)\
**Post date:** [April 17, 2024, 8:20am UTC](https://forum.fuel.network/t/abstract-contract-in-sway/5114/2 "2024-04-17T08:20:01Z")

</div>

You can see in this token example, the use of multiple imported interfaces with a single smart contract.

In this example, you have an ABI contract interface being defined in addition to some other imported interfaces.

```auto
// ERC1155 equivalent in Sway.
contract;

use src5::{SRC5, State, AccessError};
use src20::SRC20;
use src3::SRC3;
use std::{
    asset::{
        burn,
        mint_to,
    },
    call_frames::{
        contract_id,
        msg_asset_id,
    },
    hash::{
        Hash,
    },
    context::this_balance,
    storage::storage_string::*,
    string::String
};

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 {},
    owner: State = State::Uninitialized,
}

abi MultiAsset {
    #[storage(read, write)]
    fn constructor(owner_: Identity);
    
    #[storage(read, write)]
    fn set_name(asset: AssetId, name: String);

    #[storage(read, write)]
    fn set_symbol(asset: AssetId, symbol: String);

    #[storage(read, write)]
    fn set_decimals(asset: AssetId, decimals: u8);
}

impl MultiAsset for Contract {
    #[storage(read, write)]
    fn constructor(owner_: Identity) {
        require(storage.owner.read() == State::Uninitialized, "owner-initialized");
        storage.owner.write(State::Initialized(owner_));
    }
    
    #[storage(read, write)]
    fn set_name(asset: AssetId, name: String) {
        require_access_owner();
        storage.name.insert(asset, StorageString {});
        storage.name.get(asset).write_slice(name);
    }

    #[storage(read, write)]
    fn set_symbol(asset: AssetId, symbol: String) {
        require_access_owner();
        storage.symbol.insert(asset, StorageString {});
        storage.symbol.get(asset).write_slice(symbol);
    }

    #[storage(read, write)]
    fn set_decimals(asset: AssetId, decimals: u8) {
        require_access_owner();
        storage.decimals.insert(asset, decimals);
    }
}

#[storage(read)]
fn require_access_owner() {
    require(
        storage.owner.read() == State::Initialized(msg_sender().unwrap()),
        AccessError::NotOwner,
    );
}

impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        storage.name.get(asset).read_slice()
    }
    
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        storage.symbol.get(asset).read_slice()
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        storage.decimals.get(asset).try_read()
    }
}

impl SRC3 for Contract {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: SubId, amount: u64) {
        require_access_owner();
        let asset_id = AssetId::new(contract_id(), sub_id);
        let supply = storage.total_supply.get(asset_id).try_read();
        if supply.is_none() {
            storage.total_assets.write(storage.total_assets.try_read().unwrap_or(0) + 1);
        }
        let current_supply = supply.unwrap_or(0);
        storage.total_supply.insert(asset_id, current_supply + amount);
        mint_to(recipient, sub_id, amount);
    }
    
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        require_access_owner();
        let asset_id = AssetId::new(contract_id(), sub_id);
        require(this_balance(asset_id) >= amount, "not-enough-coins");
        
        let supply = storage.total_supply.get(asset_id).try_read();
        let current_supply = supply.unwrap_or(0);
        storage.total_supply.insert(asset_id, current_supply - amount);
        burn(sub_id, amount);
    }
}

```
