Skip to content

OTP-001: 支持的接口

该提案建议了一种方法来内省智能合约并找出它们支持哪些接口。

动机

目前,无法猜测用户想对合约做什么,或者无法弄清楚交易的内容,因为没有明确的方法来了解合约的功能。人类需要记住或猜测大多数情况下合约的用途。

指南

当人类尝试签署交易时,他们需要清楚地了解自己在做什么:铸币、代币转移、质押、DAO 投票。虽然以太坊钱包支持签署任意结构,但仍不清楚你在签署什么以及这样做的影响。同样,浏览器也无法以良好的形式显示发生的事情。

与特定合约开始工作的一步是进行内省——弄清楚合约声明了什么。当应用程序知道这个合约的内容时,它可以构建一个良好的用户界面,显示交易历史,并验证人类尝试签署的内容。

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

接口在自由格式规范中定义。与大多数其他方法不同,该提案将接口定义为不仅仅是合约的技术接口(例如 get 方法、内部消息等),还包括其行为描述。附加一个技术接口表示的哈希可能会导致不同标准之间的冲突,因此本提案松散地定义接口。此外,它允许接口更加灵活,例如不能转移的代币可能只是一个合约,该合约必须具有 can_transfer 方法,该方法返回 false,这意味着该代币根本不支持转移而无需实现此方法。

接口 ID 是反向域名的哈希(类似于 Java 中的包),这避免了不同团队之间的名称冲突,如果他们想为自己构建某些东西。

规范

为了支持内省,合约必须实现 supports_interface GET 方法:

solidity
(int...) supported_interfaces()

该方法返回支持的接口代码列表。第一个值必须是 hash("org.ton.introspection.v0") = 123515602279859691144772641439386770278。如果第一个值不正确,应用程序必须停止尝试内省合约。

示例:

solidity
_ supported_interfaces() method_id {
    return (123515602279859691144772641439386770278);
}

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

缺点

该提案不保证合约会正确响应接口,也不提供避免不同接口之间名称冲突的保证。这不是该提案的目标。

该提案不绑定到特定的技术接口。这可能导致多个接口执行相同的操作但具有不同的 ID。这不是该提案的目标,因为集中注册现有接口非常有用,而自定义接口主要用于内部。

原因和替代方案

  • 为什么是 128 位?我们需要维护一个无冲突的全球命名空间,不能使用更小的位数,因为冲突的概率会大大增加。我们需要类似 UUID 的熵,正好是 128 位,并且经过时间验证。超过 128 位则太浪费。
  • 为什么是自由格式?如前所述,定义一些 ID 以早期开始工作更容易,然后逐步建立标准。此外,接口(如 ERC20)通常不仅是技术接口,还有一些关于如何使用它的规则。
  • 为什么不通过反编译找出合约支持的内容?在开放世界场景中,显式总是比隐式更好。我们不能依赖我们的“反汇编”能力来进行内省,即使是小错误也可能是致命的。
  • 为什么不是表示的哈希?目前没有支持的编译器,而且该提案是面向未来的。如果有人想构建更自动化的东西,他们可以按照自己的规则轻松构建自己的哈希,并保持对外部观察者一切不变。

先前的工作

以太坊接口检测