Function selectors
You can call a System
using call
(opens in a new tab).
When you use this method, you provide two parameters.
- The
ResourceId
for theSystem
to be called. - The calldata (opens in a new tab) to send that system.
This calldata includes the four-byte function selector (opens in a new tab), as well as any function parameters.
To get the calldata, you can use
abi.encodeCall
(opens in a new tab).
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:
- The
ResourceID
of theSystem
. This value encodes both the namespace and the name of theSystem
. - The signature (name and parameter types) (opens in a new tab) of the function within the
System
.
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:
world.messaging__incrementMessage("hello");
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 theSystem
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:
world.incrementMessage("hello");