10.映射和其他类型


文档摘要

title: 10. 映射和其他类型 tags: cairo starknet mapping WTF Cairo极简教程: 10. 映射和字典 我最近在学 ,巩固一下细节,也写一个 ,供小白们使用。教程基于 版本。 推特:@0xAAScience|@WTFAcademy WTF Academy 社群:Discord|微信群|官网 wtf.academy 所有代码和教程开源在 github: github.com/WTFAcademy/WTF-Cairo 在本章中,我们将介绍如何在Cairo中使用“映射”和“字典”类型。 Mapping (映射)类型允许用户通过 来查询相应的 。例如,可以通过账户地址查询账户余额。在Cairo中,可以使用 来创建映射。

title: 10. 映射和其他类型 tags: - cairo - starknet - mapping

WTF Cairo极简教程: 10. 映射和字典

我最近在学cairo-lang,巩固一下细节,也写一个WTF Cairo极简教程,供小白们使用。教程基于cairo 2.2.0版本。

推特:@0xAA_Science@WTFAcademy_

WTF Academy 社群:Discord微信群官网 wtf.academy

所有代码和教程开源在 github: github.com/WTFAcademy/WTF-Cairo

在本章中,我们将介绍如何在Cairo中使用“映射”和“字典”类型。

Mapping

mapping(映射)类型允许用户通过来查询相应的。例如,可以通过账户地址查询账户余额。在Cairo中,可以使用LegacyMap来创建映射。

需要注意的是:

  1. LegacyMap类型只允许作为状态变量使用,不能用作合约函数的参数或返回参数,也不能用作结构体内的类型。

  2. 可以使用多个key对应一个value。

在下面的示例中,使用到了ContractAddress类型,即合约地址,需要使用use starknet::ContractAddress;导入。

use starknet::ContractAddress; #[storage] struct Storage { balances: Map::<ContractAddress, felt252>, allowance: Map::<(ContractAddress,ContractAddress),flet252> }

对于Mapping的状态变量地址的计算,需要用到sn_keccak和pedersen hash (记为h),具体算法为:对于一个名为variable_name,有n个key的mapping状态变量,其地址为h(...h(h(sn_keccak(variable_name),k_1),k_2),...,k_n),并将最终结果取模2^251-256。

与mapping的状态变量交互的函数如下:

// 读取余额 #[external(v0)] fn read_balance(self: @ContractState, account: ContractAddress) -> u256 { self.balances.read(account) }

可以使用以下函数更新给定地址的余额:

// 更新余额 #[external(v0)] fn write_balance(ref self: ContractState, account: ContractAddress, new_balance: u256){ self.balances.write(account, new_balance); }

Dictionaries

Cairo中还有一种使用键值对的数据类型-字典(dictionaries)。通过Felt252Dict<T>来进行创建,其中键唯一且只能是felt252类型,值为设定的T类型,与键相关联。你还可以进行以下两个基本操作:

  1. insert(felt252,T)->():用于向字典实例写入值。

  2. get(felt252)->T:用于从字典读取值。

#[external(v0)] fn dictionaries(self: @ContractState) -> u64{ let mut balances: Felt252Dict<u64> = Default::default(); balances.insert('Alex',100); balances.insert('Maria',200); let alex_balance = balances.get('Alex'); return alex_balance; }

需要注意的是,虽然cairo使用的是不可改内存,但字典相同键对应的值是可以修改的。

#[external(v0)] fn dictionaries_extern(self: @ContractState) -> (u64,u64){ let mut balances: Felt252Dict<u64> = Default::default(); balances.insert('Alex',100); let alex_balance_first = balances.get('Alex'); balances.insert('Alex',200); let alex_balance_second = balances.get('Alex'); return (alex_balance_first,alex_balance_second); }

总结

在本章中,我们讨论了如何在Cairo中使用映射类型和字典类型来创建和管理智能合约中的键值对。这些概念将帮助你在Starknet上开发更高效、更有组织的智能合约。


发布者: 作者: 转发
评论区 (0)
U