ZTP-1155

Method
Description

name

Token Name. Example: “Global Coin”

symbol

Token Symbol. Example: GCN

describe

Token description: “Global coin token issued by XYZ”

version

Token version

Simple Summary

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).

Abstract

This standard outlines a smart contract interface that can represent any number of fungible and non-fungible token types. Existing standards such as ZTP-20 require deployment of separate contracts per token type. The ZTP-721 standard’s token ID is a single non-fungible index and the group of these non-fungibles is deployed as a single contract with settings for the entire collection. In contrast, the ZTP-1155 Multi Token Standard allows for each token ID to represent a new configurable token type, which may have its own metadata, supply and other attributes.

The id argument contained in each function’s argument set indicates a specific token or token type in a transaction.

Motivation

Tokens standards like ZTP-20 and ZTP-721 require a separate contract to be deployed for each token type or collection. This places a lot of redundant bytecode on the Ethereum blockchain and limits certain functionality by the nature of separating each token contract into its own permissioned address. With the rise of blockchain games and platforms like Enjin Coin, game developers may be creating thousands of token types, and a new type of token standard is needed to support them. However, ZTP-1155 is not specific to games and many other applications can benefit from this flexibility.

New functionality is possible with this design such as transferring multiple token types at once, saving on transaction costs. Trading (escrow / atomic swaps) of multiple tokens can be built on top of this standard and it removes the need to “approve” individual token contracts separately. It is also easy to describe and mix multiple fungible or non-fungible token types in a single contract.

Specification Token Methods

safeTransferFrom

Transfers value amount of an id from the from address to the to address specified (with safety call).

data is an additional field with no specified format, MUST be sent unaltered in call to onZTP1155Received on to .

self.safeTransferFrom = function (paramObj) {
    let sender = Chain.msg.sender;
    Utils.assert(paramObj.from === sender || self.isApprovedForAll({
        account: paramObj.from,
        operator: sender
    }), "ERC1155: Missing approval for all");
    _safeTransferFrom(paramObj.from, paramObj.to, paramObj.id, paramObj.value, paramObj.data);
};

safeBatchTransferFrom

Transfers values amount(s) of ids from the from address to the to address specified (with safety call).

data is an additional data with no specified format, MUST be sent unaltered in call to the ZTP1155TokenReceiver hook(s) on to .

self.safeBatchTransferFrom = function (paramObj) {
    let sender = Chain.msg.sender;
    Utils.assert(paramObj.from === sender || self.isApprovedForAll({
        account: paramObj.from,
        operator: sender
    }), "ERC1155: Missing approval for all");
    _safeBatchTransferFrom(paramObj.from, paramObj.to, paramObj.ids, paramObj.values, paramObj.data);
};

balanceOf

Get the balance of an account's tokens for the token type requested.

self.balanceOf = function (paramObj) {
    let balance = BasicOperationUtil.loadObj(BasicOperationUtil.getKey(BALANCES_PRE, paramObj.id, paramObj.account));
    if (balance === false) {
        return "0";
    }
    return balance;
};

balanceOfBatch

The owner's balance of the token types requested (i.e. balance for each (owner, id) pair).

self.balanceOfBatch = function (paramObj) {
    Utils.assert(paramObj.accounts.length === paramObj.ids.length, 'Invalid array length');

    let batchBalances = [];
    let i;
    for (i = 0; i < paramObj.accounts.length; i += 1) {
        batchBalances.push(self.balanceOf({id: paramObj.ids[i], account: paramObj.accounts[i]}));
    }
    return batchBalances;
};

setApprovalForAll

Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. Returns true if the operator is approved, false to revoke approval.

self.setApprovalForAll = function (paramObj) {
    self.p.setApprovalForAll(Chain.msg.sender, paramObj.operator, paramObj.approved);
};

isApprovedForAll

Queries the approval status of an operator for a given owner.

self.isApprovedForAll = function (paramObj) {
    return BasicOperationUtil.loadObj(BasicOperationUtil.getKey(OPERATOR_APPROVAL_PRE, paramObj.owner, paramObj.operator));
};

Sample ZTP1155 contract can be found here.

Last updated