# Cairo Components

**URL:** https://community.starknet.io/t/cairo-components/101136
**Category:** Cairo Development
**Created:** [September 27, 2023, 11:17am UTC](https://community.starknet.io/t/cairo-components/101136 "2023-09-27T11:17:55Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![FeedTheFed](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/feedthefed/32/72981_2.png) [@FeedTheFed](https://community.starknet.io/u/FeedTheFed)
#### Post date: [September 27, 2023, 11:17am UTC](https://community.starknet.io/t/cairo-components/101136/1 "2023-09-27T11:17:55Z")

</div>

# Components

- [Intro](https://community.starknet.io/t/cairo-components/101136#intro-2)
- [Writing a component](https://community.starknet.io/t/cairo-components/101136#writing-a-component-3)
  - [The component module](https://community.starknet.io/t/cairo-components/101136#the-component-module-4)
  - [ComponentState vs. ContractState](https://community.starknet.io/t/cairo-components/101136#componentstate-vs-contractstate-5)
  - [Exposing the component’s logic](https://community.starknet.io/t/cairo-components/101136#exposing-the-components-logic-6)

- [Using a component in a contract](https://community.starknet.io/t/cairo-components/101136#using-a-component-in-a-contract-7)
- [Component dependencies](https://community.starknet.io/t/cairo-components/101136#component-dependencies-8)
  - [Adding a dependency on OwnableTrait to the Upgradable component](https://community.starknet.io/t/cairo-components/101136#adding-a-dependency-on-ownabletrait-to-the-upgradable-component-9)
  - [Implementing OwnableTrait in the contract](https://community.starknet.io/t/cairo-components/101136#implementing-ownabletraitcontractstate-in-the-contract-using-the-component-10)

- [Appendix - exposing the component logic, what happens under the hood](https://community.starknet.io/t/cairo-components/101136#appendix-exposing-the-component-logic-what-happens-under-the-hood-11)

## Intro

Components are a way to achieve extensibility - enriching my contract’s functionality (storage, events, and external functions) with a module that a third party wrote. Let’s consider the following simple contract maintaining a `u128` counter:

```auto

#[starknet::interface]
trait ICounterContract<TContractState> {
    fn increase_counter(ref self: TContractState, amount: u128);
    fn decrease_counter(ref self: TContractState, amount: u128);
    fn get_counter(self: @TContractState) -> u128;
}

#[starknet::contract]
mod counter_contract {

    #[storage]
    struct Storage {
        counter: u128,
    }

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        CounterIncreased: CounterIncreased,
        CounterDecreased: CounterDecreased
    }

    #[derive(Drop, starknet::Event)]
    struct CounterIncreased {
        amount: u128
    }

    #[derive(Drop, starknet::Event)]
    struct CounterDecreased {
        amount: u128
    }

    #[constructor]
    fn constructor(ref self: ContractState, initial_counter: u128) {
        self.counter.write(initial_counter);
    }

    #[external(v0)]
    impl CounterContract of super::ICounterContract<ContractState> {
        fn get_counter(self: @ContractState) -> u128 {
            self.counter.read()
        }

        fn increase_counter(ref self: ContractState, amount: u128) {
            let current = self.counter.read();
            self.counter.write(current + amount);
            self.emit(CounterIncreased { amount });
        }

        fn decrease_counter(ref self: ContractState, amount: u128) {
            let current = self.counter.read();
            self.counter.write(current - amount);
            self.emit(CounterDecreased { amount });
        }
    }
}

```

Suppose that we now want to be able to upgrade this contract. Ideally, we won’t have to write the upgradability-related logic ourselves. That’s where components come in. A component is a separate module that can contain storage, events, and external functions. Unlike a contract, a component cannot be declared or deployed. Its logic will eventually be part of your contract’s bytecode.

## Writing a Component

Now that we know what to expect, let’s examine the following (simplified) upgradability component:

```auto
// upgradable.cairo

#[starknet::interface]
trait IUpgradable<TContractState> {
    fn upgrade(ref self: TContractState, new_class_hash: ClassHash);
}

#[starknet::component]
mod upgradable {
    use starknet::ClassHash;
    use starknet::syscalls::replace_class_syscall;

    #[storage]
    struct Storage {
        current_implementation: ClassHash
    }

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        ContractUpgraded: ContractUpgraded
    }

    #[derive(Drop, starknet::Event)]
    struct ContractUpgraded {
        old_class_hash: ClassHash,
        new_class_hash: ClassHash
    }

    #[embeddable_as(UpgradableImpl)]
    impl Upgradable<
        TContractState, +HasComponent<TContractState>
    > of super::IUpgradable<ComponentState<TContractState>> {
        fn upgrade(ref self: ComponentState<TContractState>, new_class_hash: ClassHash) {
            replace_class_syscall(new_class_hash).unwrap();
            let old_class_hash = self.current_implementation.read();
            self.emit(ContractUpgraded { old_class_hash, new_class_hash });
            self.current_implementation.write(new_class_hash);
        }
    }
}

```

Let’s examine what’s special in the above code:

### The component module

The component lives in its own module, annotated with the `#[starknet::component]` attribute. Inside the component, the general structure is very similar to that of a regular contract. We see the `Storage` struct and the `Event` enum, followed by the component’s logic.

### ComponentState vs. ContractState

One of the major differences from a regular smart contract is that access to storage and events is done via the generic `ComponentState<TContractState>` type and not `ContractState`. Note that while the type is different, accessing storage or emitting events is done similarly via `self.storage_var_name.read()` or `self.emit(...)`.

### Exposing the component’s logic

To expose the component’s logic, in a way that will add external functions to the using contract, we need to implement a `#[starknet::interface]` trait and mark the impl with `[embeddable_as(<name>)]`, `<name>` is the name that we’ll be using in the contract. The functions in the impl expect the argument `ref self: ComponentState<TContractState>` (for external functions) or `self: @ComponentState<TContractState>` (for view functions), which makes the impl generic over `TContractState`. To see why we need a dependency over the `HasComponent` trait, see the [appendix](https://community.starknet.io/t/cairo-components/101136#appendix-exposing-the-component-logic-what-happens-under-the-hood-11).

## Using a component in a contract

We will now see how to use the upgradability component in our counter contract.

For completeness, this is our project hierarchy, which we’re building by running `scarb build`:

```auto
comp_examples
	src
		lib.cairo
		upgradable.cairo
		counter_contract.cairo
	scarb.toml

```

```auto
// counter_contract.cairo

#[starknet::interface]
trait ICounterContract<TContractState> {
    fn increase_counter(ref self: TContractState, amount: u128);
    fn decrease_counter(ref self: TContractState, amount: u128);
    fn get_counter(self: @TContractState) -> u128;
}

#[starknet::contract]
mod counter_contract {
	  use comp_examples::upgradable::upgradable as upgradable_component;

    component!(path: upgradable_component, storage: upgradable, event: UpgradableEvent);

		#[abi(embed_v0)]
    impl Upgradable = upgradable_component::UpgradableImpl<ContractState>;

    #[storage]
    struct Storage {
        counter: u128,
        #[substorage(v0)]
        upgradable: upgradable_component::Storage
    }

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        CounterIncreased: CounterIncreased,
        CounterDecreased: CounterDecreased,
        UpgradableEvent: upgradable_component::Event
    }

    #[derive(Drop, starknet::Event)]
    struct CounterIncreased {
        amount: u128
    }

    #[derive(Drop, starknet::Event)]
    struct CounterDecreased {
        amount: u128
    }

    #[constructor]
    fn constructor(ref self: ContractState, initial_counter: u128) {
        self.counter.write(initial_counter);
    }

    #[external(v0)]
    impl CounterContract of super::ICounterContract<ContractState> {
        fn get_counter(self: @ContractState) -> u128 {
            self.counter.read()
        }

        fn increase_counter(ref self: ContractState, amount: u128) {
            let current = self.counter.read();
            self.counter.write(current + amount);
            self.emit(CounterIncreased { amount });
        }

        fn decrease_counter(ref self: ContractState, amount: u128) {
            let current = self.counter.read();
            self.counter.write(current - amount);
            self.emit(CounterDecreased { amount });
        }
    }
}

```

We can summarize the changes to the contract in three steps:

- Declaring the component with:

```auto
component!(path: upgradable_component, storage: upgradable, event: UpgradableEvent);

```

This tells the compiler to generate an implementation for `HasComponent<TContractState>`, constructing the component state from the associated storage and event types.

- Add the component’s storage and events to the `Storage` and `Event` types:

```auto
// Add to Storage	
#[substorage(v0)]
upgradable: upgradable_component::Storage

```

```auto
// Add to Event
UpgradableEvent: upgradable_component::Event

```

Note that if the component does not emit any events, the compiler generates an empty Event enum inside the component module, so the above line still applies.

- embed `UpgradableImpl`:

```auto
#[abi(embed_v0)]
impl Upgradable = upgradable_component::UpgradableImpl<ContractSate>;

```

These lines instantiate `UpgradableImpl` from the upgradable component with the concrete `ContractState` type, and externalizes (each function in the impl is now accessible externally, and the impl/interface are reflected in the ABI). For more details on how exactly this works, see the appendix.

## Component dependencies

Suppose now that we want to add ownership to the counter contract, in a way that only allows the owner to initiate an upgrade. One way to do it is adding an owner to the storage of `Upgradable`, resulting in a new component that provides both upgradability and ownership. However, this solution will not allow sharing this owner between different usecases. Suppose that I want to define an owner that controls both upgradability and increasing/decreasing the counter.

Below we only present a single example of dependencies, to get a better idea of the potential composition you can do, you can look at two additional examples in [this repository](https://github.com/ArielElp/component-examples).

### Adding a dependency on OwnableTrait to the Upgradable component

```auto
#[starknet::interface]
trait IUpgradable<TContractState> {
    fn upgrade(ref self: TContractState, new_class_hash: ClassHash);
}

trait OwnableTrait<TContractState> {
    fn is_owner(self: @TContractState, address: ContractAddress) -> bool;
}

#[starknet::component]
mod upgradable {
    use starknet::{ClassHash, get_caller_address};
    use starknet::syscalls::replace_class_syscall;

    #[storage]
    struct Storage {
        current_implementation: ClassHash
    }

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        ContractUpgraded: ContractUpgraded
    }

    #[derive(Drop, starknet::Event)]
    struct ContractUpgraded {
        old_class_hash: ClassHash,
        new_class_hash: ClassHash
    }

    #[embeddable_as(UpgradableImpl)]
    impl Upgradable<
        TContractState, +HasComponent<TContractState>, +OwnableTrait<TContractstate>
    > of super::IUpgradable<ComponentState<TContractState>> {
	        fn upgrade(ref self: ComponentState<TContractState>, new_class_hash: ClassHash) {
			let is_owner = self.get_contract().is_owner(get_caller_address());
			if is_owner {
				replace_class_syscall(new_class_hash).unwrap();
				let old_class_hash = self.current_implementation.read();
				self.emit(ContractUpgraded { old_class_hash, new_class_hash });
				self.current_implementation.write(new_class_hash);
			}
		}
	}
}

```

Recall that the `HasComponent` (see the appendix) trait allows us to move from `ComponentState<TContractState>` back to the generic `TContractState` (which we consider the state of the contract using the component) via the `get_contract` function. By “moving up” to the using contract, it is sufficient to add a generic impl dependency `+OwnableTrait<TContractstate>`. Note that we gain dependencies for free from the standard generic impl mechanism.

Adding this dependency made `Upgradable` pluggable only into contracts that implement the `OwnableTrait` trait. They can do it via implementing it directly or by using an Ownable component, from the perspective of the Upgradable component - this is an implementation detail.

### Implementing OwnableTrait in the contract using the component

In the code below, we chose to implement `OwnableTrait` inside our counter contract directly (rather than via a second component).

```auto
#[starknet::interface]
trait ICounterContract<TContractState> {
    fn increase_counter(ref self: TContractState, amount: u128);
    fn decrease_counter(ref self: TContractState, amount: u128);
    fn get_counter(self: @TContractState) -> u128;
}

#[starknet::contract]
mod counter_contract {
	  use comp_examples::upgradable::upgradable as upgradable_component;

    component!(path: upgradable_component, storage: upgradable, event: UpgradableEvent);

    #[abi(embed_v0)]
    impl Upgradable = upgradable_component::UpgradableImpl<ContractState>;

    impl Ownable of super::OwnableTrait<ContractState> {
        fn is_owner(self: @ContractState, address: ContractAddress) -> bool {
            let caller = get_caller_address();
            let owner = self.owner_address.read();
            caller == owner
        }
    }

    #[storage]
    struct Storage {
        counter: u128,
        #[substorage(v0)]
        upgradable: upgradable_component::Storage
    }

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        CounterIncreased: CounterIncreased,
        CounterDecreased: CounterDecreased,
        UpgradableEvent: upgradable_component::Event
    }

    #[derive(Drop, starknet::Event)]
    struct CounterIncreased {
        amount: u128
    }

    #[derive(Drop, starknet::Event)]
    struct CounterDecreased {
        amount: u128
    }

    #[constructor]
    fn constructor(ref self: ContractState, initial_counter: u128) {
        self.counter.write(initial_counter);
    }

    #[external(v0)]
    impl CounterContract of super::ICounterContract<ContractState> {
        fn get_counter(self: @ContractState) -> u128 {
            self.counter.read()
        }

        fn increase_counter(ref self: ContractState, amount: u128) {
            let is_owner = self.is_owner(get_caller_address());
            if is_owner {
                let current = self.counter.read();
                self.counter.write(current + amount);
                self.emit(CounterIncreased { amount });
            }
        }

        fn decrease_counter(ref self: ContractState, amount: u128) {
            let is_owner = self.is_owner(get_caller_address());
            if is_owner {
                let current = self.counter.read();
                self.counter.write(current - amount);
                self.emit(CounterDecreased { amount });
            }
        }
    }
}

```

Note that if we remove the `Ownable` impl, then the following line will not compile:

```auto
    impl Upgradable = upgradable_component::UpgradableImpl<ContractState>;

```

since we cannot instantiate the impl `UpgradableImpl<ContractState>` if there is no present impl for `OwnableTrait<ContractState>` (and in particular, we won’t be able to embed this impl in our contract).

## Appendix - exposing the component logic, what happens under the hood

The purpose of this section is to explain what exactly is going on in the compiler in the following lines:

```auto
#[embeddable_as(UpgradableImpl)]
impl Upgradable<
    TContractState, +HasComponent<TContractState>
> of super::IUpgradable<ComponentState<TContractState>> {
    fn upgrade(ref self: ComponentState<TContractState>, new_class_hash: ClassHash) {
			...
    }
}

```

If you only want to start playing with components, you can skip this part. If, however, you want to understand the exact role of every single line, we suggest that you continue reading.

Before we zoom into the `Upgradable` impl, we need to discuss embeddable impls, a new feature introduced in Cairo v2.3.0. An `impl` of a starknet interface trait (that is, a trait annotated with the `#[starknet::interface]` attribute) can be embeddable. One can embed embeddable impls in any contract, consequently adding new entry points and changing the ABI. Let’s consider the following example (which is not using components):

```auto
#[starknet::interface]
trait SimpleTrait<TContractState> {
    fn ret_4(self: @TContractState) -> u8;
}

#[starknet::embeddable]
impl SimpleImpl<TContractState> of SimpleTrait<TContractState> {
    fn ret_4(self: @TContractState) -> u8 {
        4
    }
}

#[starknet::contract]
mod simple_contract {
    #[storage]
    struct Storage {}

    #[abi(embed_v0)]
    impl MySimpleImpl = super::SimpleImpl<ContractState>;
}

```

The ABI of the above simple contract is:

```json
{
	"abi": [
	    {
	      "type": "impl",
	      "name": "SimpleImpl",
	      "interface_name": "simple_contract::simple_contract::SimpleTrait"
	    },
	    {
	      "type": "interface",
	      "name": "simple_contract::simple_contract::SimpleTrait",
	      "items": [
	        {
	          "type": "function",
	          "name": "ret_4",
	          "inputs": [],
	          "outputs": [
	            {
	              "type": "core::u8"
	            }
	          ],
	          "state_mutability": "view"
	        }
	      ]
	    },
	    {
	      "type": "event",
	      "name": "simple_contract::simple_contract::simple_contract::Event",
	      "kind": "enum",
	      "variants": []
	    }
	  ]
}

```

As we see, by embedding the impl with the following impl alias syntax (also introduced in Cairo v2.3.0:

```auto
#[abi(embed_v0)]
impl MySimpleImpl = super::SimpleImpl<ContractState>;

```

we have added `MySimpleImpl` and `SimpleTrait` to the ABI of the contract, and can call `ret4` externally.

Now that we’re more familiar with the embedding mechanism, we can go back to the `Upgradable` impl inside our component:

```auto
#[embeddable_as(UpgradableImpl)]
	impl Upgradable<TContractState, +HasComponent<TContractState>> of super:IUpgradable<ComponentState<TContractState>> {
	...
}

```

Zooming in, we can notice two component-specific changes:

- `Upgradable` is dependent on an implementation of the `HasComponent<TContractState>` trait

- `Upgradable` is annotated with the `embeddable_as(<name>)` attribute:

To complete the picture, we look at the following lines inside `counter_contract.cairo`

```auto
#[abi(embed_v0)]
impl Upgradable = upgradable_component::UpgradableImpl<ContractSate>; 

```

We’ve seen how `UpgradableImpl` was generated by the compiler inside `upgradable.cairo`. The above lines use the Cairo v2.3.0 impl embedding mechanism alongside the impl alias syntax. We’re instantiating the generic `UpgradableImpl<TContractState>` with the concrete type `ContractState`. Recall that `UpgradableImpl<TContractState>` has the `HasComponent<TContractState>` generic impl param. An implementation of this trait is generated by the `component!` macro. Note that only the using contract could have implemented this trait since only it knows about both the contract state and the component state.

---

<div class="post-metadata">

### Author: ![Bal7hazar](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/bal7hazar/32/3870_2.png) [@Bal7hazar](https://community.starknet.io/u/Bal7hazar)
#### Post date: [September 27, 2023, 6:23pm UTC](https://community.starknet.io/t/cairo-components/101136/2 "2023-09-27T18:23:44Z")

</div>

Thank you for this awesome new feature.

> [@FeedTheFed](#):
>
> `#[substorage(v0)]`

Is `#[substorage(v0)]` will make the compiler to raise an error on storage name clash please?

---

<div class="post-metadata">

### Author: ![FeedTheFed](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/feedthefed/32/72981_2.png) [@FeedTheFed](https://community.starknet.io/u/FeedTheFed)
#### Post date: [September 28, 2023, 5:21am UTC](https://community.starknet.io/t/cairo-components/101136/3 "2023-09-28T05:21:16Z")

</div>

thanks for your reply!

`substorage` essentially means that it’s not accessed directly, like other storage variables whose type implement the `Store` trait. For example, if I want to access upgradable’s storage from the using contract, I do `self.upgradable.current_implementation.read()`.

Regarding your question, yes, the compiler will give an error if different components (or the contract itself) collide on some storage variable name. With v0 we still determine the layout in storage solely based on the variable name. This is important for upgradability purposes, where you want to use components but have the storage match exactly the non-component version. We plan to release v1 in the future where the name will also be determined by the “component name”, so you can have identical names in different components but they will not collide inside the storage.

---

<div class="post-metadata">

### Author: ![Bal7hazar](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/bal7hazar/32/3870_2.png) [@Bal7hazar](https://community.starknet.io/u/Bal7hazar)
#### Post date: [September 28, 2023, 7:38am UTC](https://community.starknet.io/t/cairo-components/101136/4 "2023-09-28T07:38:32Z")

</div>

Thank you for the answer, the v1 will be awesome.

With the 2.2.0 version we used to make composability using unsafe contract states, it was not secure espcially for storage variable names clashes I guess, but it brings a lot of flexibility.

With the component feature, and after a first read (I didn’t tried yet) I feel less comfortable regarding this flexibility. I am questioning the fact that we have to change a component regarding the contract usage I will have when I would like my component to be very neutral/generic. An example is worth a thousand words, I used to do this in my contracts to manage access control:

```plaintext
#[starknet::contract]
mod contract {
    ...
    #[external(v0)]
    impl UpgradeableImpl of IUpgradeable<ContractState> {
        fn upgrade(ref self: ContractState, impl_hash: ClassHash) {
            // [Check] Only owner
            let unsafe_state = Ownable::unsafe_new_contract_state();
            Ownable::InternalImpl::assert_only_owner(@unsafe_state);
            // [Effect] Upgrade
            let mut unsafe_state = Upgradeable::unsafe_new_contract_state();
            Upgradeable::InternalImpl::_upgrade(ref unsafe_state, impl_hash)
        }
    }
    ...
}

```

The example you provided is feature parity with this instance but what if I wanted to manage my access control with some custom controls (from OZ AccessControl module for instance). Am I supposed to have a dedicated component for each usage I need in my different contract?

---

<div class="post-metadata">

### Author: ![FeedTheFed](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/feedthefed/32/72981_2.png) [@FeedTheFed](https://community.starknet.io/u/FeedTheFed)
#### Post date: [September 28, 2023, 2:01pm UTC](https://community.starknet.io/t/cairo-components/101136/5 "2023-09-28T14:01:30Z")

</div>

Not sure if I correctly understand what you’re trying to do, but I think [dependencies](https://community.starknet.io/t/cairo-components/101136#component-dependencies-8) achieve what you want. Let’s say that `AccessControl` is a trait that manages access according to the logic you want, then if the component is dependent on an implementation of `AccessControl<TContractState>`, then it doesn’t care how your contract got it. As long as such an implementation exists, you can use the component.

---

<div class="post-metadata">

### Author: ![glihm](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/glihm/32/73137_2.png) [@glihm](https://community.starknet.io/u/glihm)
#### Post date: [September 29, 2023, 1:57am UTC](https://community.starknet.io/t/cairo-components/101136/6 "2023-09-29T01:57:54Z")

</div>

@FeedTheFed as always, thanks for those very insightful posts!  
Will test this in order to make more feedback. It looks awesome. 🚀

---

<div class="post-metadata">

### Author: ![Bal7hazar](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/bal7hazar/32/3870_2.png) [@Bal7hazar](https://community.starknet.io/u/Bal7hazar)
#### Post date: [September 29, 2023, 8:04am UTC](https://community.starknet.io/t/cairo-components/101136/7 "2023-09-29T08:04:55Z")

</div>

Thank you, so if I understand well and if I have one contract that implement AccessControl and another that implements Ownable, I will need to have 2 dedicated components? This was the topic I was trying to point out, using unsafe contract state strategy we are able to implement a single generic component for this purpose.

---

<div class="post-metadata">

### Author: ![FeedTheFed](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/feedthefed/32/72981_2.png) [@FeedTheFed](https://community.starknet.io/u/FeedTheFed)
#### Post date: [October 3, 2023, 12:52pm UTC](https://community.starknet.io/t/cairo-components/101136/8 "2023-10-03T12:52:59Z")

</div>

You will probably need two components, although you can write one component that fits your purpose.

[This repo](https://github.com/ArielElp/component-examples) contains a few more elaborate dependency examples that you can check out.

---

<div class="post-metadata">

### Author: ![TeddyNotBear](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/teddynotbear/32/73378_2.png) [@TeddyNotBear](https://community.starknet.io/u/TeddyNotBear)
#### Post date: [November 28, 2023, 9:55am UTC](https://community.starknet.io/t/cairo-components/101136/10 "2023-11-28T09:55:15Z")

</div>

Awesome feature !

I saw that there is a macro `get_dep_component_mut!` which seems to do the same thing as the `get_component_mut()` function. I tried to implement both to understand the difference but couldn’t find one. Are they similar or is there a real difference between them?

With macro `get_dep_component_mut!` :

```auto
# [embeddable_as (SimpleContractImpl)]
impl SimpleContract<
   TContractState,
   +HasComponent<TContractState>,
   impl Upgradeable: UpgradeableComponent::HasComponent<TContractState>,
   +Drop<TContractState>
> of super::ISimpleContract<ComponentState<TContractState>> {
   ...
   fn upgrade(ref self: ComponentState<TContractState>, new_class_hash: ClassHash) {
      let mut upgradeable_component = get_dep_component_mut!(ref self, Upgradeable);
      upgradeable_component._upgrade(new_class_hash);
   }
}

```

With function `get_component_mut()` :

```auto
# [embeddable_as (SimpleContractImpl)]
impl SimpleContract<
   TContractState,
   +HasComponent<TContractState>,
   +UpgradeableComponent::HasComponent<TContractState>,
   +Drop<TContractState>
> of super::ISimpleContract<ComponentState<TContractState>> {
   ...
   fn upgrade(ref self: ComponentState<TContractState>, new_class_hash: ClassHash) {
      let mut contract = self.get_contract_mut();
      let mut upgradeable_component = UpgradeableComponent::HasComponent::< 
         TContractState
      >::get_component_mut(ref contract);
      upgradeable_component._upgrade(new_class_hash);
   }
}

```

---

<div class="post-metadata">

### Author: ![FeedTheFed](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/feedthefed/32/72981_2.png) [@FeedTheFed](https://community.starknet.io/u/FeedTheFed)
#### Post date: [December 7, 2023, 8:21pm UTC](https://community.starknet.io/t/cairo-components/101136/11 "2023-12-07T20:21:40Z")

</div>

`get_dep_component_mut!` returns a `ComponentState` as opposed to `@ComponentState`, so you can use the component’s non-view functions.

Note that for now both macros only work on a mutable input (i.e. you can’t use them in a view function). It makes sense for `get_dep_component!` to take a snapshot as input, we’ll try to address this in the next release.

---

<div class="post-metadata">

### Author: ![juniset](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/juniset/32/40_2.png) [@juniset](https://community.starknet.io/u/juniset)
#### Post date: [February 7, 2024, 11:02am UTC](https://community.starknet.io/t/cairo-components/101136/12 "2024-02-07T11:02:10Z")

</div>

> [@FeedTheFed](#):
>
> Note that for now both macros only work on a mutable input (i.e. you can’t use them in a view function). It makes sense for `get_dep_component!` to take a snapshot as input, we’ll try to address this in the next release.

Is this available now?

---

<div class="post-metadata">

### Author: ![FeedTheFed](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/feedthefed/32/72981_2.png) [@FeedTheFed](https://community.starknet.io/u/FeedTheFed)
#### Post date: [February 18, 2024, 1:43pm UTC](https://community.starknet.io/t/cairo-components/101136/13 "2024-02-18T13:43:29Z")

</div>

yes, this was fixed in 2.5.x, `get_dep_component` now expects a snapshot
