引言dent_list是sui-framework实现的一个拒绝名单列表,用于进行对sui核心类型的地址访问控制。它仅能由系统事务创建,是shareobj,本文通过介绍deny_list的实现与使用,理解在suimove中实现访问控制的思想
dent_list是sui-framework实现的一个拒绝名单列表,用于进行对sui核心类型的地址访问控制。它仅能由系统事务创建,是share obj,本文通过介绍deny_list的实现与使用,理解在sui move中实现访问控制的思想
首先来看实现deny_list使用了哪些库
use sui::table::{Self, Table};
use sui::bag::{Self, Bag};
use sui::vec_set::{Self, VecSet};
table、bag、vec_set在前面的文章都有分析
struct DenyList has key {
id: UID,
lists: Bag,
}
struct PerTypeList has key, store {
id: UID,
denied_count: Table<address, u64>,
denied_addresses: Table<vector<u8>, VecSet<address>>,
}
拒绝名单的构成可以抽象为
/ address 1
type 1 ...
/ \ address n
TypeList 1 ...
\ / address 1
type n ...
\ address n
/
DenyList ...
\
/ address 1
type 1 ...
/ \ address n
TypeList n ...
\ / address 1
type n ...
\ address n
DenyList中bag:键为TypeList索引,值为相应的TypeList
TypeList中denied_count:用来快速检索一个地址是否在拒绝列表中
denied_addresses:用来储存拒绝列表 键为限制类型 用VecSet储存限制被限制的地址
public(friend) fun add(
deny_list: &mut DenyList,
per_type_index: u64,
type: vector<u8>,
addr: address,
) {
per_type_list_add(bag::borrow_mut(&mut deny_list.lists, per_type_index), type, addr)
}
fun per_type_list_add(
list: &mut PerTypeList,
type: vector<u8>,
addr: address,
) {
if (!table::contains(&list.denied_addresses, type)) {
table::add(&mut list.denied_addresses, type, vec_set::empty());
};
let denied_addresses = table::borrow_mut(&mut list.denied_addresses, type);
let already_denied = vec_set::contains(denied_addresses, &addr);
if (already_denied) return;
vec_set::insert(denied_addresses, addr);
if (!table::contains(&list.denied_count, addr)) {
table::add(&mut list.denied_count, addr, 0);
};
let denied_count = table::borrow_mut(&mut list.denied_count, addr);
*denied_count = *denied_count + 1;
}
public(friend) fun remove(
deny_list: &mut DenyList,
per_type_index: u64,
type: vector<u8>,
addr: address,
) {
per_type_list_remove(bag::borrow_mut(&mut deny_list.lists, per_type_index), type, addr)
}
fun per_type_list_remove(
list: &mut PerTypeList,
type: vector<u8>,
addr: address,
) {
let denied_addresses = table::borrow_mut(&mut list.denied_addresses, type);
assert!(vec_set::contains(denied_addresses, &addr), ENotDenied);
vec_set::remove(denied_addresses, &addr);
let denied_count = table::borrow_mut(&mut list.denied_count, addr);
*denied_count = *denied_count - 1;
if (*denied_count == 0) {
table::remove(&mut list.denied_count, addr);
}
}
public(friend) fun contains(
deny_list: &DenyList,
per_type_index: u64,
type: vector<u8>,
addr: address,
): bool {
per_type_list_contains(bag::borrow(&deny_list.lists, per_type_index), type, addr)
}
fun per_type_list_contains(
list: &PerTypeList,
type: vector<u8>,
addr: address,
): bool {
if (!table::contains(&list.denied_count, addr)) return false;
let denied_count = table::borrow(&list.denied_count, addr);
if (*denied_count == 0) return false;
if (!table::contains(&list.denied_addresses, type)) return false;
let denied_addresses = table::borrow(&list.denied_addresses, type);
vec_set::contains(denied_addresses, &addr)
}
在本文中,介绍了sui-framework中的拒绝名单列表(deny_list)的实现与使用方法。该功能用于进行对sui核心类型的地址访问控制。希望有所帮助。
Move语言学习交流QQ群: 79489587 Sui官方中文开发者电报群: https://t.me/sui_dev_cn
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!