Variables

Hay 3 tipos de variables en los contratos de Cairo:

  • Local
    • declared inside a function
    • not stored on the blockchain
  • Storage
    • declared in the Storage of a contract
    • can be accessed from one execution to another
  • Global
    • provides information about the blockchain
    • accessed anywhere, even within library functions

Local Variables

Las variables locales se utilizan y se accede a ellas dentro del alcance de una función o bloque de código específico. Son temporales y existen solo mientras dure esa función en particular o la ejecución del bloque.

Las variables locales se almacenan en la memoria y no en la cadena de bloques. Esto significa que no se puede acceder a ellos de una ejecución a otra. Las variables locales son útiles para almacenar datos temporales que son relevantes sólo dentro de un contexto específico. También hacen que el código sea más legible al dar nombres a los valores intermedios.

Aquí hay un ejemplo simple de un contrato con solo variables locales:

#[starknet::interface]
trait ILocalVariablesExample<TContractState> {
    fn do_something(self: @TContractState, value: u32) -> u32;
}

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

    #[abi(embed_v0)]
    impl LocalVariablesExample of super::ILocalVariablesExample<ContractState> {
        fn do_something(self: @ContractState, value: u32) -> u32 {
            // This variable is local to the current block. It can't be accessed once it goes out of scope.
            let increment = 10;

            {
                // The scope of a code block allows for local variable declaration
                // We can access variables defined in higher scopes.
                let sum = value + increment;
                sum
            }
        }
    }
}

Visite el contrato en Voyager](https://goerli.voyager.online/contract/0x015B3a10F9689BeD741Ca3C210017BC097122CeF76f3cAA191A20ff8b9b56b96) o juegue con él en Remix.

Storage Variables

Las variables de almacenamiento (storage) son datos persistentes almacenados en la blockchain. Se puede acceder a ellos de una ejecución a otra, lo que permite que el contrato recuerde y actualice la información a lo largo del tiempo.

Para escribir o actualizar una variable de storage, debe interactuar con el contrato a través de un punto de entrada externo mediante el envío de una transacción.

Por otro lado, puedes leer variables de estado, de forma gratuita, sin ninguna transacción, simplemente interactuando con un nodo.

A continuación se muestra un ejemplo sencillo de un contrato con una variable de almacenamiento:

#[starknet::interface]
trait IStorageVariableExample<TContractState> {
    fn set(ref self: TContractState, value: u32);
    fn get(self: @TContractState) -> u32;
}
#[starknet::contract]
mod StorageVariablesExample {
    // All storage variables are contained in a struct called Storage
    // annotated with the `#[storage]` attribute
    #[storage]
    struct Storage {
        // Storage variable holding a number
        value: u32
    }

    #[abi(embed_v0)]
    impl StorageVariablesExample of super::IStorageVariableExample<ContractState> {
        // Write to storage variables by sending a transaction that calls an external function
        fn set(ref self: ContractState, value: u32) {
            self.value.write(value);
        }

        // Read from storage variables without sending transactions
        fn get(self: @ContractState) -> u32 {
            self.value.read()
        }
    }
}

Visita el contrato en Voyager o juega con él en Remix.

Global Variables

Las variables globales son variables predefinidas que proporcionan información sobre la blockchain y el entorno de ejecución actual. ¡Se puede acceder a ellos en cualquier momento y desde cualquier lugar!

En Starknet, puede acceder a variables globales utilizando funciones específicas contenidas en las bibliotecas principales de Starknet.

Por ejemplo, la función get_caller_address devuelve la dirección de la persona que llama de la transacción actual, y la función get_contract_address devuelve la dirección del contrato actual.

#[starknet::interface]
trait IGlobalExample<TContractState> {
    fn foo(ref self: TContractState);
}
#[starknet::contract]
mod GlobalExample {
    // import the required functions from the starknet core library
    use starknet::get_caller_address;

    #[storage]
    struct Storage {}

    #[abi(embed_v0)]
    impl GlobalExampleImpl of super::IGlobalExample<ContractState> {
        fn foo(ref self: ContractState) {
            // Call the get_caller_address function to get the sender address
            let caller = get_caller_address();
        // ...
        }
    }
}

Visite el contrato en Voyager](https://goerli.voyager.online/contract/0x05bD2F3943bd4e030f85678b55b2EC2C1be939e32388530FB20ED967B3Be433F) o juega con él en Remix.

Last change: 2023-11-20, commit: 3890c7b