Function selectors
You can call a System using call (opens in a new tab).
When you use this method, you provide two parameters.
- The
ResourceIdfor theSystemto 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
ResourceIDof 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
ResourceIdof theSystemto be called - The signature of the World` function (as a string)
- The selector of the
Systemfunction (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");