---
title: OTP-001：支持的接口
description: 此提案建议了一种方法，用于检查智能合约并确定其支持哪些接口
sidebar:
  order: 1
---

此提案建议了一种方法，用于检查智能合约并确定其支持哪些接口。

## 动机

现在，我们无法猜测用户想用合约做什么，也无法弄清交易的内容，因为没有明确的方法找到合约的内容。 在大多数情况下，人类需要记住或猜测这是怎么回事。

## 指南

当人们试图签署一项交易时，他们需要清楚地了解自己在做什么：铸币、代币转移、质押、DAO 投票。 虽然以太坊钱包支持签署任意结构，但仍不清楚您签署的是什么以及这样做的影响。 同样，区块链浏览器无法以直观的形式展示正在发生的事情。

与特定合约交互的起点是执行反推操作，即弄清楚该合约对自身的声明。 当应用程序知道这份合约的内容时，它就可以建立一个良好的用户界面，显示交易历史，并验证人类试图签署的内容。

该提案描述了一种报告合约支持哪些接口的方法。

接口是以自由格式的规范定义的。 与其他大多数方法不同的是，本提案不仅将接口定义为合约的技术接口（获取方法、内部信息等），还将其定义为合约行为的描述。 附加一个合约技术接口表示的哈希值可能会导致不同标准之间的冲突，因此该提案对接口的定义较为宽松。 此外，这种方法使接口更加灵活，例如，一个无法转移的代币可以仅是一个合约，它包含一个返回 `false` 的方法 `can_transfer`。这就意味着该代币完全不支持转移，而无需实际实现转移功能。

接口 ID 是反向域名（类似于 Java 中的包）的哈希值，这可以避免不同团队在为自己构建功能时发生名称冲突。

## 技术说明

为了支持反推，合约必须实现 supports_interface GET 方法：

`(int...) supported_interfaces()`
返回支持的接口代码列表。 第一个值必须是 `hash("org.ton.introspection.v0")` = `123515602279859691144772641439386770278`。
如果第一个值不正确，应用程序必须停止尝试反推合约。
示例

```func
_ supported_interfaces() method_id {
    return (123515602279859691144772641439386770278);
}
```

接口的哈希值定义为截断为 128 位的 SHA256。

## 缺点

这项建议并不能保证合约对接口的正确执行，也不能保证避免不同接口之间的名称冲突。 这不是本提案的目标。

这项建议与特定的技术接口无关。 这可能导致多个接口做同样的事情，但 ID 不同。 这是该提案的非目标，因为一个集中式的注册表对于现有接口非常有用，而自定义的注册表主要是内部使用。

## 理由和替代方案

- 为什么是 128 位？ 我们需要在不发生冲突的情况下保留一个全局命名空间，我们不能使用小得多的命名空间，因为发生冲突的可能性会高得多。 我们正在研究类似 UUID 的熵，它正好是 128 位，并且经过时间验证。 超过 128 太浪费了。
- 为什么是自由形式？ 如前所述，定义一些 ID 更容易尽早开始工作，然后最终建立一个标准。 此外，接口（如 ERC20）通常不仅仅是一个技术接口，还包括一些如何使用它的规则。
- 为什么不通过反编译找出合约支持什么？ 在开放世界场景中，明示总比暗示好。 我们不能依靠自己的 "拆解 "能力来进行反推，即使是很小的错误也可能是致命的。
- 为什么不使用表示的哈希值？ 目前还没有编译器支持这一点，而且这项建议是面向未来的。 如果有人想构建更自动化的东西，他们可以很容易地按照自己的规则构建自己的哈希值，对外部观察者而言，一切保持不变。

## 现有技术

[以太坊接口检测](https://eips.ethereum.org/EIPS/eip-165)
