Access Control
关键概念
管理员管理
该系统具有一个顶层管理员,该管理员有权调用 AccessControl
trait 中的任何函数。必须在合约初始化期间设置此管理员,模块才能正常运行。为了实现去中心化,这个总管理员可以放弃自己的权限。
管理员转移实现为两步过程,以防止意外或恶意的接管:
-
当前管理员通过指定新管理员和过期时间 (
live_until_ledger
) *发起*转移。 -
指定的新管理员必须*显式接受*转移才能完成它。
在转移被接受之前,原始管理员保留完全控制权,并且可以通过发起新的转移或使用 live_until_ledger
为 0
来覆盖或取消转移。
使用示例
以下是使用 Access Control 模块的简单示例:
use soroban_sdk::{contract, contractimpl, symbol_short, Address, Env};
use stellar_access::access_control::{self as access_control, AccessControl};
use stellar_macros::{has_role, only_admin};
#[contract]
pub struct MyContract;
#[contractimpl]
impl MyContract {
pub fn __constructor(e: &Env, admin: Address) {
// 设置合约管理员
access_control::set_admin(e, &admin);
// 创建一个 "minter" 角色,其中 admin 作为其管理员
access_control::set_role_admin_no_auth(e, &symbol_short!("minter"), &symbol_short!("admin"));
}
#[only_admin]
pub fn admin_restricted_function(e: &Env) -> Vec<String> {
vec![&e, String::from_str(e, "seems sus")]
}
// 我们想要宏提供的 `require_auth()`,因为在 `Base::mint` 中没有
// `require_auth()`。
#[only_role(caller, "minter")]
pub fn mint(e: &Env, caller: Address, to: Address, token_id: u32) {
Base::mint(e, &to, token_id)
}
// 允许 minter 或 burner 角色,不在宏中强制执行 `require_auth`
#[has_any_role(caller, ["minter", "burner"])]
pub fn multi_role_action(e: &Env, caller: Address) -> String {
caller.require_auth();
String::from_str(e, "multi_role_action_success")
}
// 允许 minter 或 burner 角色 AND 在宏中强制执行 `require_auth`
#[only_any_role(caller, ["minter", "burner"])]
pub fn multi_role_auth_action(e: &Env, caller: Address) -> String {
String::from_str(e, "multi_role_auth_action_success")
}
}