上一篇文章介绍了使用Rust标准库的Vec作为集合,Vec是一个列表,存储一组相同类型的数据。 这篇文章介绍另外的集合,基于键值对的哈希表(HashMap),包括: frame_support::storage::StorageMapframe_support::storage::StorageDoubleMapStorageMap定义存储 这里把上一篇文章中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参数可以删除这一组数据,删除完成后触发事件。 —- 编译者/作者:松果 玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。 |
【Substrate开发教程】20 - StorageMap和StorageDoubleMap的使用
2020-11-04 松果 来源:区块链网络
LOADING...
相关阅读:
- 终于弄懂了:全民GMT简介2020-11-04
- 阿中能源:大数据为加油站带来新机遇2020-11-04
- 黑客告诉我们如何分配2020年通过勒索软件被盗的1亿美元2020-11-04
- 美国总统选举中,来自第一数据:比特币如何应对?2020-11-04
- OKEx|交易大数据11032020-11-03