一、概述

本标准定义了以下内容:

  • API / 工具应以什么格式返回地址。
  • API / 工具应以什么格式接受地址。
  • 地址应如何显示。
  • 地址应如何存储。

1. 不在范围内

先前的讨论主要围绕如何区分各种地址、公钥/私钥及其他数据的十六进制表示方式。同时,也探讨了地址表示法的一种更加紧凑的形式。但这个标准并不涉及上述讨论内容(它们更类似于一个 v2 版本的标准),它的目标仅仅是将我们目前使用的做法(v1)标准化。

二、动机

在 Aptos 区块链中,每个账户或对象都有一个32字节长度的唯一账户地址来进行标识。在内部处理时,地址就是以一个32字节的序列形式存在。但在传输与展示这些地址时,常常采用十六进制的格式。目前,还没有一个统一标准来规定这些地址在不同场景下应该如何展示。由于表示一个地址有多种在技术上都正确的方法,这就造成了一个分裂的生态,不同的 API、工具和产品在表示和接受地址时各不相同。这种情况可能会在查询链上数据和提交格式正确的交易时造成问题。

三、影响

此 AIP 仅定义了一个标准。我们的意图是,现有的 API 将继续以它们当前的方式返回地址,以避免破坏任何下游用户。然而,新产品必须符合这个新定义的标准。

因此,需要根据此 AIP 采取行动的人通常是平台开发人员,例如 API、工具、钱包等的开发人员。

四、理由

1. 可选方案:立即迁移到新标准

我们可以直接跳过 v1 标准,立即迁移到 v2 标准。在这个标准中,我们可以彻底改变所有标识符(地址、公钥、私钥、资源、字节的表示方式等)。我们可以这样做,但我怀疑讨论、实施和迁移将需要很长的时间。因此,最好是先为现有情况定义一个标准,然后再考虑 v2 标准。

2. 可选方案:将所有地址表示为长格式

在这个替代的世界中,我们不会以不同的方式显示特殊地址(见下文定义),而是只使用长格式。这将使标准更简单,但用户体验会较差,人们习惯于看到特殊地址(下文定义)以短格式表示,例如 0x1。事实上,允许特殊地址使用短格式表示有一些好处,例如避免恶意行为者显示看起来像特殊地址但实际上不是的地址,例如 0x0{62}1 vs 0x0{63}1

在这种情况下,我们不会对特殊地址(具体定义见下文)进行不同的展示处理,而是统一使用扩展形式(长格式)展示。这样虽然能够简化标准,但会大打折扣用户体验——用户已经习惯了看到特殊地址以缩写形式出现,如 0x1 等。事实上,允许特殊地址以缩写形式表示有其优势,例如它可以预防恶意行为者展示类似特殊地址但实际上并非如此的地址,例如一个地址是 0x0 后面跟62个零再加上1,而另一个地址是 0x0 后面跟63个零再加上1 (e.g. 0x0{62}1 vs 0x0{63}1)。

五、规范

1. 格式

1.1 LONG

表示:

0x<64 个十六进制字符>

示例:

0x0000000000000000000000000000000000000000000000000000000000000001
0x14b6041b77304fe9354aba2e0b1a0ae51d816d0513332ef651a039fac90339cb
0x043ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2

1.2 SHORT

表示:

0x<十六进制字符,去掉前导零>

示例:

0x1
0x14b6041b77304fe9354aba2e0b1a0ae51d816d0513332ef651a039fac90339cb
0x43ec2cb158e3569842d537740fd53403e992b9e7349cc5d3dfaa5aff8faaef2

1.3 不带 0x 前缀的 LONG

LONG 相同,但没有 0x 前缀。

1.4 不带 0x 前缀的 SHORT

SHORT 相同,但没有 0x 前缀。

2. 特殊地址

如果在 0x 前缀后的十六进制字符串的前63个字符都是零,则地址被视为特殊地址。换句话说,如果前31个字节都是零,最后一个字节小于 0b10000(16),则地址是特殊地址。换句话说,特殊地址被定义为与以下正则表达式匹配的地址:^0x0{63}[0-9a-f]$。简而言之,这意味着从 0x00xf(包括这两个值)范围内的地址都是特殊地址。

参考实现中对此进行了更详细的解释。

3. 可接受的输入格式

解析 / 验证表示账户地址的字符串的函数必须接受以下格式(其中前面的 0x 是必需的):

  1. 长格式(LONG)
  2. 特殊地址的短格式(SHORT)

此外,解析 / 验证账户地址的函数可以接受以下格式:

  1. 具有或不具有前导 0x 的长格式
  2. 对所有地址(而不仅仅是特殊地址)具有或不具有前导 0x 的短格式

以下列举的是目前已经广泛使用的若干地址表示方法。实现这些格式可能是为了保持与现有生态的向后兼容性。这是必要的,因为有些工具目前返回的账户地址使用的就是这些格式,如果不考虑向后兼容性的话,将无法更新这些工具。

在可行的情况下,开发者应当尽量不采用这些格式(比如在开发 API、钱包、工具等软件时),但如果是出于保持向后兼容性的考虑,使用这些格式也是可以接受的。

此原则的参考实现可以在 v2 TypeScript SDK 中找到:

  • fromString:这个更严格的函数只接受格式 12 的地址。
  • fromStringRelaxed:这个更宽松的函数接受格式 1234 的地址。

4. 显示格式

这部分描述了地址应该如何显示。此处的显示指的是任何向用户显示地址的情况,包括在 Web UI、日志、编译器中的输出等。

  • 应该使用 SHORT 格式表示特殊地址。
  • 所有其他地址必须使用 LONG 格式表示。

5. 响应格式

此部分定义了当采用十六进制格式表示地址时,API(如节点和索引器所提供的接口)以及其他编程接口应如何返回这些地址信息。

  • 地址必须使用与显示格式相同的规则进行格式化。

6. 静态格式

一些系统,比如索引器处理器在写入存储时,使用字符串表示来存储地址。

  • 地址应该使用与显示格式相同的规则进行格式化。

注意:首选地址的二进制表示形式。

7. 二进制格式

在使用二进制表示时,地址必须以规范格式的BCS编码。

六、参考实现

v2 TypeScript SDK 中的 toString 函数的实现以符合标准的方式返回账户地址字符串。

fromStringfromStringRelaxed 函数实现了上述标准中描述的解析 / 验证方面。

七、风险和缺点

鉴于不同的工具、网站等已经以不同的方式表示 / 接受地址,这个标准不应进一步分裂生态系统,而是将其统一起来。此外,我们没有计划对现有的 API 进行重大更改。因此,风险应该是最小的。

八、时间表

在这一部分,我概述了我们必须实施变更的顺序。我将具体日期的确定留给以后处理。

1. 确保符合标准的地址库存在

在我们支持的主要语言(TypeScript、Rust 和 Python)中,我们必须确保有符合标准的 AccountAddress 类。我们还应该努力支持其他重要的语言,如 C#。这基本上意味着以下函数必须存在:

  • 一个函数,将地址输出为符合标准的字符串。
  • 一个函数,按照符合标准的方式从字符串中解析地址(严格和放宽)。
  • 一个函数,检查地址的相等性(实质上是结合了前两个函数)。

参考实现已经为 Rust 实现了这一点。给定这些变化是轻微的,TypeScript 和 Python 将会很快跟进。

2. 发布指南,解释如何处理地址

总的来说,这个指南将是这个 AIP 的精简、以代码为中心的版本,参考我们添加的库和下面建议的迁移时间表。

我们将与生态系统中的构建者联系,提供明确的行动计划清单。很可能有许多工具已经在某种/全部方面符合标准,所以需要变化的部分应该是很小的。在其他情况下,只需更新依赖项以使用 SDK 的新版本即可。

3. 将接受地址输入的产品进行更新,以确保它们遵循相关标准。

在对地址的显示 / 返回 / 存储方式进行任何更改之前,我们必须更新所有接受地址作为输入的地方,使其符合标准。在所有情况下,接受的地址应该比之前更具宽容性,因为标准的目标是在输入端具有宽容性。

可能需要更改的内容示例:

  • API
    • 节点 API(Node APIs)
    • 索引器 API(Indexer APIs)
    • 生态系统参与者运行的任何其他 API
  • 命令行界面
    • aptos 命令行界面(The aptos CLI)
  • 钱包
  • Dapp
    • 浏览器(Explorers)
    • 市场(Marketplaces)
    • 分析平台(Analytics platforms)
  • SDK
    • TypeScript
    • Rust
    • Python
  • 配置
    • 节点配置(Node configs)
    • 命令行界面配置(CLI configs)
    • 处理器配置(Processor configs)

在一般情况下,如果一个工具只接受特定格式的地址,而另一个以不同格式提交地址,则可能会引起问题。这就是为什么在我们更改输出格式之前,必须首先使任何接受地址作为输入的内容更具宽容性,整个生态系统都要这样做。

4. 对于那些与地址相关的产品进行升级,以便它们采用新引入的地址比对函数。

这个 AIP 的主要动机之一是由于在不同格式中比较地址而导致的问题。任何进行这种操作的产品(参见上面的列表)都必须迁移到新的相等性函数,这些函数将处理上述可接受输入格式中的地址。

5. 更新返回 / 显示地址的产品以符合标准

此时,应该可以安全地更新所有产品,以标准符合的方式显示(对于图形工具)或返回(对于以字符串形式返回地址的编程工具)地址。

6. 安全考虑

通过不允许接受 SHORT 地址作为非特殊地址,我们使钓鱼行为 / 错误变得更加困难(例如,通过省略前导零来尝试欺骗用户)。就我所知,此 AIP 没有任何显着的安全缺陷。

7. 测试

参考实施的测试计划。