# 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, 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).&#x20;

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

```javascript
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` .

```javascript
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.

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

```javascript
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.

```javascript
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.

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

## [Zetrix Ecosystem Proposals](https://github.com/Zetrix-Chain/zetrix-protocol)

Sample ZTP1155 contract can be found [here](https://github.com/Zetrix-Chain/zetrix-protocol/blob/main/ZTP/ZTP-1155.js).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.zetrix.com/en/developer-resources/smart-contract/ztp-standard/ztp-1155.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
