# ZTP-165

## Introduction

### What is the  Protocol ZTP-165

`ZTP165` provides a protocol standard similar to `ZEP165` and `ERC165` for detecting smart contract interfaces on the `ZTP` blockchain. It specifies how smart contracts can declare and validate their supported interfaces, ensuring compatibility and ease of integration between different smart contracts.

The `ZTP165` standard introduces a way for contracts on the ZTP blockchain to explicitly declare the interfaces they support. This allows other contracts to interact seamlessly with them, by querying supported interfaces and adjusting their functionality accordingly.

### **Protocol Overview**

#### **Interface Function**

Contracts implementing `ZTP165` must include the following function:

```javascript
const IZEP165 = {
  supportsInterface: function() {
    return this;
  }
};
```

#### **Support Interface Function**

```javascript
this.supportsInterface = function(interfaceId) {
    let iface1 = Utils.sha256(JSON.stringify(IZEP165), 1);
    let iface2 = Utils.sha256(JSON.stringify(IOptimismMintableZTP20), 1);
    return interfaceId === iface1 || interfaceId === iface2;
};
```

#### **Support Interface Validation in Init Function**

```javascript
function init(input_str) {
  let input = JSON.parse(input_str);

  Utils.assert(implementsInterface(OptimismMintableZTP20, IOptimismMintableZTP20), 'OptimismMintableZTP20 does not implement IOptimismMintableZTP20');
  Utils.assert(implementsInterface(OptimismMintableZTP20, IZEP165), 'OptimismMintableZTP20 does not implement IZEP165');

  return true;
}
```

#### **Usage**

```javascript
this.isOptimismMintableZTP20 = function (token) {
    let interfaceId = utils.sha256(JSON.stringify(interfaceId), 1);
    let queryInput = {
        'method': 'supportsInterface',
        'params': {
            'interfaceId' : interfaceId
        }
    };

    let ret = Chain.contractQuery(token, JSON.stringify(queryInput));
    utils.assert(ret !== false, 'Contract does not exist');

    if (ret.err === null && ret.error) {
        return false;
    }

    return JSON.parse(ret.result).data;
    
```

### Full ZTP-165 contract example:

```javascript
'use strict';

const IOptimismMintableZTP20 = {
  remoteToken: function() {
    return this;
  },
  bridge: function() {
    return this;
  },
  mint: function() {
    return this;
  },
  burn: function() {
    return this;
  }
};

const IZEP165 = {
  supportsInterface: function() {
    return this;
  }
};

function implementsInterface(obj, interfaceObj) {
  let keys = Object.keys(interfaceObj);
  let i;
  for (i = 0; i < keys.length; i += 1) {
    if (!obj.hasOwnProperty(keys[i]) || typeof obj[keys[i]] !== "function") {
      return false;
    }
  }
  return true;
}

const OptimismMintableZTP20Class = function() {
  this.remoteToken = function() {
    Chain.tlog('remoteToken1');
  };

  this.bridge = function() {
    Chain.tlog('bridge1');
  };

  this.mint = function() {
    Chain.tlog('mint1');
  };

  this.burn = function() {
    Chain.tlog('burn1');
  };

  this.supportsInterface = function(interfaceId) {
    let iface1 = Utils.sha256(JSON.stringify(IZEP165), 1);
    let iface2 = Utils.sha256(JSON.stringify(IOptimismMintableZTP20), 1);
    return interfaceId === iface1 || interfaceId === iface2;
  };
};

const OptimismMintableZTP20 = new OptimismMintableZTP20Class();

function init(input_str) {
  let input = JSON.parse(input_str);

  Utils.assert(implementsInterface(OptimismMintableZTP20, IOptimismMintableZTP20), 'OptimismMintableZTP20 does not implement IOptimismMintableZTP20');
  Utils.assert(implementsInterface(OptimismMintableZTP20, IZEP165), 'OptimismMintableZTP20 does not implement IZIP165');

  return true;
}

function main(input_str) {
  let input = JSON.parse(input_str);
  let params = input.params;

  let result = {};
  if (input.method === 'mint') {
    OptimismMintableZTP20Class.mint();
  } else {
    throw 'Unknown operating: ' + input.method + '.';
  }
  return JSON.stringify(result);

}

function query(input_str) {
  let input = JSON.parse(input_str);
  let params = input.params;

  let result = {};
  if (input.method === 'supportsInterface') {
    result.data = OptimismMintableZTP20.supportsInterface(params.interfaceId);
  } else {
    throw 'Unknown operating: ' + input.method + '.';
  }

  return JSON.stringify(result);
}
```


---

# 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-165.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.
