cairo-contracts icon indicating copy to clipboard operation
cairo-contracts copied to clipboard

Add hooks usage section

Open andrew-fleming opened this issue 1 year ago • 5 comments

It might be helpful for users not familiar with hooks to have a more formal description and example. This probably belongs in /components.adoc#customization

andrew-fleming avatar Apr 24 '24 04:04 andrew-fleming

Hey, does someone have a simple example of ERC20HooksTrait usage?

o-tsaruk avatar Apr 29 '24 12:04 o-tsaruk

We will include a guide for them, but in the meantime we will be updating the wizard probably this week with the ERC20Votes extension, and that extension uses hooks.

ericnordelo avatar Apr 29 '24 14:04 ericnordelo

Hey, @o-tsaruk. In the mean time, you can also take a look at our ERC20Votes mock for a usage example: https://github.com/OpenZeppelin/cairo-contracts/blob/main/src/tests/mocks/erc20_votes_mocks.cairo#L63-L86

andrew-fleming avatar Apr 29 '24 16:04 andrew-fleming

Thank you, friends! Do you know if can we use the storage variable inside ERC20HooksTrait implementation? Or it's possible only for ERC-20 storage variables?

#[storage]
struct Storage {
    #[substorage(v0)]
    erc20: ERC20Component::Storage,
    some_variable: u256,
 }

o-tsaruk avatar Apr 30 '24 13:04 o-tsaruk

Sorry for the delay @o-tsaruk . We can definitely use a contract's storage variables inside the hooks trait. It's a different approach than with the mock example.

First, we need to remove the generic syntax of the implementation and instead pass in the contract's state (ContractState). And then we can access the state with get_contract from the HasComponent trait.

Here's an example with your struct:

impl ERC20HooksImpl of ERC20Component::ERC20HooksTrait<ContractState> {
    fn before_update(
        ref self: ERC20Component::ComponentState<ContractState>,
        from: ContractAddress,
        recipient: ContractAddress,
        amount: u256
    ) {
        let mut contract_state = ERC20Component::HasComponent::get_contract_mut(ref self);
        contract_state.some_variable.write(12345);
    }
    
    (...)
}

S/o to @ericnordelo for the solution

andrew-fleming avatar May 09 '24 03:05 andrew-fleming