dojo-world

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Dojo World Management

Dojo World 管理

Manage your Dojo world's permissions, namespaces, resource registration, and access control policies.
管理你的Dojo世界的权限、命名空间、资源注册及访问控制策略。

When to Use This Skill

何时使用该Skill

  • "Configure world permissions"
  • "Set up namespace access"
  • "Grant writer permissions"
  • "Manage resource ownership"
  • "配置世界权限"
  • "设置命名空间访问权限"
  • "授予写入者权限"
  • "管理资源所有权"

What This Skill Does

该Skill的功能

Handles world management:
  • Namespace configuration
  • Writer permissions (can write data)
  • Owner permissions (can write data + manage permissions)
  • Permission hierarchy management
处理世界管理相关事宜:
  • 命名空间配置
  • 写入者权限(可写入数据)
  • 所有者权限(可写入数据+管理权限)
  • 权限层级管理

Quick Start

快速开始

Configure permissions:
"Grant writer permission to my system"
Check permissions:
"List permissions for my world"
配置权限:
"Grant writer permission to my system"
检查权限:
"List permissions for my world"

Permission Concepts

权限概念

Permission Types

权限类型

Owner Permission:
  • Write data to the resource
  • Grant and revoke permissions to others
  • Upgrade the resource
  • Set resource metadata
Writer Permission:
  • Write data to the resource
  • Cannot grant permissions to others
  • Cannot upgrade the resource
Reading is always permissionless.
所有者权限:
  • 向资源写入数据
  • 向他人授予或撤销权限
  • 升级资源
  • 设置资源元数据
写入者权限:
  • 向资源写入数据
  • 无法向他人授予权限
  • 无法升级资源
读取操作始终无需权限。

Permission Hierarchy

权限层级

World Owner (highest)
    └── Namespace Owner
        └── Resource Owner / Writer (lowest)
  • World Owner: Can do anything in the world
  • Namespace Owner: Can manage all resources in their namespace
  • Resource Owner: Can manage a specific resource (model/contract/event)
  • Writer: Can only write data to a resource
World Owner (highest)
    └── Namespace Owner
        └── Resource Owner / Writer (lowest)
  • **World Owner(世界所有者):**可在世界内执行任意操作
  • **Namespace Owner(命名空间所有者):**可管理其命名空间内的所有资源
  • **Resource Owner(资源所有者):**可管理特定资源(模型/合约/事件)
  • **Writer(写入者):**仅能向资源写入数据

Configuration-Based Permissions

基于配置的权限

Set permissions during deployment in
dojo_<profile>.toml
:
toml
[writers]
可在部署阶段通过
dojo_<profile>.toml
设置权限:
toml
[writers]

Namespace-level: actions can write to all resources in my_game

Namespace-level: actions can write to all resources in my_game

"my_game" = ["my_game-actions"]
"my_game" = ["my_game-actions"]

Resource-specific: movement can only write to Position

Resource-specific: movement can only write to Position

"my_game-Position" = ["my_game-movement"]
[owners]
"my_game-Position" = ["my_game-movement"]
[owners]

Namespace ownership

Namespace ownership

"my_game" = ["my_game-admin"]

**Format:** `"<TARGET_TAG>" = ["<GRANTEE_TAG>"]`
"my_game" = ["my_game-admin"]

**格式:** `"<TARGET_TAG>" = ["<GRANTEE_TAG>"]`

CLI Permission Management

CLI权限管理

Grant Permissions

授予权限

bash
undefined
bash
undefined

Grant writer permission

Grant writer permission

sozo auth grant writer my_game-Position,my_game-actions
sozo auth grant writer my_game-Position,my_game-actions

Grant owner permission

Grant owner permission

sozo auth grant owner my_game,my_game-admin
undefined
sozo auth grant owner my_game,my_game-admin
undefined

Revoke Permissions

撤销权限

bash
undefined
bash
undefined

Revoke writer permission

Revoke writer permission

sozo auth revoke writer my_game-Position,my_game-actions
sozo auth revoke writer my_game-Position,my_game-actions

Revoke owner permission

Revoke owner permission

sozo auth revoke owner my_game,my_game-admin
undefined
sozo auth revoke owner my_game,my_game-admin
undefined

List Permissions

列出权限

bash
undefined
bash
undefined

List all permissions

List all permissions

sozo auth list
undefined
sozo auth list
undefined

Runtime Permission Management (Cairo)

运行时权限管理(Cairo)

Grant Permissions

授予权限

cairo
use dojo::world::WorldStorage;

// Grant writer permission to a contract
world.grant_writer(
    selector_from_tag!("my_game-Position"),
    movement_system_address
);

// Grant owner permission
world.grant_owner(
    selector_from_tag!("my_game-GameState"),
    new_owner_address
);
cairo
use dojo::world::WorldStorage;

// Grant writer permission to a contract
world.grant_writer(
    selector_from_tag!("my_game-Position"),
    movement_system_address
);

// Grant owner permission
world.grant_owner(
    selector_from_tag!("my_game-GameState"),
    new_owner_address
);

Revoke Permissions

撤销权限

cairo
// Revoke writer permission
world.revoke_writer(
    selector_from_tag!("my_game-Position"),
    old_system_address
);

// Revoke owner permission
world.revoke_owner(
    selector_from_tag!("my_game-GameState"),
    old_owner_address
);
cairo
// Revoke writer permission
world.revoke_writer(
    selector_from_tag!("my_game-Position"),
    old_system_address
);

// Revoke owner permission
world.revoke_owner(
    selector_from_tag!("my_game-GameState"),
    old_owner_address
);

Check Permissions

检查权限

cairo
// Check if address is owner
let is_owner = world.is_owner(resource_selector, address);

// Check if address is writer
let can_write = world.is_writer(resource_selector, address);
cairo
// Check if address is owner
let is_owner = world.is_owner(resource_selector, address);

// Check if address is writer
let can_write = world.is_writer(resource_selector, address);

Permission Patterns

权限模式

Principle of Least Privilege

最小权限原则

cairo
// Good: Specific permissions for specific functions
world.grant_writer(selector_from_tag!("my_game-Position"), movement_contract);
world.grant_writer(selector_from_tag!("my_game-Health"), combat_contract);

// Bad: Overly broad permissions
world.grant_owner(selector_from_tag!("my_game"), movement_contract);
cairo
// Good: Specific permissions for specific functions
world.grant_writer(selector_from_tag!("my_game-Position"), movement_contract);
world.grant_writer(selector_from_tag!("my_game-Health"), combat_contract);

// Bad: Overly broad permissions
world.grant_owner(selector_from_tag!("my_game"), movement_contract);

Multi-System Architecture

多系统架构

cairo
// Different systems handle different aspects
world.grant_writer(selector_from_tag!("my_game-Position"), movement_system);
world.grant_writer(selector_from_tag!("my_game-Health"), combat_system);
world.grant_writer(selector_from_tag!("my_game-Inventory"), inventory_system);

// Trading system needs access to Inventory too
world.grant_writer(selector_from_tag!("my_game-Inventory"), trading_system);
cairo
// Different systems handle different aspects
world.grant_writer(selector_from_tag!("my_game-Position"), movement_system);
world.grant_writer(selector_from_tag!("my_game-Health"), combat_system);
world.grant_writer(selector_from_tag!("my_game-Inventory"), inventory_system);

// Trading system needs access to Inventory too
world.grant_writer(selector_from_tag!("my_game-Inventory"), trading_system);

Namespace-Level Permissions

命名空间级权限

Grant access to all resources in a namespace:
cairo
// This system can write to ANY resource in "my_game" namespace
world.grant_writer(
    selector_from_tag!("my_game"),
    system_contract
);
授予对命名空间内所有资源的访问权限:
cairo
// This system can write to ANY resource in "my_game" namespace
world.grant_writer(
    selector_from_tag!("my_game"),
    system_contract
);

Admin System

管理系统

cairo
// Admin has owner permission on namespace
world.grant_owner(selector_from_tag!("my_game"), game_admin);

// Admin has owner permission on critical resources
world.grant_owner(selector_from_tag!("my_game-GameConfig"), game_admin);
cairo
// Admin has owner permission on namespace
world.grant_owner(selector_from_tag!("my_game"), game_admin);

// Admin has owner permission on critical resources
world.grant_owner(selector_from_tag!("my_game-GameConfig"), game_admin);

Authorization in Systems

系统中的授权

Public Functions

公共函数

Anyone can call:
cairo
fn spawn(ref self: ContractState) {
    let mut world = self.world_default();
    let player = get_caller_address();

    // No permission check - anyone can spawn
    world.write_model(@Position { player, vec: Vec2 { x: 0, y: 0 } });
}
任何人都可调用:
cairo
fn spawn(ref self: ContractState) {
    let mut world = self.world_default();
    let player = get_caller_address();

    // No permission check - anyone can spawn
    world.write_model(@Position { player, vec: Vec2 { x: 0, y: 0 } });
}

Checking Permissions

权限检查

cairo
fn admin_function(ref self: ContractState) {
    let mut world = self.world_default();
    let caller = get_caller_address();

    // Check caller is owner of the namespace
    assert(
        world.is_owner(selector_from_tag!("my_game"), caller),
        'not authorized'
    );

    // Proceed with admin logic
}
cairo
fn admin_function(ref self: ContractState) {
    let mut world = self.world_default();
    let caller = get_caller_address();

    // Check caller is owner of the namespace
    assert(
        world.is_owner(selector_from_tag!("my_game"), caller),
        'not authorized'
    );

    // Proceed with admin logic
}

Permission Events

权限事件

The World contract emits events when permissions change:
cairo
#[derive(Drop, starknet::Event)]
pub struct OwnerUpdated {
    #[key]
    pub resource: felt252,
    #[key]
    pub contract: ContractAddress,
    pub value: bool,
}

#[derive(Drop, starknet::Event)]
pub struct WriterUpdated {
    #[key]
    pub resource: felt252,
    #[key]
    pub contract: ContractAddress,
    pub value: bool,
}
当权限发生变更时,World合约会触发事件:
cairo
#[derive(Drop, starknet::Event)]
pub struct OwnerUpdated {
    #[key]
    pub resource: felt252,
    #[key]
    pub contract: ContractAddress,
    pub value: bool,
}

#[derive(Drop, starknet::Event)]
pub struct WriterUpdated {
    #[key]
    pub resource: felt252,
    #[key]
    pub contract: ContractAddress,
    pub value: bool,
}

Common Scenarios

常见场景

Initial Setup (via config)

初始设置(通过配置)

toml
undefined
toml
undefined

dojo_dev.toml

dojo_dev.toml

[namespace] default = "my_game"
[writers]
[namespace] default = "my_game"
[writers]

All resources in my_game can be written by actions

All resources in my_game can be written by actions

"my_game" = ["my_game-actions"]
[owners]
"my_game" = ["my_game-actions"]
[owners]

Admin system owns the namespace

Admin system owns the namespace

"my_game" = ["my_game-admin"]
undefined
"my_game" = ["my_game-admin"]
undefined

Adding New System (runtime)

添加新系统(运行时)

cairo
fn add_new_system(ref self: ContractState, new_system_address: ContractAddress) {
    let mut world = self.world_default();

    // Must be namespace owner to grant permissions
    world.grant_writer(
        selector_from_tag!("my_game-Position"),
        new_system_address
    );
}
cairo
fn add_new_system(ref self: ContractState, new_system_address: ContractAddress) {
    let mut world = self.world_default();

    // Must be namespace owner to grant permissions
    world.grant_writer(
        selector_from_tag!("my_game-Position"),
        new_system_address
    );
}

Transfer Namespace Ownership

转移命名空间所有权

cairo
fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) {
    let mut world = self.world_default();

    // Grant owner to new address
    world.grant_owner(selector_from_tag!("my_game"), new_owner);

    // Revoke from current owner
    world.revoke_owner(selector_from_tag!("my_game"), get_caller_address());
}
cairo
fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) {
    let mut world = self.world_default();

    // Grant owner to new address
    world.grant_owner(selector_from_tag!("my_game"), new_owner);

    // Revoke from current owner
    world.revoke_owner(selector_from_tag!("my_game"), get_caller_address());
}

Troubleshooting

故障排除

"Not authorized" errors

"未授权"错误

  • Check writer permissions are granted
  • Verify the system address is correct
  • Check if permission is at namespace or resource level
  • 检查是否已授予写入者权限
  • 验证系统地址是否正确
  • 检查权限是在命名空间级别还是资源级别设置的

"Permission denied"

"权限拒绝"错误

  • Check you have owner permission to grant/revoke
  • Verify you're calling from the correct account
  • 检查你是否拥有授予/撤销权限的所有者权限
  • 验证你是否从正确的账户发起调用

Debugging Permissions

调试权限

cairo
fn debug_permissions(world: @WorldStorage, resource: felt252, address: ContractAddress) {
    let is_owner = world.is_owner(resource, address);
    let is_writer = world.is_writer(resource, address);

    // Log or print these values for debugging
}
cairo
fn debug_permissions(world: @WorldStorage, resource: felt252, address: ContractAddress) {
    let is_owner = world.is_owner(resource, address);
    let is_writer = world.is_writer(resource, address);

    // Log or print these values for debugging
}

Next Steps

后续步骤

After permission setup:
  1. Test all permission checks work correctly
  2. Document the permission structure
  3. Set up monitoring for permission changes
  4. Consider using a multi-sig for production owner accounts
完成权限设置后:
  1. 测试所有权限检查是否正常工作
  2. 记录权限结构
  3. 设置权限变更监控
  4. 考虑在生产环境中使用多签账户作为所有者账户

Related Skills

相关Skill

  • dojo-deploy: Deploy world first
  • dojo-system: Add authorization to systems
  • dojo-config: Configure permissions in profile
  • dojo-review: Audit permission setup
  • dojo-deploy:先部署世界
  • dojo-system:为系统添加授权
  • dojo-config:在配置文件中配置权限
  • dojo-review:审核权限设置