MLD-1155: Multi-token standard

MLD-1155 is a mirror of ERC-1155 on Ethereum and is a standard interface for contracts that manage multiple token types. A single deployed contract may include any combination of fungible tokens, non-fungible tokens or other configurations (e.g. semi-fungible tokens).

What is meant by Multi-Token Standard?

The idea is simple and seeks to create a smart contract interface that can represent and control any number of fungible and non-fungible token types. In this way, the MLD-1155 token can do the same functions as an MLD-20 and MLD-721 token, and even both at the same time. It improves the functionality of both the MLD-20 and MLD-721 standards, making it more efficient and correcting obvious implementation errors.

MLD-1155 Functions & Features

Batch Transfer: Transfer multiple assets in a single call. Batch Balance: Get the balances of multiple assets in a single call. Batch Approval: Approve all tokens to an address. Hooks: Receive tokens hook. NFT Support: If supply is only 1, treat it as NFT. Safe Transfer Rules: Set of rules for secure transfer.

Batch Transfers

The batch transfer works very similarly to regular MLD-20 transfers. Let's look at the regular MLD-20 transferFrom function:


// MLD-1155
function safeBatchTransferFrom(
    address _from,
    address _to,
    uint256[] calldata _ids,
    uint256[] calldata _values,
    bytes calldata _data
) external;

The only difference in NFT-1155 is that we pass the values as an array and we also pass an array of ids. For example, given ids=[3, 6, 13] and values=[100, 200, 5], the resulting transfers will be

  1. Transfer 100 tokens with id 3 from _from to _to.

  2. Transfer 200 tokens with id 6 from _from to _to.

  3. Transfer 5 tokens with id 13 from _from to _to.

In MLD-1155 we only have transferFrom, no transfer. To use it like a regular transfer, just set the from address to the address that's calling the function.

Batch Balance

The respective MLD-20 balanceOf call likewise has its partner function with batch support. As a reminder, this is the MLD-20 version:


// MLD-20
    function balanceOf(address owner) external view returns (uint256);

// MLD-1155
    function balanceOfBatch(
    address[] calldata _owners,
    uint256[] calldata _ids
) external view returns (uint256[] memory);

Even simpler for the balance call, we can retrieve multiple balances in a single call. We pass the array of owners, followed by the array of token ids.

For example given _ids=[3, 6, 13] and _owners=[0xbeef..., 0x1337..., 0x1111...], the return value will be

[
   balanceOf(0xbeef...),
   balanceOf(0x1337...),
   balanceOf(0x1111...)
   ]

Batch Approval

// MLD-1155
function setApprovalForAll(
    address _operator,
    bool _approved
) external;
    
function isApprovedForAll(
    address _owner,
    address _operator
    ) external view returns (bool);

The approvals are slightly different than MLD-20. Instead of approving specific amounts, you set an operator to approved or not approved via setApprovalForAll.

Reading the current status can be done via isApprovedForAll. As you can see, it's an all-or-nothing operation. You cannot define how many tokens to approve or even which token class.

This is intentionally designed with simplicity in mind. You can only approve everything for one address.

Receive Hook

function onMLD1155BatchReceived( 
    address _operator,
    address _from,
    uint256[] calldata _ids,
    uint256[] calldata _values,
    bytes calldata _data
) external returns(bytes4); 

Given the EIP-165 support, MLD-1155 supports receive hooks for smart contracts only. The hook function must return a magic predefined bytes4 value which is given as:

bytes4(keccak256("onMLD1155BatchReceived(address,address,uint256[],uint256[],bytes)")) Copy

When the receiving contract returns this value, it is assumed the contract accepts the transfer and knows how to handle the MLD-1155 tokens.

NFT Support

When the supply is just one, the token is essentially a non-fungible token (NFT). And as is standard for MLD-721, you can define a metadata URL. The URL can be read and modified by clients

Safe Transfer Rule

We've touched on a few safe transfer rules already in the previous explanations. But let's look at the most important of the rules:

  1. The caller must be approved to spend the tokens for the _from address or the caller must equal _from.

  2. The transfer call must revert if

    1. _to address is 0.

    2. length of _ids is not the same as length of _values.

    3. any of the balance(s) of the holder(s) for token(s) in _ids is lower than the respective amount(s) in _values sent to the recipient.

    4. any other error occurs.

Note: All batch functions including the hook also exist as versions without batch. This is done for gas efficiency, considering transferring just one asset will likely still be the most commonly used way. We've left them out for simplicity in the explanations, including safe transfer rules. The names are identical, just remove the 'Batch'.

Last updated