Alert Source Discuss
🚧 Stagnant Standards Track: ERC

ERC-1319: 智能合约包注册表接口

Authors Piper Merriam <piper@ethereum.org>, Christopher Gewecke <christophergewecke@gmail.com>, g. nicholas d'andrea <nick.dandrea@consensys.net>, Nick Gheorghita (@njgheorghita)
Created 2018-08-13
Discussion Link https://github.com/ethereum/EIPs/issues/1319

简单概述

智能合约包注册表的标准接口。

摘要

本 EIP 指定了与智能合约包注册表进行发布和检索资产的接口。它是 1123 的配套 EIP,后者定义了智能合约包清单的标准。

动机

目标是建立一个框架,允许智能合约发布者设计和部署具有任意业务逻辑的代码注册表,同时公开一组常用端点,工具可以使用这些端点来检索合约消费者的资产。

一个清晰的标准将有助于现有的 EthPM 包注册表从一个中心化的、单一项目的社区资源发展成为一个去中心化的多注册表系统,其组成部分通过提议的接口绑定在一起。反过来,这些注册表可以使用 ENS 命名空间,从而实现 npm 和其他包管理器用户熟悉的安装约定。

示例

$ ethpm install packages.zeppelin.eth/Ownership
const SimpleToken = await web3.packaging
                              .registry('packages.ethpm.eth')
                              .getPackage('simple-token')
                              .getVersion('^1.1.5');

规范

该规范描述了一个小的读/写 API,其组件是强制性的。它允许注册表使用 semver 的约定来管理版本化的发布,而无需将其作为要求。它假设注册表将共享以下结构和约定:

  • 注册表(registry) 是一个部署的合约,用于管理 包(packages) 的集合。
  • 包(package)发布(releases) 的集合
  • 包(package) 由给定的 注册表(registry) 中的唯一字符串名称和唯一的 bytes32 packageId 标识
  • 发布(release)bytes32 releaseId 标识,对于给定的包名称和发布版本字符串对,该 releaseId 必须是唯一的。
  • releaseId 映射到一组数据,其中包括 manifestURI 字符串,该字符串描述了 EIP 1123 包清单 的位置。该清单包含有关发布的数据,包括其组件代码资产的位置。
  • manifestURI 是由 RFC3986 定义的 URI,可用于检索包清单的内容。除了针对 RFC3986 进行验证外,每个 manifestURI 还必须包含内容的哈希,如 EIP-1123 中所述。

示例

包名称 / 发布版本

"simple-token" # 包名称
"1.0.1"        # 版本字符串

发布 ID

实现可以自由选择任何方案来生成 releaseId。一种常见的方法是将字符串哈希在一起,如下所示:

// 哈希包名称和发布版本字符串
function generateReleaseId(string packageName, string version)
  public
  view
  returns (bytes32 releaseId)
  {
    return keccak256(abi.encodePacked(packageName, version));
  }

实现 必须 公开此 ID 生成逻辑作为其公共 read API 的一部分,以便 工具可以轻松地将基于字符串的发布查询映射到注册表中该发布的唯一标识符。

清单 URI

任何 IPFS 或 Swarm URI 都符合 manifestURI 的定义。

另一个例子是 GitHub 上的内容,通过其 SHA-1 哈希寻址。可以通过运行以下命令获得此哈希处的 Base64 编码内容:

$ curl https://api.github.com/repos/:owner/:repo/git/blobs/:file_sha

# Example
$ curl https://api.github.com/repos/rstallman/hello/git/blobs/ce013625030ba8dba906f756967f9e9ca394464a

可以通过将其与以下输出进行比较,来独立验证字符串“hello”的 GitHub SHA-1 哈希:

$ printf "blob 6\000hello\n" | sha1sum
> ce013625030ba8dba906f756967f9e9ca394464a

写入 API 规范

写入 API 由单个方法 release 组成。它将包名称、发布的版本标识符和指定清单位置的 URI 传递给注册表,其中 清单详细说明了发布的内容。

function release(string packageName, string version, string manifestURI) public
  returns (bytes32 releaseId);

事件

VersionRelease

release 成功调用时,必须 触发。

event VersionRelease(string packageName, string version, string manifestURI)

读取 API 规范

读取 API 由一组方法组成,这些方法允许工具从注册表中提取所有可使用的数据。

// 检索注册表中所有唯一包标识符列表的切片。
// `offset` 和 `limit` 启用分页响应 / 检索完整集合。 (见下面的注释)
function getAllPackageIds(uint offset, uint limit) public view
  returns (
    bytes32[] packageIds,
    uint pointer
  );

// 检索与包的 id 关联的唯一字符串 `name`。
function getPackageName(bytes32 packageId) public view returns (string packageName);

// 检索注册表中现有包版本的唯一标识符。
function getReleaseId(string packageName, string version) public view returns (bytes32 releaseId);

// 检索包的所有发布 id 列表的切片。
// `offset` 和 `limit` 启用分页响应 / 检索完整集合。 (见下面的注释)
function getAllReleaseIds(string packageName, uint offset, uint limit) public view
  returns (
    bytes32[] releaseIds,
    uint pointer
  );

// 检索发布 id 的包名称、发布版本和 URI 位置数据。
function getReleaseData(bytes32 releaseId) public view
  returns (
    string packageName,
    string version,
    string manifestURI
  );

// 检索注册表在执行发布时将为包名称和版本对生成的发布 id。
function generateReleaseId(string packageName, string version)
  public
  view
  returns (bytes32 releaseId);

// 返回注册表中唯一包的总数。
function numPackageIds() public view returns (uint totalCount);

// 返回注册表中给定 packageName 的唯一发布的总数。
function numReleaseIds(string packageName) public view returns (uint totalCount);

分页

getAllPackageIdsgetAllReleaseIds 支持分页请求,因为这些方法的返回值可能会变得非常大。这些方法应该返回一个 pointer,它指向所有项目列表中的下一个可用项目,以便调用者可以使用它从上一个请求中断的地方继续。 (有关各种分页策略的优缺点的讨论,请参见 此处。)limit 参数定义了注册表每个请求应返回的最大项目数。

理由

该提案希望实现以下目标:

  • 定义必要的最小输入集,以允许注册表将包名称映射到一组 发布版本,同时允许他们使用他们选择的任何版本控制方案。
  • 提供从注册表中检索包数据所需的最小 getter 方法集,以便注册表聚合器可以读取其所有数据。
  • 定义一个标准查询,该查询从包名称和版本对合成一个发布标识符,以便工具可以解析特定的包版本请求,而无需查询注册表中有关包的所有发布。

注册表可能会提供更复杂的 read API,以管理 semver 范围或 latest 等中的包请求。此 EIP 对工具或注册表如何实现这些是不可知的。它建议注册表实现 EIP-165 并利用资源来发布更复杂的接口,例如 EIP-926

向后兼容性

没有现有的包注册表标准。当前由 EthPM 部署的包注册表不符合该标准,因为它仅实现了规范中描述的一种方法签名。

实现

该提案的参考实现正在 GitHub 上的 EthPM 组织中积极开发 此处

版权

根据 CC0 放弃版权和相关权利。

Citation

Please cite this document as:

Piper Merriam <piper@ethereum.org>, Christopher Gewecke <christophergewecke@gmail.com>, g. nicholas d'andrea <nick.dandrea@consensys.net>, Nick Gheorghita (@njgheorghita), "ERC-1319: 智能合约包注册表接口 [DRAFT]," Ethereum Improvement Proposals, no. 1319, August 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1319.