变量

Cairo合约中有 3 种变量:

  • 局部
    • 在函数中声明
    • 不存储在区块链中
  • 存储
    • 在合约的 Storage 中声明
    • 可从一个执行过程访问到另一个执行过程
  • 全局
    • 提供有关区块链的信息
    • 可在任何地方访问,甚至在库函数中

局部变量

局部变量在特定函数或代码块的范围内使用和访问。它们是临时的,只在特定函数或代码块执行期间存在。

局部变量存储在内存中,不会存储在区块链上。这就意味着在执行过程中无法访问它们。局部变量可用于存储仅在特定上下文中相关的临时数据。通过为中间值命名,它们还能使代码更具可读性。

下面是一个只有局部变量的简单合约示例:

#[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
            }
        }
    }
}

访问 Voyager 上的合约,或在 Remix 中尝试它。

存储用变量

存储变量是存储在区块链上的持久数据。它们可以在不同的执行过程中被访问,从而使合约能够保存和更新信息。

要写入或更新存储变量,需要通过外部入口点发送交易与合约交互。

另一方面,只需与节点交互,就可以免费读取状态变量,无需发出任何交易。

下面是一个带有一个存储变量的简单合约示例:

#[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()
        }
    }
}

访问 Voyager 上的合约,或在 Remix 中尝试它。

全局变量

全局变量是预定义变量,可提供有关区块链和当前执行环境的信息。可以随时随地访问它们!

在 Starknet 中,您可以通过使用 starknet 核心库中的特定函数来访问全局变量。

例如,get_caller_address函数返回当前事务的调用者地址,get_contract_address函数返回当前合同的地址。

#[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();
        // ...
        }
    }
}

访问 Voyager 上的合约,或在 Remix 中尝试它。

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