变量
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();
// ...
}
}
}