世界合约
世界合约是一个中央系统内核,是启动和解决所有交互的基础。在这个内核中,合约被部署、注册和执行,简化了下游系统的流程,使得客户只需与一个合约而不是潜在的数百个合约打交道。
Dojo 核心将此合约抽象化,作为开发者,您无需编写此合约,也无需在构建世界时对其进行修改。但是,了解它的工作原理以及它与系统其他部分的交互方式非常重要。
思考: 将自治世界视为驻留在另一个区块链中的主权区块链--可以说是嵌套区块链。正如你可以在以太坊上部署合约来增强其功能一样,你也可以在世界合约中引入系统来丰富其功能。与以太坊类似,任何人都可以为 "世界 "做出贡献,但与组件状态交互需要授权。有一个专门的主题会讨论授权。
Context(上下文)
你会注意到,每个 System 都接受一个 Context
结构体作为第一个参数。这是一个特殊的结构体,包含有关世界和调用者的信息。
#[derive(Copy, Drop, Serde)]
struct Context {
world: IWorldDispatcher, // Dispatcher to the world contract
origin: ContractAddress, // Address of the origin
system: felt252, // Name of the calling system
system_class_hash: ClassHash, // Class hash of the calling system
}
uuid()
命令
为实体生成唯一 ID 通常很有用。uuid()
函数可用来生成唯一 ID。
像这样使用它:
let game_id = ctx.world.uuid();
完整的世界API
世界公开了一个接口,任何客户端都可以与之交互。
// World interface
#[starknet::interface]
trait IWorld<T> {
fn component(self: @T, name: felt252) -> ClassHash;
fn register_component(ref self: T, class_hash: ClassHash);
fn system(self: @T, name: felt252) -> ClassHash;
fn register_system(ref self: T, class_hash: ClassHash);
fn uuid(ref self: T) -> usize;
fn emit(self: @T, keys: Array<felt252>, values: Span<felt252>);
fn execute(ref self: T, system: felt252, calldata: Array<felt252>) -> Span<felt252>;
fn entity(
self: @T, component: felt252, keys: Span<felt252>, offset: u8, length: usize
) -> Span<felt252>;
fn set_entity(
ref self: T, component: felt252, keys: Span<felt252>, offset: u8, value: Span<felt252>
);
fn entities(
self: @T, component: felt252, index: felt252, length: usize
) -> (Span<felt252>, Span<Span<felt252>>);
fn set_executor(ref self: T, contract_address: ContractAddress);
fn executor(self: @T) -> ContractAddress;
fn delete_entity(ref self: T, component: felt252, keys: Span<felt252>);
fn origin(self: @T) -> ContractAddress;
fn is_owner(self: @T, account: ContractAddress, target: felt252) -> bool;
fn grant_owner(ref self: T, account: ContractAddress, target: felt252);
fn revoke_owner(ref self: T, account: ContractAddress, target: felt252);
fn is_writer(self: @T, component: felt252, system: felt252) -> bool;
fn grant_writer(ref self: T, component: felt252, system: felt252);
fn revoke_writer(ref self: T, component: felt252, system: felt252);
}