From 14153c60790efa232a4dd0d21922192551be2d5a Mon Sep 17 00:00:00 2001 From: cgewecke Date: Mon, 30 Jul 2018 12:14:43 -0700 Subject: [PATCH 01/11] Initial draft of registry eip --- EIPS/eip-ethpm-registry.md | 124 +++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 EIPS/eip-ethpm-registry.md diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md new file mode 100644 index 00000000000000..06852888cb7c7c --- /dev/null +++ b/EIPS/eip-ethpm-registry.md @@ -0,0 +1,124 @@ +[ Needs table header ... ] + +## Abstract +This EIP specifies an interface for publishing to and retrieving assets from smart contract package registries. It is a companion EIP to [1123](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md) which defined a standard for smart contract package manifests. + +## Motivation +The goal is to establish a framework that allows smart contract publishers to design and deploy code registries of arbitrary complexity which expose standard endpoints to tooling that retrieves assets for contract package consumers. + +A clear standard would help the existing EthPM Package Registry evolve from a centralized, single-project community resource into a decentralized multi-registry system whose constituents are bound together by the proposed interface. In turn, these registries could be ENS name-spaced, enabling installation conventions familiar to users of `npm` and other package managers. + +**Examples** +```shell +$ ethpm install packages.zeppelin.eth/Ownership +``` + +```javascript +const SimpleToken = await web3.packaging + .registry('packages.ethpm.eth') + .getPackage('SimpleToken') + .getVersion('^1.1.5'); +``` + +## Specification +The specification describes a small read/write API whose components are mandatory. It encourages (without enforcing) the management of versioned releases using the conventions of [semver](https://semver.org/). It assumes registries will share the following structure and encoding conventions: + ++ a **registry** is a deployed contract which manages a collection of **packages**. ++ a **package** is a collection of **releases** ++ a **package** is identified by a unique string name within a given **registry** ++ a **release** is identified by a bytes32 **releaseHash** which is the keccak256 hash of the following: + + the keccak256 hash of a package's string name *WITH* + + the keccak256 hash of its semver components + + uint32 major + + uint32 minor + + uint32 patch + + string preRelease + + string build ++ a **releaseHash** maps to a set of data that includes a **manifestURI** string which describes the location of an [EIP 1123 package manifest](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md). This manifest contains data about the release including the location of its component code assets. ++ a **manifestURI** string contains a cryptographic hash which can be used to verify the integrity of the content found at the URI. The URI format is defined in [RFC3986](https://tools.ietf.org/html/rfc3986). + +The canonical way to generate a **releaseHash** is the using the following methods (in Solidity): +```solidity +// Hashes package name +function hashPackageName(string packageName) + public + pure + returns (bytes32) + { + return keccak256(abi.encodePacked(packageName)); + } + +// Hashes version components +function hashReleaseVersion( uint32 major, uint32 minor, uint32 patch, string preRelease, string build) + public + pure + returns (bytes32) + { + return keccak256(abi.encodePacked(major, minor, patch, preRelease, build)); + } + +// Hashes package name hash and version components hash together +function hashRelease(bytes32 packageNameHash, bytes32 releaseVersionHash) + public + pure + returns (bytes32) + { + return keccak256(abi.encodePacked(packageNameHash, releaseVersionHash)); + } +``` +(See *Rationale* below for more information about the purpose of this hashing strategy.) + +**Write API** +The write API consists of a single method, `release` which passes the registry the release information described above and allows it to create a unique, retrievable, semver compliant record of a versioned code package. +```solidity +function release( + string name, + uint32 major, + uint32 minor, + uint32 patch, + string preRelease, + string build, + string manifestURI + ) + public + returns (bool); +``` +**Read API Specification** + +The read API consists of a minimal set of methods that allows tooling to extract all consumable data from a registry. + +```solidity +// Retrieves all packages published to a registry +function getAllPackageNames() public view returns (string[]); + +// Retrieves all releases for a given package +function getAllPackageReleaseHashes(string name) public view returns (bytes32[]); + +// Retrieves version and manifestURI data for a given release hash +function getReleaseData(bytes32 releaseHash) public view + returns ( + uint32 major, + uint32 minor, + uint32 patch, + string preRelease, + string build, + string manifestURI + ); +``` + +## Rationale +The proposal is meant to accomplish the following: ++ Establish a publication norm that helps registries implement semver and store package data in mappings that reflect a two-tiered hierarchy of packages that are collections of releases. This is the rationale behind the two-phased hashing of package and version components together into a single release hash identifier. ++ Provide the minimum set of getter methods needed to retrieve all package data from a registry so that registry aggregators can read all of their data. ++ Define a standard way of generating a release hash so that tooling can resolve specific package version requests *without* needing to query a registry about its entire contents. + +In practice registries may offer more complex `read` APIs that manage consumers requests for packages within a semver range or at `latest` etc. This EIP is agnostic about how tooling or registry contracts implement these. It recommends that registries implement [EIP 165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) and avail themselves of resources to publish more complex interfaces such as [EIP 926](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-926.md). + +## Backwards Compatibility +The standard simplifies the interface of the existing EthPM package registry in such a way that the currently deployed version would not comply with proposed standard. Specifically, the deployed version lacks the `getAllPackageNames` method. + +## Implementation +A reference implementation of the proposed standard can be found at the EthPM organization on Github [here](https://github.com/ethpm/escape-truffle). + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file From 801f54736f231f3bae2829fbeb6cef0b16fd8971 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Mon, 30 Jul 2018 18:00:46 -0700 Subject: [PATCH 02/11] Revisions towards pipers initial review --- EIPS/eip-ethpm-registry.md | 120 ++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 67 deletions(-) diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md index 06852888cb7c7c..991aff55f6c5d1 100644 --- a/EIPS/eip-ethpm-registry.md +++ b/EIPS/eip-ethpm-registry.md @@ -1,10 +1,10 @@ [ Needs table header ... ] ## Abstract -This EIP specifies an interface for publishing to and retrieving assets from smart contract package registries. It is a companion EIP to [1123](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md) which defined a standard for smart contract package manifests. +This EIP specifies an interface for publishing to and retrieving assets from smart contract package registries. It is a companion EIP to [1123](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md) which defines a standard for smart contract package manifests. ## Motivation -The goal is to establish a framework that allows smart contract publishers to design and deploy code registries of arbitrary complexity which expose standard endpoints to tooling that retrieves assets for contract package consumers. +The goal is to establish a framework that allows smart contract publishers to design and deploy code registries with arbitrary business logic while exposing a set of common endpoints that tooling can use to retrieve assets for contract package consumers. A clear standard would help the existing EthPM Package Registry evolve from a centralized, single-project community resource into a decentralized multi-registry system whose constituents are bound together by the proposed interface. In turn, these registries could be ENS name-spaced, enabling installation conventions familiar to users of `npm` and other package managers. @@ -21,104 +21,90 @@ const SimpleToken = await web3.packaging ``` ## Specification -The specification describes a small read/write API whose components are mandatory. It encourages (without enforcing) the management of versioned releases using the conventions of [semver](https://semver.org/). It assumes registries will share the following structure and encoding conventions: +The specification describes a small read/write API whose components are mandatory. It allows registries to manage versioned releases using the conventions of [semver](https://semver.org/) without imposing this as a requirement. It assumes registries will share the following structure and conventions: + a **registry** is a deployed contract which manages a collection of **packages**. + a **package** is a collection of **releases** + a **package** is identified by a unique string name within a given **registry** -+ a **release** is identified by a bytes32 **releaseHash** which is the keccak256 hash of the following: - + the keccak256 hash of a package's string name *WITH* - + the keccak256 hash of its semver components - + uint32 major - + uint32 minor - + uint32 patch - + string preRelease - + string build -+ a **releaseHash** maps to a set of data that includes a **manifestURI** string which describes the location of an [EIP 1123 package manifest](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md). This manifest contains data about the release including the location of its component code assets. ++ a **release** is identified by a `bytes32` **releaseId** which must be unique for a given package name and release version string pair. ++ a **releaseId** maps to a set of data that includes a **manifestURI** string which describes the location of an [EIP 1123 package manifest](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md). This manifest contains data about the release including the location of its component code assets. + a **manifestURI** string contains a cryptographic hash which can be used to verify the integrity of the content found at the URI. The URI format is defined in [RFC3986](https://tools.ietf.org/html/rfc3986). -The canonical way to generate a **releaseHash** is the using the following methods (in Solidity): -```solidity -// Hashes package name -function hashPackageName(string packageName) - public - pure - returns (bytes32) - { - return keccak256(abi.encodePacked(packageName)); - } +An example of a package name and release version string pair is: +```shell +"SimpleToken" # package name +"1.0.1" # version string +``` -// Hashes version components -function hashReleaseVersion( uint32 major, uint32 minor, uint32 patch, string preRelease, string build) - public - pure - returns (bytes32) - { - return keccak256(abi.encodePacked(major, minor, patch, preRelease, build)); - } +Implementations are free to choose any scheme for generating a **releaseId**. A common approach would be to hash the strings together as below. -// Hashes package name hash and version components hash together -function hashRelease(bytes32 packageNameHash, bytes32 releaseVersionHash) +```solidity +// Hashes package name and a release version string +function generateReleaseId(string packageName, string version) public pure returns (bytes32) { - return keccak256(abi.encodePacked(packageNameHash, releaseVersionHash)); + return keccak256(abi.encodePacked(packageName, version)); } ``` -(See *Rationale* below for more information about the purpose of this hashing strategy.) -**Write API** -The write API consists of a single method, `release` which passes the registry the release information described above and allows it to create a unique, retrievable, semver compliant record of a versioned code package. +Implementations **must** expose this id generation logic as part of their public `read` API so +tooling can easily map a string based release query to the registry's unique identifier for that release. + +**Write API Specification** +The write API consists of a single method, `release`. It passes the registry the package name, a +version identifier for the release, and a URI specifying the location of a manifest which +details the contents of the release. ```solidity -function release( - string name, - uint32 major, - uint32 minor, - uint32 patch, - string preRelease, - string build, - string manifestURI - ) - public - returns (bool); +function release(string packageName, string version, string manifestURI) public; ``` **Read API Specification** -The read API consists of a minimal set of methods that allows tooling to extract all consumable data from a registry. +The read API consists of a set of methods that allows tooling to extract all consumable data from a registry. ```solidity -// Retrieves all packages published to a registry +// Retrieves all the packages published to a registry. function getAllPackageNames() public view returns (string[]); -// Retrieves all releases for a given package -function getAllPackageReleaseHashes(string name) public view returns (bytes32[]); +// Retrieves the registry's unique identifier for an existing release of a package. +function getReleaseId(string packageName, string version) public view returns (bytes32); + +// Retrieves all release ids for a package +function getAllReleaseIds(string packageName) public view returns (bytes32[]); -// Retrieves version and manifestURI data for a given release hash -function getReleaseData(bytes32 releaseHash) public view +// Retrieves package name, release version and URI location data for a release id. +function getReleaseData(bytes32 releaseId) public view returns ( - uint32 major, - uint32 minor, - uint32 patch, - string preRelease, - string build, + string packageName, + string version, string manifestURI - ); + ); + +// Retrieves the release id a registry *would* generate for a package name and version pair +// when executing a release. +function generateReleaseId(string packageName, string version) pure returns (bytes32); + +// Declares whether a registry maintains its releases in semver compliant order. +function usesSemver() public pure returns (bool); ``` ## Rationale -The proposal is meant to accomplish the following: -+ Establish a publication norm that helps registries implement semver and store package data in mappings that reflect a two-tiered hierarchy of packages that are collections of releases. This is the rationale behind the two-phased hashing of package and version components together into a single release hash identifier. -+ Provide the minimum set of getter methods needed to retrieve all package data from a registry so that registry aggregators can read all of their data. -+ Define a standard way of generating a release hash so that tooling can resolve specific package version requests *without* needing to query a registry about its entire contents. +The proposal hopes to accomplish the following: + ++ Define the smallest set of inputs necessary to allow registries to map package names to a set of +release versions while allowing them to use any versioning schema they choose. ++ Provide the minimum set of getter methods needed to retrieve package data from a registry so that registry aggregators can read all of their data. ++ Define a standard query that synthesizes a release identifier from a package name and version pair so that tooling can resolve specific package version requests without needing to query a registry about all of a package's releases. ++ Mandate that registries indicate whether or not they enforce semver so that tooling can determine whether consumer requests for packages at a semver range are possible. -In practice registries may offer more complex `read` APIs that manage consumers requests for packages within a semver range or at `latest` etc. This EIP is agnostic about how tooling or registry contracts implement these. It recommends that registries implement [EIP 165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) and avail themselves of resources to publish more complex interfaces such as [EIP 926](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-926.md). +Registries may offer more complex `read` APIs that manage requests for packages within a semver range or at `latest` etc. This EIP is agnostic about how tooling or registries might implement these. It recommends that registries implement [EIP 165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) and avail themselves of resources to publish more complex interfaces such as [EIP 926](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-926.md). ## Backwards Compatibility -The standard simplifies the interface of the existing EthPM package registry in such a way that the currently deployed version would not comply with proposed standard. Specifically, the deployed version lacks the `getAllPackageNames` method. +The standard modifies the interface of the existing EthPM package registry in such a way that the currently deployed version would not comply with standard since it implements only one of the method signatures described in the specification. ## Implementation -A reference implementation of the proposed standard can be found at the EthPM organization on Github [here](https://github.com/ethpm/escape-truffle). +A reference implementation of this proposal can be found at the EthPM organization on Github [here](https://github.com/ethpm/escape-truffle). ## Copyright -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 3350338ffbb9ccd4891223f470b2ef668ed311a0 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 3 Aug 2018 00:03:36 -0700 Subject: [PATCH 03/11] Remove usesSemver, paginate large requests, clarify manifestURI --- EIPS/eip-ethpm-registry.md | 52 ++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md index 991aff55f6c5d1..cfe233c123818b 100644 --- a/EIPS/eip-ethpm-registry.md +++ b/EIPS/eip-ethpm-registry.md @@ -30,13 +30,18 @@ The specification describes a small read/write API whose components are mandator + a **releaseId** maps to a set of data that includes a **manifestURI** string which describes the location of an [EIP 1123 package manifest](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md). This manifest contains data about the release including the location of its component code assets. + a **manifestURI** string contains a cryptographic hash which can be used to verify the integrity of the content found at the URI. The URI format is defined in [RFC3986](https://tools.ietf.org/html/rfc3986). -An example of a package name and release version string pair is: +### Examples + +**Package Names / Release Versions** + ```shell "SimpleToken" # package name "1.0.1" # version string ``` -Implementations are free to choose any scheme for generating a **releaseId**. A common approach would be to hash the strings together as below. +**Release IDs** + +Implementations are free to choose any scheme for generating a **releaseId**. A common approach would be to hash the strings together as below: ```solidity // Hashes package name and a release version string @@ -48,30 +53,52 @@ function generateReleaseId(string packageName, string version) return keccak256(abi.encodePacked(packageName, version)); } ``` - Implementations **must** expose this id generation logic as part of their public `read` API so tooling can easily map a string based release query to the registry's unique identifier for that release. -**Write API Specification** +**Manifest URIs** + +Any IPFS or Swarm URI meets the definition of **manifestURI**. + +Another example is content on GitHub addressed by its SHA-1 hash. This hash can be obtained by running: +```shell +$ curl https://api.github.com/repos///contents/ +``` +A file containing the word "hello" could have its GitHub SHA-1 hash independently verified by comparing it to the output of: +```shell +$ printf "blob 6\000hello\n" | sha1sum +``` + +### Write API Specification The write API consists of a single method, `release`. It passes the registry the package name, a version identifier for the release, and a URI specifying the location of a manifest which details the contents of the release. ```solidity function release(string packageName, string version, string manifestURI) public; ``` -**Read API Specification** +### Read API Specification The read API consists of a set of methods that allows tooling to extract all consumable data from a registry. ```solidity -// Retrieves all the packages published to a registry. -function getAllPackageNames() public view returns (string[]); +// Retrieves all packages published to a registry. `offset` and `limit` enable +// paginated responses. (See note below) +function getAllPackageNames(uint offset, uint limit) public view + returns ( + string[] names, + uint offset + ); // Retrieves the registry's unique identifier for an existing release of a package. function getReleaseId(string packageName, string version) public view returns (bytes32); -// Retrieves all release ids for a package -function getAllReleaseIds(string packageName) public view returns (bytes32[]); +// Retrieves all release ids for a package. `offset` and `limit` enable paginated responses. +// (See note below) +function getAllReleaseIds(string packageName, uint offset, uint limit) public view + returns ( + bytes32[] ids, + uint offset + ); // Retrieves package name, release version and URI location data for a release id. function getReleaseData(bytes32 releaseId) public view @@ -84,10 +111,10 @@ function getReleaseData(bytes32 releaseId) public view // Retrieves the release id a registry *would* generate for a package name and version pair // when executing a release. function generateReleaseId(string packageName, string version) pure returns (bytes32); - -// Declares whether a registry maintains its releases in semver compliant order. -function usesSemver() public pure returns (bool); ``` +**Pagination** + +`getAllPackages` and `getAllReleaseIds` support paginated requests because it's possible that the return values for these methods could become quite large. The methods should return an `offset` that is a pointer to the next available item in a list of all items such that a caller can use it to pick up from where the previous request left off. (See [here](https://mixmax.com/blog/api-paging-built-the-right-way) for a discussion of the merits and demerits of various pagination strategies.) The `limit` parameter defines the maximum number of items a registry should return per request. ## Rationale The proposal hopes to accomplish the following: @@ -96,7 +123,6 @@ The proposal hopes to accomplish the following: release versions while allowing them to use any versioning schema they choose. + Provide the minimum set of getter methods needed to retrieve package data from a registry so that registry aggregators can read all of their data. + Define a standard query that synthesizes a release identifier from a package name and version pair so that tooling can resolve specific package version requests without needing to query a registry about all of a package's releases. -+ Mandate that registries indicate whether or not they enforce semver so that tooling can determine whether consumer requests for packages at a semver range are possible. Registries may offer more complex `read` APIs that manage requests for packages within a semver range or at `latest` etc. This EIP is agnostic about how tooling or registries might implement these. It recommends that registries implement [EIP 165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) and avail themselves of resources to publish more complex interfaces such as [EIP 926](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-926.md). From 88e6b819c929666c87ad36c90ea4d2496ad0704d Mon Sep 17 00:00:00 2001 From: c-g-e-w-e-k-e- Date: Sun, 5 Aug 2018 12:57:18 -0700 Subject: [PATCH 04/11] Correct and clarify GitHub manifestURI example --- EIPS/eip-ethpm-registry.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md index cfe233c123818b..1a5cc5534f82b6 100644 --- a/EIPS/eip-ethpm-registry.md +++ b/EIPS/eip-ethpm-registry.md @@ -60,13 +60,18 @@ tooling can easily map a string based release query to the registry's unique ide Any IPFS or Swarm URI meets the definition of **manifestURI**. -Another example is content on GitHub addressed by its SHA-1 hash. This hash can be obtained by running: +Another example is content on GitHub addressed by its SHA-1 hash. The Base64 encoded content at this hash can be obtained by running: ```shell -$ curl https://api.github.com/repos///contents/ +$ curl https://api.github.com/repos/:owner/:repo/git/blobs/:file_sha + +# Example +$ curl https://api.github.com/repos/rstallman/hello/git/blobs/ce013625030ba8dba906f756967f9e9ca394464a ``` -A file containing the word "hello" could have its GitHub SHA-1 hash independently verified by comparing it to the output of: + +The string "hello" can have its GitHub SHA-1 hash independently verified by comparing it to the output of: ```shell $ printf "blob 6\000hello\n" | sha1sum +> ce013625030ba8dba906f756967f9e9ca394464a ``` ### Write API Specification From 7d96e105d79105dcaa940f6ee8b8f6e783d8bf20 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Tue, 7 Aug 2018 14:39:02 -0700 Subject: [PATCH 05/11] Use packageIds instead of packageNames & misc rewording --- EIPS/eip-ethpm-registry.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md index 1a5cc5534f82b6..56d18f91d8f8c1 100644 --- a/EIPS/eip-ethpm-registry.md +++ b/EIPS/eip-ethpm-registry.md @@ -4,7 +4,7 @@ This EIP specifies an interface for publishing to and retrieving assets from smart contract package registries. It is a companion EIP to [1123](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md) which defines a standard for smart contract package manifests. ## Motivation -The goal is to establish a framework that allows smart contract publishers to design and deploy code registries with arbitrary business logic while exposing a set of common endpoints that tooling can use to retrieve assets for contract package consumers. +The goal is to establish a framework that allows smart contract publishers to design and deploy code registries with arbitrary business logic while exposing a set of common endpoints that tooling can use to retrieve assets for contract consumers. A clear standard would help the existing EthPM Package Registry evolve from a centralized, single-project community resource into a decentralized multi-registry system whose constituents are bound together by the proposed interface. In turn, these registries could be ENS name-spaced, enabling installation conventions familiar to users of `npm` and other package managers. @@ -25,7 +25,7 @@ The specification describes a small read/write API whose components are mandator + a **registry** is a deployed contract which manages a collection of **packages**. + a **package** is a collection of **releases** -+ a **package** is identified by a unique string name within a given **registry** ++ a **package** is identified by a unique string name and unique bytes32 **packageId** within a given **registry** + a **release** is identified by a `bytes32` **releaseId** which must be unique for a given package name and release version string pair. + a **releaseId** maps to a set of data that includes a **manifestURI** string which describes the location of an [EIP 1123 package manifest](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md). This manifest contains data about the release including the location of its component code assets. + a **manifestURI** string contains a cryptographic hash which can be used to verify the integrity of the content found at the URI. The URI format is defined in [RFC3986](https://tools.ietf.org/html/rfc3986). @@ -86,19 +86,22 @@ function release(string packageName, string version, string manifestURI) public; The read API consists of a set of methods that allows tooling to extract all consumable data from a registry. ```solidity -// Retrieves all packages published to a registry. `offset` and `limit` enable -// paginated responses. (See note below) -function getAllPackageNames(uint offset, uint limit) public view +// Retrieves a slice of the list of all unique package identifiers in a registry. +// `offset` and `limit` enable paginated responses / retrieval of the complete set. (See note below) +function getAllPackageIds(uint offset, uint limit) public view returns ( - string[] names, + bytes32 packageIds, uint offset ); +// Retrieves the unique string `name` associated with a package's id. +function getPackageName(bytes32 packageId) public view returns (string name); + // Retrieves the registry's unique identifier for an existing release of a package. function getReleaseId(string packageName, string version) public view returns (bytes32); -// Retrieves all release ids for a package. `offset` and `limit` enable paginated responses. -// (See note below) +// Retrieves a slice of the list of all release ids for a package. +// `offset` and `limit` enable paginated responses / retrieval of the complete set. (See note below) function getAllReleaseIds(string packageName, uint offset, uint limit) public view returns ( bytes32[] ids, @@ -119,7 +122,7 @@ function generateReleaseId(string packageName, string version) pure returns (byt ``` **Pagination** -`getAllPackages` and `getAllReleaseIds` support paginated requests because it's possible that the return values for these methods could become quite large. The methods should return an `offset` that is a pointer to the next available item in a list of all items such that a caller can use it to pick up from where the previous request left off. (See [here](https://mixmax.com/blog/api-paging-built-the-right-way) for a discussion of the merits and demerits of various pagination strategies.) The `limit` parameter defines the maximum number of items a registry should return per request. +`getAllPackageIds` and `getAllReleaseIds` support paginated requests because it's possible that the return values for these methods could become quite large. The methods should return an `offset` that is a pointer to the next available item in a list of all items such that a caller can use it to pick up from where the previous request left off. (See [here](https://mixmax.com/blog/api-paging-built-the-right-way) for a discussion of the merits and demerits of various pagination strategies.) The `limit` parameter defines the maximum number of items a registry should return per request. ## Rationale The proposal hopes to accomplish the following: @@ -132,7 +135,7 @@ release versions while allowing them to use any versioning schema they choose. Registries may offer more complex `read` APIs that manage requests for packages within a semver range or at `latest` etc. This EIP is agnostic about how tooling or registries might implement these. It recommends that registries implement [EIP 165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) and avail themselves of resources to publish more complex interfaces such as [EIP 926](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-926.md). ## Backwards Compatibility -The standard modifies the interface of the existing EthPM package registry in such a way that the currently deployed version would not comply with standard since it implements only one of the method signatures described in the specification. +No existing standard exists for package registries. The package registry currently deployed by EthPM would not comply with the standard since it implements only one of the method signatures described in the specification. ## Implementation A reference implementation of this proposal can be found at the EthPM organization on Github [here](https://github.com/ethpm/escape-truffle). From 06c4bc062cd7a3fc7d6ce32e299532e122379fb7 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Tue, 7 Aug 2018 14:59:35 -0700 Subject: [PATCH 06/11] Add temporary table header --- EIPS/eip-ethpm-registry.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md index 56d18f91d8f8c1..0fe388d122fe14 100644 --- a/EIPS/eip-ethpm-registry.md +++ b/EIPS/eip-ethpm-registry.md @@ -1,4 +1,13 @@ -[ Needs table header ... ] +--- +eip: unknown +title: Contract Package Registry Interface +author: Piper Merriam , Christopher Gewecke +type: Standards Track +category: ERC +status: Draft +created: 2018-08-07 +discussions-to: +--- ## Abstract This EIP specifies an interface for publishing to and retrieving assets from smart contract package registries. It is a companion EIP to [1123](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md) which defines a standard for smart contract package manifests. From aa7935379454bc2165dbabf4523050a5139167a0 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Wed, 8 Aug 2018 18:15:33 -0700 Subject: [PATCH 07/11] Use simple-token --- EIPS/eip-ethpm-registry.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md index 0fe388d122fe14..c3b312f033e056 100644 --- a/EIPS/eip-ethpm-registry.md +++ b/EIPS/eip-ethpm-registry.md @@ -25,7 +25,7 @@ $ ethpm install packages.zeppelin.eth/Ownership ```javascript const SimpleToken = await web3.packaging .registry('packages.ethpm.eth') - .getPackage('SimpleToken') + .getPackage('simple-token') .getVersion('^1.1.5'); ``` @@ -44,8 +44,8 @@ The specification describes a small read/write API whose components are mandator **Package Names / Release Versions** ```shell -"SimpleToken" # package name -"1.0.1" # version string +"simple-token" # package name +"1.0.1" # version string ``` **Release IDs** From fa805d215338d8a8e44c260806a7cbbca6d2a3e0 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Wed, 8 Aug 2018 18:19:19 -0700 Subject: [PATCH 08/11] Clarify manifestURI definition --- EIPS/eip-ethpm-registry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md index c3b312f033e056..e54a25f46230eb 100644 --- a/EIPS/eip-ethpm-registry.md +++ b/EIPS/eip-ethpm-registry.md @@ -37,7 +37,7 @@ The specification describes a small read/write API whose components are mandator + a **package** is identified by a unique string name and unique bytes32 **packageId** within a given **registry** + a **release** is identified by a `bytes32` **releaseId** which must be unique for a given package name and release version string pair. + a **releaseId** maps to a set of data that includes a **manifestURI** string which describes the location of an [EIP 1123 package manifest](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md). This manifest contains data about the release including the location of its component code assets. -+ a **manifestURI** string contains a cryptographic hash which can be used to verify the integrity of the content found at the URI. The URI format is defined in [RFC3986](https://tools.ietf.org/html/rfc3986). ++ a **manifestURI** is a URI as defined by [RFC3986](https://tools.ietf.org/html/rfc3986) which can be used to retrieve the contents of the package manifest. In addition to validation against RFC3986, each **manifestURI** must also contain a hash of the content as specified in the [EIP 1123](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md). ### Examples From 1c9a6e32756dbc8452e7699ff7328247da762f9a Mon Sep 17 00:00:00 2001 From: cgewecke Date: Wed, 8 Aug 2018 18:22:53 -0700 Subject: [PATCH 09/11] Let `release` return a releaseID --- EIPS/eip-ethpm-registry.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md index e54a25f46230eb..b10172b2dd711b 100644 --- a/EIPS/eip-ethpm-registry.md +++ b/EIPS/eip-ethpm-registry.md @@ -88,7 +88,8 @@ The write API consists of a single method, `release`. It passes the registry the version identifier for the release, and a URI specifying the location of a manifest which details the contents of the release. ```solidity -function release(string packageName, string version, string manifestURI) public; +function release(string packageName, string version, string manifestURI) public + returns (bytes32 releaseId); ``` ### Read API Specification From 59dc574d848cb48a2658020ac6cdb36db3fd3b32 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Mon, 13 Aug 2018 10:25:11 -0700 Subject: [PATCH 10/11] Update header info, add simple summary, qualify implementation as ongoing --- EIPS/eip-ethpm-registry.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md index b10172b2dd711b..6849b710c2e720 100644 --- a/EIPS/eip-ethpm-registry.md +++ b/EIPS/eip-ethpm-registry.md @@ -1,14 +1,17 @@ --- -eip: unknown -title: Contract Package Registry Interface -author: Piper Merriam , Christopher Gewecke +eip: +title: Smart Contract Package Registry Interface +author: Piper Merriam , Christopher Gewecke , g. nicholas d'andrea type: Standards Track category: ERC status: Draft -created: 2018-08-07 +created: 2018-08-13 discussions-to: --- +## Simple Summary +A standard interface for smart contract package registries. + ## Abstract This EIP specifies an interface for publishing to and retrieving assets from smart contract package registries. It is a companion EIP to [1123](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md) which defines a standard for smart contract package manifests. @@ -148,7 +151,7 @@ Registries may offer more complex `read` APIs that manage requests for packages No existing standard exists for package registries. The package registry currently deployed by EthPM would not comply with the standard since it implements only one of the method signatures described in the specification. ## Implementation -A reference implementation of this proposal can be found at the EthPM organization on Github [here](https://github.com/ethpm/escape-truffle). +A reference implementation of this proposal is in active development at the EthPM organization on Github [here](https://github.com/ethpm/escape-truffle). ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 26cf02516a2775af7f53780e20f6fe9c86ed0387 Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Mon, 13 Aug 2018 13:40:50 -0400 Subject: [PATCH 11/11] Change gnidan's email --- EIPS/eip-ethpm-registry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-ethpm-registry.md b/EIPS/eip-ethpm-registry.md index 6849b710c2e720..4585f46f5c1888 100644 --- a/EIPS/eip-ethpm-registry.md +++ b/EIPS/eip-ethpm-registry.md @@ -1,7 +1,7 @@ --- eip: title: Smart Contract Package Registry Interface -author: Piper Merriam , Christopher Gewecke , g. nicholas d'andrea +author: Piper Merriam , Christopher Gewecke , g. nicholas d'andrea type: Standards Track category: ERC status: Draft