LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 币圈百科 > 【Substrate开发教程】20 - StorageMap和StorageDoubleMap的使用

【Substrate开发教程】20 - StorageMap和StorageDoubleMap的使用

2020-11-04 松果 来源:区块链网络


上一篇文章介绍了使用Rust标准库的Vec作为集合,Vec是一个列表,存储一组相同类型的数据。

这篇文章介绍另外的集合,基于键值对的哈希表(HashMap),包括:

frame_support::storage::StorageMapframe_support::storage::StorageDoubleMap

StorageMap定义存储

这里把上一篇文章中Vec集合的成员作为键(key)存储在Substrate提供的StorageMap中。

decl_storage! { trait Store for Module<T: Trait> as VecMap { Members get(fn members): map hasher(blake2_128_concat) T::AccountId => (); MemberCount: u32; } }

StorageMap内部不会自动跟踪其容量大小,因此引入了第二个存储值MemberCount用于统计成员数量。

这里只关心键(key),因此值(value)为()。

StorageMap添加成员

模块中定义了一个add_member函数来添加成员到Members集合,添加成员时会做一些条件检查以确保安全。

fn add_member(origin) -> DispatchResult { let new_member = ensure_signed(origin)?; let member_count = MemberCount::get(); ensure!(member_count < MAX_MEMBERS, Error::<T>::MembershipLimitReached); ensure!(!Members::<T>::contains_key(&new_member), Error::<T>::AlreadyMember); Members::<T>::insert(&new_member, ()); MemberCount::put(member_count + 1); Self::deposit_event(RawEvent::MemberAdded(new_member)); Ok(()) }

这里使用了StorageMap的contains_key方法,检查列表是否已存在潜在的新成员,以避免添加重复成员。

如果查找到该成员已存在则返回错误,如果查找到该成员不存在则调用insert方法插入该成员到Map,然后触发一个事件。

成功添加数据后,手动增加MemberCount的计数。

StorageMap删除成员

fn remove_member(origin) -> DispatchResult { let old_member = ensure_signed(origin)?; ensure!(Members::<T>::contains_key(&old_member), Error::<T>::NotMember); Members::<T>::remove(&old_member); MemberCount::mutate(|v| *v -= 1); Self::deposit_event(RawEvent::MemberRemoved(old_member)); Ok(()) }

删除成员时首先在Map中查找调用者,如果不存在则返回错误,如果调用者存在,则调用remove方法删除此数据,并更新MemberCount的大小。

StorageDoubleMap

StorageDoubleMap使用两个键(key)来实现哈希表,第一个键是Group ID,模块中定义存储的代码如下:

pub type GroupIndex = u32; decl_storage! { trait Store for Module<T: Trait> as Dmap { MemberScore get(fn member_score): double_map hasher(blake2_128_concat) GroupIndex, hasher(blake2_128_concat) T::AccountId => u32; GroupMembership get(fn group_membership): map hasher(blake2_128_concat) T::AccountId => GroupIndex; AllMembers get(fn all_members): Vec<T::AccountId>; } }

StorageDoubleMap是双重哈希表,外层哈希表的键是GroupIndex,值是内层哈希表;内层哈希表的键是AccountId类型,值是u32类型。

使用StorageDoubleMap删除一组数据

使用StorageDoubleMap可以有效删除具有相同的第一个键的所有成员。

fn remove_group_score(origin, group: GroupIndex) -> DispatchResult { let member = ensure_signed(origin)?; let group_id = <GroupMembership<T>>::get(member); ensure!(group_id == group, "member isn't in the group, can't remove it"); <MemberScore<T>>::remove_prefix(&group_id); Self::deposit_event(RawEvent::RemoveGroup(group_id)); Ok(()) }

这里定义的remove_group_score函数带有一个GroupIndex参数,StorageDoubleMap使用其成员函数remove_prefix,传入group_id参数可以删除这一组数据,删除完成后触发事件。

—-

编译者/作者:松果

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...