Function Selectors

Function selectors

You can call a System using call (opens in a new tab). When you use this method, you provide two parameters.

If you have the necessary delegation you can also use callFrom, which lets you also specify the address on whose behalf you are calling.

To improve the developer experience of calling System functions, the namespace owner can register a function selector for each System function in the World contract. This removes the need for the caller to know the system's ResourceId, and the need to manually encode the calldata via abi.encodeCall. Once the namespace owner registers a function selector for a System function, anybody can call the System via <World>.<namespace>__<function>(<args>).

To register a function selector, you use <world>.registerFunctionSelector (opens in a new tab). This function takes two parameters:

For example, in the Extending a World guide we create a namespace called messaging, within it a System called message, and that System includes a function called incrementMessage.

This is the code we use to register the System and the function selector:

    ResourceId systemId = WorldResourceIdLib.encode(RESOURCE_SYSTEM, "messaging", "message");
    world.registerSystem(systemId, messageSystem, true);
    world.registerFunctionSelector(systemId, "incrementMessage(string)");

After the function selector is registered, it can be accessed directly on the World:


Root function selectors

The owner of the root namespace can use registerRootFunctionSelector (opens in a new tab) to register an arbitrary string as a function signature.

This function has three parameters:

  • The ResourceId of the System to be called
  • The signature of the World` function (as a string)
  • The selector of the System function (as the four-byte signature)

This means that the World's function name for a function in a root System can be any string, it does not need to correlate to the name inside the System.

For example, the root namespace owner could register message:incrementMessage(string) using this code

    ResourceId systemId = WorldResourceIdLib.encode(RESOURCE_SYSTEM, "messaging", "message");
    world.registerRootFunctionSelector(systemId, "incrementMessage(string)", bytes4(0x80e40162));

After the function selector is registered, it can be accessed directly on the World: