MultiOperatorHost Extension

MultiOperatorHost Extension code - MultiOperatorHost Extension address

Factory Approach

The MultiOperatorHost Extension, implementing the LazyInitCapableElement contract, is factory-capable contract, meaning that it can be cloned and initialized via the Extension Factories. Only the EthereansOS private team multi-sig has the right to add a new Extension clonable model to the Extension Factories while everyone can clone an Extension from one of the available models.

Granular Permissions

The Extension can assign two permissions to two operators:

  1. Create and / or mint Items

  2. Change Collection and / or Item metadata

Only the name, symbol and uri of an Item can be changed by the Extension; the host cannot be changed.

Permissions are assigned when an Extension is cloned from the Extension Factory and initialized. (see here)

An assigned Operator address—and no one else—can reassign the permission to a new Operator address.

There can only be one Operator address per permission:

function setOperator(uint256 op, address newValue) external override returns(address oldValue) {
    require(operator[op] == msg.sender, "Unauthorized");
    return _setOperator(op, newValue);

The permission table is managed via the _subjectIsAuthorizedFor function:

function _subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata, uint256) internal virtual override view returns(bool, bool) {
    //1 = mintItems, 4 = setMetadata.
    uint256 op = selector == this.mintItems.selector ? 1 :
        (selector == this.setHeader.selector || selector == this.setItemsMetadata.selector) ? 4 : 0;
    return(true, op > 0 && location == address(this) && operator[op] == subject);

To reiterate, permissions aside from the two outlined above can’t be assigned and once a Collection is linked to a MultiOperatorHost, it can’t be linked to another extension


An itemId created via an Extension has 18 decimals on both the Main interface (the ERC1155 interface) and on its Interoperable Interface (its ERC20 interface).

MultiOperatorHost deploy and initialization

When you deploy a MultiOperatorHost Extension, you also automatically create the Items collection.

The MultiOperatorHost Extension must be cloned using the deploy method of the Extension Factory:

function deploy(bytes calldata deployData) external payable override(Factory, IFactory) returns(address deployedAddress, bytes memory deployedLazyInitResponse)

To correctly initialize the MultiOperatorHost Extension, you have to pass the deployData in this way:

//MultiOperatorHost Extension Operators, i.e. mint operator and Metadata operator
var data = web3.eth.abi.encodeParameters(["uint256[]", "address[]"], [[],[]]);
//Collection data to create the Items Collection within the Extension
data = abi.encode(
  [utilities.voidBytes32, header, item, data]
//LazyInitCapableElement -> pass as address(0)
data = web3.eth.abi.encodeParameters(["address", "bytes"], [utilities.voidEthereumAddress, data]);
//Factory model index
data = web3.eth.abi.encodeParameters(["uint256", "bytes"], [0, data]);

//Clone the Extension using the Extension Factory
var transaction = await itemProjectionFactory.methods.deploy(data).send({from : accounts[1]});

Actually, using the current existing Extension models, you can’t do this because the host of a Collection can’t be changed after contract initialization.

So you have to create the Collection within the Extension


Change Operators addresses

function setOperator(uint256 op, address newValue) external override returns(address oldValue)li
  • Function type: write

  • Callable by:

    • Operator address

This function is used to change an Operator address and can only be called by a current Operator address. For example, the Operator with permission to create and / or mint Items can call it to give up its permission to a new Operator.

Create/Mint Items

function mintItems(CreateItem[] memory items) authorizedOnly virtual override public returns(uint256[] memory itemIds)
  • Function type: write.

  • Callable by:

    • Operator address with the minting permission

This function can be used to create a new Item id or to mint a new amount of an existing Item id inside an already existing Collection.

In the first case, the id parameter of the CreateItem must be passed as 0. In the second case, it must be passed as the existing item id to mint.

Change Collection and Items Metadata

Change Collection Metadata

function setHeader(Header calldata value) authorizedOnly external returns(Header memory oldValue);
  • Function type: write.

  • Callable by:

    • Operator address with the Metadata permission

This function is used to change the Header, and thereby the metadata, of the Collection linked to the Extension.

The input function is the new Header struct (address host, string name, string symbol, string uri).

The host address cannot be changed.

The function output represents the old Collection Header.

Change Items Metadata

function setItemsMetadata(uint256[] calldata itemIds, Header[] calldata values) authorizedOnly override external returns(Header[] memory oldValues);
  • Function type: write

  • Callable by:

    • Operator address with the Metadata permission

This function is used to change the Collection’s Items Metadata. As input, it takes an array of itemIds, and a corresponding new Header struct that contains the new Metadata.

Keep in mind that an Item has no host, so even if a host address is passed, the host will automatically be set as address(0).

The function’s output represents the old Items’ Header.

Last updated