forked from DecentralizedClimateFoundation/DCIPs
1043 lines
34 KiB
Markdown
1043 lines
34 KiB
Markdown
|
---
|
|||
|
eip: 2678
|
|||
|
title: Revised Ethereum Smart Contract Packaging Standard (EthPM v3)
|
|||
|
author: g. nicholas d’andrea (@gnidan), Piper Merriam (@pipermerriam), Nick Gheorghita (@njgheorghita), Christian Reitwiessner (@chriseth), Ben Hauser (@iamdefinitelyahuman), Bryant Eisenbach (@fubuloubu)
|
|||
|
discussions-to: https://ethereum-magicians.org/t/ethpm-v3-specification-working-group/4086
|
|||
|
status: Final
|
|||
|
type: Standards Track
|
|||
|
category: ERC
|
|||
|
created: 2020-05-26
|
|||
|
---
|
|||
|
|
|||
|
|
|||
|
## Simple Summary
|
|||
|
|
|||
|
A data format describing a smart contract software package.
|
|||
|
|
|||
|
|
|||
|
## Abstract
|
|||
|
|
|||
|
This EIP defines a data format for *package manifest* documents,
|
|||
|
representing a package of one or more smart contracts, optionally
|
|||
|
including source code and any/all deployed instances across multiple
|
|||
|
networks. Package manifests are minified JSON objects, to be distributed
|
|||
|
via content addressable storage networks, such as IPFS. Packages
|
|||
|
are then published to on-chain EthPM registries, defined in
|
|||
|
[EIP-1319](./eip-1319.md), from where they can be freely accessed.
|
|||
|
|
|||
|
This document presents a natural language description of a formal
|
|||
|
specification for version **3** of this format.
|
|||
|
|
|||
|
|
|||
|
## Motivation
|
|||
|
|
|||
|
This standard aims to encourage the Ethereum development ecosystem
|
|||
|
towards software best practices around code reuse. By defining an open,
|
|||
|
community-driven package data format standard, this effort seeks to
|
|||
|
provide support for package management tools development by offering a
|
|||
|
general-purpose solution that has been designed with observed common
|
|||
|
practices in mind.
|
|||
|
|
|||
|
- Updates the schema for a *package manifest* to be compatible with
|
|||
|
the [metadata](https://solidity.readthedocs.io/en/latest/metadata.html) output for compilers.
|
|||
|
- Updates the `"sources"` object definition to support a wider range of source file types and serve as [JSON input](https://solidity.readthedocs.io/en/latest/using-the-compiler.html#compiler-input-and-output-json-description) for a compiler.
|
|||
|
- Moves compiler definitions to a top-level `"compilers"` array in order to:
|
|||
|
- Simplify the links between a compiler version, sources, and the
|
|||
|
compiled assets.
|
|||
|
- Simplify packages that use multiple compiler versions.
|
|||
|
- Updates key formatting from `snake_case` to `camelCase` to be
|
|||
|
more consistent with [JSON convention](https://google.github.io/styleguide/jsoncstyleguide.xml?showone=Property_Name_Format#Property_Name_Format).
|
|||
|
|
|||
|
### Guiding Principles
|
|||
|
|
|||
|
This specification makes the following assumptions about the document
|
|||
|
lifecycle.
|
|||
|
|
|||
|
1. Package manifests are intended to be generated programmatically by
|
|||
|
package management software as part of the release process.
|
|||
|
|
|||
|
2. Package manifests will be consumed by package managers during tasks
|
|||
|
like installing package dependencies or building and deploying new
|
|||
|
releases.
|
|||
|
|
|||
|
3. Package manifests will typically **not** be stored alongside the
|
|||
|
source, but rather by package registries *or* referenced by package
|
|||
|
registries and stored in something akin to IPFS.
|
|||
|
|
|||
|
4. Package manifests can be used to verify public deployments of source
|
|||
|
contracts.
|
|||
|
|
|||
|
### Use Cases
|
|||
|
|
|||
|
The following use cases were considered during the creation of this
|
|||
|
specification.
|
|||
|
|
|||
|
* **owned**: A package which contains contracts which are not meant to be used by themselves but rather as base contracts to provide functionality to other contracts through inheritance.
|
|||
|
* **transferable**: A package which has a single dependency.
|
|||
|
* **standard-token**: A package which contains a reusable contract.
|
|||
|
* **safe-math-lib**: A package which contains deployed instance of one of the package contracts.
|
|||
|
* **piper-coin**: A package which contains a deployed instance of a reusable contract from a dependency.
|
|||
|
* **escrow**: A package which contains a deployed instance of a local contract which is linked against a deployed instance of a local library.
|
|||
|
* **wallet**: A package with a deployed instance of a local contract which is linked against a deployed instance of a library from a dependency.
|
|||
|
* **wallet-with-send**: A package with a deployed instance which links against a deep dependency.
|
|||
|
* **simple-auction**: Compiler `"metadata"` field output.
|
|||
|
|
|||
|
## Package Specification
|
|||
|
|
|||
|
### Conventions
|
|||
|
|
|||
|
#### RFC2119
|
|||
|
|
|||
|
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
|
|||
|
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this
|
|||
|
document are to be interpreted as described in RFC 2119.
|
|||
|
|
|||
|
- <https://www.ietf.org/rfc/rfc2119.txt>
|
|||
|
|
|||
|
|
|||
|
#### Prefixed vs Unprefixed
|
|||
|
|
|||
|
A [prefixed](#prefixed) hexadecimal value begins with `0x`.
|
|||
|
[Unprefixed](#unprefixed) values have no prefix. Unless otherwise
|
|||
|
specified, all hexadecimal values **should** be represented with the
|
|||
|
`0x` prefix.
|
|||
|
|
|||
|
* **Prefixed**: `0xdeadbeef`
|
|||
|
* **Unprefixed**: `deadbeef`
|
|||
|
|
|||
|
### Document Format
|
|||
|
|
|||
|
The canonical format is a single JSON object. Packages **must** conform
|
|||
|
to the following serialization rules.
|
|||
|
|
|||
|
- The document **must** be tightly packed, meaning no linebreaks or
|
|||
|
extra whitespace.
|
|||
|
|
|||
|
- The keys in all objects **must** be sorted alphabetically.
|
|||
|
|
|||
|
- Duplicate keys in the same object are invalid.
|
|||
|
|
|||
|
- The document **must** use
|
|||
|
[UTF-8](https://en.wikipedia.org/wiki/UTF-8)
|
|||
|
encoding.
|
|||
|
|
|||
|
- The document **must** not have a trailing newline.
|
|||
|
|
|||
|
- To ensure backwards compatibility, `manifest_version` is a forbidden
|
|||
|
top-level key.
|
|||
|
|
|||
|
|
|||
|
### Document Specification
|
|||
|
|
|||
|
The following fields are defined for the package. Custom fields **may**
|
|||
|
be included. Custom fields **should** be prefixed with `x-` to prevent
|
|||
|
name collisions with future versions of the specification.
|
|||
|
|
|||
|
* **See Also**: Formalized ([JSON-Schema](https://json-schema.org)) version of this specification: [package.spec.json](../assets/eip-2678/package.spec.json)
|
|||
|
* **Jump To**: [Definitions](#object-definitions)
|
|||
|
|
|||
|
### EthPM Manifest Version
|
|||
|
|
|||
|
The `manifest` field defines the specification version that this
|
|||
|
document conforms to.
|
|||
|
|
|||
|
- Packages **must** include this field.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Key**: `manifest`
|
|||
|
* **Type**: String
|
|||
|
* **Allowed Values**: `ethpm/3`
|
|||
|
|
|||
|
### Package Name
|
|||
|
|
|||
|
The `name` field defines a human readable name for this package.
|
|||
|
|
|||
|
- Packages **should** include this field to be released on an EthPM
|
|||
|
registry.
|
|||
|
|
|||
|
- Package names **must** begin with a lowercase letter and be
|
|||
|
comprised of only the lowercase letters `a-z`, numeric characters `0-9`, and the
|
|||
|
dash character `-`.
|
|||
|
|
|||
|
- Package names **must** not exceed 255 characters in length.
|
|||
|
|
|||
|
* **Required**: If `version` is included.
|
|||
|
* **Key**: `name`
|
|||
|
* **Type**: String
|
|||
|
* **Format**: **must** match the regular expression `^[a-z][-a-z0-9]{0,255}$`
|
|||
|
|
|||
|
### Package Version
|
|||
|
|
|||
|
The `version` field declares the version number of this release.
|
|||
|
|
|||
|
- Packages **should** include this field to be released on an EthPM
|
|||
|
registry.
|
|||
|
|
|||
|
- This value **should** conform to the
|
|||
|
[semver](http://semver.org/) version numbering
|
|||
|
specification.
|
|||
|
|
|||
|
* **Required**: If `name` is included.
|
|||
|
* **Key**: `version`
|
|||
|
* **Type**: String
|
|||
|
|
|||
|
### Package Metadata
|
|||
|
|
|||
|
The `meta` field defines a location for metadata about the package which
|
|||
|
is not integral in nature for package installation, but may be important
|
|||
|
or convenient to have on-hand for other reasons.
|
|||
|
|
|||
|
- This field **should** be included in all Packages.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `meta`
|
|||
|
* **Type**: [Package Meta Object](#the-package-meta-object)
|
|||
|
|
|||
|
### Sources
|
|||
|
|
|||
|
The `sources` field defines a source tree that **should** comprise the
|
|||
|
full source tree necessary to recompile the contracts contained in this
|
|||
|
release.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `sources`
|
|||
|
* **Type**: Object (String: [Sources Object](#the-source-object))
|
|||
|
|
|||
|
### Contract Types
|
|||
|
|
|||
|
The `contractTypes` field hosts the [Contract
|
|||
|
Types](#contract-type) which have been included in this release.
|
|||
|
|
|||
|
- Packages **should** only include contract types that can be found in
|
|||
|
the source files for this package.
|
|||
|
|
|||
|
- Packages **should not** include contract types from dependencies.
|
|||
|
|
|||
|
- Packages **should not** include abstract contracts in the contract
|
|||
|
types section of a release.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `contractTypes`
|
|||
|
* **Type**: Object (String: [Contract Type Object](#the-contract-type-object))
|
|||
|
* **Format**: Keys **must** be valid [Contract Aliases](#contract-alias). <br> Values **must** conform to the [Contract Type Object](#the-contract-type-object) definition.
|
|||
|
|
|||
|
### Compilers
|
|||
|
|
|||
|
The `compilers` field holds the information about the compilers and
|
|||
|
their settings that have been used to generate the various
|
|||
|
`contractTypes` included in this release.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `compilers`
|
|||
|
* **Type**: Array ([Compiler Information Object](#the-compiler-information-object))
|
|||
|
|
|||
|
### Deployments
|
|||
|
|
|||
|
The `deployments` field holds the information for the chains on which
|
|||
|
this release has [Contract Instances](#contract-instance) as well
|
|||
|
as the [Contract Types](#contract-type) and other deployment
|
|||
|
details for those deployed contract instances. The set of chains defined
|
|||
|
by the [BIP122 URI](#bip122-uri) keys for this object **must** be
|
|||
|
unique. There cannot be two different URI keys in a deployments field
|
|||
|
representing the same blockchain.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `deployments`
|
|||
|
* **Type**: Object (String: Object(String: [Contract Instance Object](#the-contract-instance-object)))
|
|||
|
* **Format**: Keys **must** be a valid BIP122 URI chain definition. <br>Values **must** be objects which conform to the following format:<br>- Keys **must** be valid [Contract Instance Names](#contract-instance-name)<br>- Values **must** be a valid [Contract Instance Object](#the-contract-instance-object)
|
|||
|
|
|||
|
### Build Dependencies
|
|||
|
|
|||
|
The `buildDependencies` field defines a key/value mapping of EthPM
|
|||
|
packages that this project depends on.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `buildDependencies`
|
|||
|
* **Type**: Object (String: String)
|
|||
|
* **Format**: Keys **must** be valid [package names](#package-name).<br>Values **must** be a [Content Addressable URI](#content-addressable-uri) which resolves to a valid package that conforms the same EthPM manifest version as its parent.
|
|||
|
|
|||
|
### Object Definitions
|
|||
|
|
|||
|
Definitions for different objects used within the Package. All objects
|
|||
|
allow custom fields to be included. Custom fields **should** be prefixed
|
|||
|
with `x-` to prevent name collisions with future versions of the
|
|||
|
specification.
|
|||
|
|
|||
|
|
|||
|
### The *Link Reference* Object
|
|||
|
|
|||
|
A [Link Reference](#link-reference) object has the following
|
|||
|
key/value pairs. All link references are assumed to be associated with
|
|||
|
some corresponding [Bytecode](#bytecode).
|
|||
|
|
|||
|
#### Offsets: `offsets`
|
|||
|
|
|||
|
The `offsets` field is an array of integers, corresponding to each of
|
|||
|
the start positions where the link reference appears in the bytecode.
|
|||
|
Locations are 0-indexed from the beginning of the bytes representation
|
|||
|
of the corresponding bytecode. This field is invalid if it references a
|
|||
|
position that is beyond the end of the bytecode.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Type**: Array
|
|||
|
|
|||
|
#### Length: `length`
|
|||
|
|
|||
|
The `length` field is an integer which defines the length in bytes of
|
|||
|
the link reference. This field is invalid if the end of the defined link
|
|||
|
reference exceeds the end of the bytecode.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Type**: Integer
|
|||
|
|
|||
|
#### Name: `name`
|
|||
|
|
|||
|
The `name` field is a string which **must** be a valid
|
|||
|
[Identifier](#identifier). Any link references which **should** be
|
|||
|
linked with the same link value **should** be given the same name.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: String
|
|||
|
* **Format**: **must** conform to the [Identifier](#identifier) format.
|
|||
|
|
|||
|
### The *Link Value* Object
|
|||
|
|
|||
|
Describes a single [Link Value](#link-value).
|
|||
|
|
|||
|
A **Link Value object** is defined to have the following key/value
|
|||
|
pairs.
|
|||
|
|
|||
|
|
|||
|
#### Offsets: `offsets`
|
|||
|
|
|||
|
The `offsets` field defines the locations within the corresponding
|
|||
|
bytecode where the `value` for this link value was written. These
|
|||
|
locations are 0-indexed from the beginning of the bytes representation
|
|||
|
of the corresponding bytecode.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Type**: Integer
|
|||
|
* **Format**: See below.
|
|||
|
|
|||
|
Format
|
|||
|
|
|||
|
Array of integers, where each integer **must** conform to all of the
|
|||
|
following.
|
|||
|
|
|||
|
- greater than or equal to zero
|
|||
|
|
|||
|
- strictly less than the length of the unprefixed hexadecimal
|
|||
|
representation of the corresponding bytecode.
|
|||
|
|
|||
|
#### Type: `type`
|
|||
|
|
|||
|
The `type` field defines the `value` type for determining what is
|
|||
|
encoded when [linking](#linking) the corresponding bytecode.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Type**: String
|
|||
|
* **Allowed Values**: `"literal"` for bytecode literals.<br>`"reference"` for named references to a particular [Contract Instance](#contract-instance)
|
|||
|
|
|||
|
#### Value: `value`
|
|||
|
|
|||
|
The `value` field defines the value which should be written when [linking](#linking) the corresponding bytecode.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Type**: String
|
|||
|
* **Format**: Determined based on `type`, see below.
|
|||
|
|
|||
|
Format
|
|||
|
|
|||
|
For static value *literals* (e.g. address), value **must** be a 0x-prefixed
|
|||
|
hexadecimal string representing bytes.
|
|||
|
|
|||
|
|
|||
|
To reference the address of a [Contract
|
|||
|
Instance](#contract-instance) from the current package the value
|
|||
|
should be the name of that contract instance.
|
|||
|
|
|||
|
- This value **must** be a valid [Contract Instance
|
|||
|
Name](#contract-instance-name).
|
|||
|
|
|||
|
- The chain definition under which the contract instance that this
|
|||
|
link value belongs to must contain this value within its keys.
|
|||
|
|
|||
|
- This value **may not** reference the same contract instance that
|
|||
|
this link value belongs to.
|
|||
|
|
|||
|
To reference a contract instance from a [Package](#package) from
|
|||
|
somewhere within the dependency tree the value is constructed as
|
|||
|
follows.
|
|||
|
|
|||
|
- Let `[p1, p2, .. pn]` define a path down the dependency tree.
|
|||
|
|
|||
|
- Each of `p1, p2, pn` **must** be valid package names.
|
|||
|
|
|||
|
- `p1` **must** be present in keys of the `buildDependencies` for the
|
|||
|
current package.
|
|||
|
|
|||
|
- For every `pn` where `n > 1`, `pn` **must** be present in the keys
|
|||
|
of the `buildDependencies` of the package for `pn-1`.
|
|||
|
|
|||
|
- The value is represented by the string
|
|||
|
`<p1>:<p2>:<...>:<pn>:<contract-instance>` where all of `<p1>`,
|
|||
|
`<p2>`, `<pn>` are valid package names and `<contract-instance>` is
|
|||
|
a valid [Contract Name](#contract-name).
|
|||
|
|
|||
|
- The `<contract-instance>` value **must** be a valid [Contract
|
|||
|
Instance Name](#contract-instance-name).
|
|||
|
|
|||
|
- Within the package of the dependency defined by `<pn>`, all of the
|
|||
|
following must be satisfiable:
|
|||
|
|
|||
|
- There **must** be *exactly* one chain defined under the
|
|||
|
`deployments` key which matches the chain definition that this
|
|||
|
link value is nested under.
|
|||
|
|
|||
|
- The `<contract-instance>` value **must** be present in the keys
|
|||
|
of the matching chain.
|
|||
|
|
|||
|
### The *Bytecode* Object
|
|||
|
|
|||
|
A bytecode object has the following key/value pairs.
|
|||
|
|
|||
|
#### Bytecode: `bytecode`
|
|||
|
|
|||
|
The `bytecode` field is a string containing the `0x` prefixed
|
|||
|
hexadecimal representation of the bytecode.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Type**: String
|
|||
|
* **Format**: `0x` prefixed hexadecimal.
|
|||
|
|
|||
|
#### Link References: `linkReferences`
|
|||
|
|
|||
|
The `linkReferences` field defines the locations in the corresponding
|
|||
|
bytecode which require [linking](#linking).
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: Array
|
|||
|
* **Format**: All values **must** be valid [Link Reference objects](#the-link-reference-object). See also below.
|
|||
|
|
|||
|
Format
|
|||
|
|
|||
|
This field is considered invalid if *any* of the [Link
|
|||
|
References](#link-reference) are invalid when applied to the
|
|||
|
corresponding `bytecode` field, *or* if any of the link references
|
|||
|
intersect.
|
|||
|
|
|||
|
Intersection is defined as two link references which overlap.
|
|||
|
|
|||
|
#### Link Dependencies: `linkDependencies`
|
|||
|
|
|||
|
The `linkDependencies` defines the [Link Values](#link-value) that
|
|||
|
have been used to link the corresponding bytecode.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: Array
|
|||
|
* **Format**: All values **must** be valid [Link Value objects](#the-link-value-object). See also below.
|
|||
|
|
|||
|
Format
|
|||
|
|
|||
|
Validation of this field includes the following:
|
|||
|
|
|||
|
- Two link value objects **must not** contain any of the same values
|
|||
|
for `offsets`.
|
|||
|
|
|||
|
- Each [link value object](#the-link-value-object) **must** have a
|
|||
|
corresponding [link reference object](#the-link-reference-object) under
|
|||
|
the `linkReferences` field.
|
|||
|
|
|||
|
- The length of the resolved `value` **must** be equal to the `length`
|
|||
|
of the corresponding [Link Reference](#link-reference).
|
|||
|
|
|||
|
|
|||
|
### The *Package Meta* Object
|
|||
|
|
|||
|
The *Package Meta* object is defined to have the following key/value
|
|||
|
pairs.
|
|||
|
|
|||
|
#### Authors
|
|||
|
|
|||
|
The `authors` field defines a list of human readable names for the
|
|||
|
authors of this package. Packages **may** include this field.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `authors`
|
|||
|
* **Type**: Array(String)
|
|||
|
|
|||
|
#### License
|
|||
|
|
|||
|
The `license` field declares the license associated with this package.
|
|||
|
This value **should** conform to the
|
|||
|
[SPDX](https://spdx.org/licenses/)
|
|||
|
format. Packages **should** include this field. If a file [Source
|
|||
|
Object](#the-source-object) defines its own license, that license takes
|
|||
|
precedence for that particular file over this package-scoped `meta`
|
|||
|
license.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `license`
|
|||
|
* **Type**: String
|
|||
|
|
|||
|
#### Description
|
|||
|
|
|||
|
The `description` field provides additional detail that may be relevant
|
|||
|
for the package. Packages **may** include this field.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `description`
|
|||
|
* **Type**: String
|
|||
|
|
|||
|
#### Keywords
|
|||
|
|
|||
|
The `keywords` field provides relevant keywords related to this package.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `keywords`
|
|||
|
* **Type**: Array(String)
|
|||
|
|
|||
|
#### Links
|
|||
|
|
|||
|
The `links` field provides URIs to relevant resources associated with
|
|||
|
this package. When possible, authors **should** use the following keys
|
|||
|
for the following common resources.
|
|||
|
|
|||
|
- `website`: Primary website for the package.
|
|||
|
|
|||
|
- `documentation`: Package Documentation
|
|||
|
|
|||
|
- `repository`: Location of the project source code.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `links`
|
|||
|
* **Type**: Object (String: String)
|
|||
|
|
|||
|
### The *Sources* Object
|
|||
|
|
|||
|
A *Sources* object is defined to have the following fields.
|
|||
|
|
|||
|
* **Key**: A unique identifier for the source file. (String)
|
|||
|
* **Value**: [Source Object](#the-source-object)
|
|||
|
|
|||
|
### The *Source* Object
|
|||
|
|
|||
|
#### Checksum: `checksum`
|
|||
|
|
|||
|
Hash of the source file.
|
|||
|
|
|||
|
* **Required**: Only **if** the `content` field is missing and none of the provided URLs contain a content hash.
|
|||
|
* **Key**: `checksum`
|
|||
|
* **Value**: [Checksum Object](#the-checksum-object)
|
|||
|
|
|||
|
#### URLS: `urls`
|
|||
|
|
|||
|
Array of urls that resolve to the same source file.
|
|||
|
- Urls **should** be stored on a content-addressable filesystem.
|
|||
|
**If** they are not, then either `content` or `checksum` **must** be
|
|||
|
included.
|
|||
|
|
|||
|
- Urls **must** be prefixed with a scheme.
|
|||
|
|
|||
|
- If the resulting document is a directory the key **should** be
|
|||
|
interpreted as a directory path.
|
|||
|
|
|||
|
- If the resulting document is a file the key **should** be
|
|||
|
interpreted as a file path.
|
|||
|
|
|||
|
* **Required**: If `content` is not included.
|
|||
|
* **Key**: `urls`
|
|||
|
* **Value**: Array(String)
|
|||
|
|
|||
|
#### Content: `content`
|
|||
|
|
|||
|
Inlined contract source. If both `urls` and `content` are provided, the `content` value
|
|||
|
**must** match the content of the files identified in `urls`.
|
|||
|
|
|||
|
* **Required**: If `urls` is not included.
|
|||
|
* **Key**: `content`
|
|||
|
* **Value**: String
|
|||
|
|
|||
|
#### Install Path: `installPath`
|
|||
|
|
|||
|
Filesystem path of source file.
|
|||
|
- **Must** be a relative filesystem path that begins with a `./`.
|
|||
|
|
|||
|
- **Must** resolve to a path that is within the current virtual
|
|||
|
working directory.
|
|||
|
|
|||
|
- **Must** be unique across all included sources.
|
|||
|
|
|||
|
- **Must not** contain `../` to avoid accessing files outside of
|
|||
|
the source folder in improper implementations.
|
|||
|
|
|||
|
* **Required**: This field **must** be included for the package to be writable to disk.
|
|||
|
* **Key**: `installPath`
|
|||
|
* **Value**: String
|
|||
|
|
|||
|
#### Type: `type`
|
|||
|
|
|||
|
The `type` field declares the type of the source file. The field
|
|||
|
**should** be one of the following values: `solidity`, `vyper`,
|
|||
|
`abi-json`, `solidity-ast-json`.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `type`
|
|||
|
* **Value**: String
|
|||
|
|
|||
|
#### License: `license`
|
|||
|
|
|||
|
The `license` field declares the type of license associated with
|
|||
|
this source file. When defined, this license overrides the
|
|||
|
package-scoped [meta license](#license).
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `license`
|
|||
|
* **Value**: String
|
|||
|
|
|||
|
### The *Checksum* Object
|
|||
|
|
|||
|
A *Checksum* object is defined to have the following key/value pairs.
|
|||
|
|
|||
|
#### Algorithm: `algorithm`
|
|||
|
|
|||
|
The `algorithm` used to generate the corresponding hash. Possible
|
|||
|
algorithms include, but are not limited to `sha3`, `sha256`, `md5`,
|
|||
|
`keccak256`.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Type**: String
|
|||
|
|
|||
|
#### Hash: `hash`
|
|||
|
|
|||
|
The `hash` of a source files contents generated with the corresponding
|
|||
|
algorithm.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Type**: String
|
|||
|
|
|||
|
### The *Contract Type* Object
|
|||
|
|
|||
|
A *Contract Type* object is defined to have the following key/value
|
|||
|
pairs.
|
|||
|
|
|||
|
#### Contract Name: `contractName`
|
|||
|
|
|||
|
The `contractName` field defines the [Contract
|
|||
|
Name](#contract-name) for this [Contract
|
|||
|
Type](#contract-type).
|
|||
|
|
|||
|
* **Required**: If the [Contract Name](#contract-name) and [Contract Alias](#contract-alias) are not the same.
|
|||
|
* **Type**: String
|
|||
|
* **Format**: **Must** be a valid [Contract Name](#contract-name)
|
|||
|
|
|||
|
#### Source ID: `sourceId`
|
|||
|
|
|||
|
The global source identifier for the source file from which this
|
|||
|
contract type was generated.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: String
|
|||
|
* **Format**: **Must** match a unique source ID included in the [Sources Object](#the-sources-object) for this package.
|
|||
|
|
|||
|
#### Deployment Bytecode: `deploymentBytecode`
|
|||
|
|
|||
|
The `deploymentBytecode` field defines the bytecode for this [Contract
|
|||
|
Type](#contract-type).
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: Object
|
|||
|
* **Format**: **Must** conform to the [Bytecode object](#the-bytecode-object) format.
|
|||
|
|
|||
|
#### Runtime Bytecode: `runtimeBytecode`
|
|||
|
|
|||
|
The `runtimeBytecode` field defines the unlinked `0x`-prefixed runtime
|
|||
|
portion of [Bytecode](#bytecode) for this [Contract
|
|||
|
Type](#contract-type).
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: Object
|
|||
|
* **Format**: **Must** conform to the [Bytecode object](#the-bytecode-object) format.
|
|||
|
|
|||
|
#### ABI: `abi`
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: Array
|
|||
|
* **Format**: **Must** conform to the [Ethereum Contract ABI JSON](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#json) format.
|
|||
|
|
|||
|
#### UserDoc: `userdoc`
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: Object
|
|||
|
* **Format**: **Must** conform to the [UserDoc](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format#user-documentation) format.
|
|||
|
|
|||
|
#### DevDoc: `devdoc`
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: Object
|
|||
|
* **Format**: **Must** conform to the [DevDoc](https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format#developer-documentation) format.
|
|||
|
|
|||
|
### The *Contract Instance* Object
|
|||
|
|
|||
|
A **Contract Instance Object** represents a single deployed [Contract
|
|||
|
Instance](#contract-instance) and is defined to have the following
|
|||
|
key/value pairs.
|
|||
|
|
|||
|
#### Contract Type: `contractType`
|
|||
|
|
|||
|
The `contractType` field defines the [Contract
|
|||
|
Type](#contract-type) for this [Contract
|
|||
|
Instance](#contract-instance). This can reference any of the
|
|||
|
contract types included in this [Package](#package) *or* any of the
|
|||
|
contract types found in any of the package dependencies from the
|
|||
|
`buildDependencies` section of the [Package
|
|||
|
Manifest](#package-manifest).
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Type**: String
|
|||
|
* **Format**: See below.
|
|||
|
|
|||
|
Format
|
|||
|
|
|||
|
Values for this field **must** conform to *one of* the two formats
|
|||
|
herein.
|
|||
|
|
|||
|
To reference a contract type from this Package, use the format
|
|||
|
`<contract-alias>`.
|
|||
|
|
|||
|
- The `<contract-alias>` value **must** be a valid [Contract
|
|||
|
Alias](#contract-alias).
|
|||
|
|
|||
|
- The value **must** be present in the keys of the `contractTypes`
|
|||
|
section of this Package.
|
|||
|
|
|||
|
To reference a contract type from a dependency, use the format
|
|||
|
`<package-name>:<contract-alias>`.
|
|||
|
|
|||
|
- The `<package-name>` value **must** be present in the keys of the
|
|||
|
`buildDependencies` of this Package.
|
|||
|
|
|||
|
- The `<contract-alias>` value **must** be be a valid [Contract
|
|||
|
Alias](#contract-alias).
|
|||
|
|
|||
|
- The resolved package for `<package-name>` must contain the
|
|||
|
`<contract-alias>` value in the keys of the `contractTypes` section.
|
|||
|
|
|||
|
#### Address: `address`
|
|||
|
|
|||
|
The `address` field defines the [Address](#address) of the
|
|||
|
[Contract Instance](#contract-instance).
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Type**: String
|
|||
|
* **Format**: Hex encoded `0x` prefixed Ethereum address matching the regular expression `^0x[0-9a-fA-F]{40}$`.
|
|||
|
|
|||
|
#### Transaction: `transaction`
|
|||
|
|
|||
|
The `transaction` field defines the transaction hash in which this
|
|||
|
[Contract Instance](#contract-instance) was created.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: String
|
|||
|
* **Format**: `0x` prefixed hex encoded transaction hash.
|
|||
|
|
|||
|
#### Block: `block`
|
|||
|
|
|||
|
The `block` field defines the block hash in which this the transaction
|
|||
|
which created this *contract instance* was mined.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: String
|
|||
|
* **Format**: `0x` prefixed hex encoded block hash.
|
|||
|
|
|||
|
#### Runtime Bytecode: `runtimeBytecode`
|
|||
|
|
|||
|
The `runtimeBytecode` field defines the runtime portion of bytecode for
|
|||
|
this [Contract Instance](#contract-instance). When present, the
|
|||
|
value from this field supersedes the `runtimeBytecode` from the
|
|||
|
[Contract Type](#contract-type) for this [Contract
|
|||
|
Instance](#contract-instance).
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Type**: Object
|
|||
|
* **Format**: **Must** conform to the [Bytecode Object](#the-bytecode-object) format.
|
|||
|
|
|||
|
Every entry in the `linkReferences` for this bytecode **must** have a
|
|||
|
corresponding entry in the `linkDependencies` section.
|
|||
|
|
|||
|
### The *Compiler Information* Object
|
|||
|
|
|||
|
The `compilers` field defines the various compilers and settings used
|
|||
|
during compilation of any [Contract Types](#contract-type) or
|
|||
|
[Contract Instance](#contract-instance) included in this package.
|
|||
|
|
|||
|
A *Compiler Information* object is defined to have the following
|
|||
|
key/value pairs.
|
|||
|
|
|||
|
#### Name: `name`
|
|||
|
|
|||
|
The `name` field defines which compiler was used in compilation.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Key**: `name`
|
|||
|
* **Type**: String
|
|||
|
|
|||
|
#### Version: `version`
|
|||
|
|
|||
|
The `version` field defines the version of the compiler. The field
|
|||
|
**should** be OS agnostic (OS not included in the string) and take the
|
|||
|
form of either the stable version in
|
|||
|
[semver](http://semver.org/) format or if built on a
|
|||
|
nightly should be denoted in the form of `<semver>-<commit-hash>` ex:
|
|||
|
`0.4.8-commit.60cc1668`.
|
|||
|
|
|||
|
* **Required**: Yes
|
|||
|
* **Key**: `version`
|
|||
|
* **Type**: String
|
|||
|
|
|||
|
#### Settings: `settings`
|
|||
|
|
|||
|
The `settings` field defines any settings or configuration that was used
|
|||
|
in compilation. For the `"solc"` compiler, this **should** conform to
|
|||
|
the [Compiler Input and Output
|
|||
|
Description](http://solidity.readthedocs.io/en/latest/using-the-compiler.html#compiler-input-and-output-json-description).
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `settings`
|
|||
|
* **Type**: Object
|
|||
|
|
|||
|
#### Contract Types: `contractTypes`
|
|||
|
|
|||
|
A list of the [Contract Alias](#contract-alias) or [Contract Types](#contract-type) in this package
|
|||
|
that used this compiler to generate its outputs.
|
|||
|
|
|||
|
- All `contractTypes` that locally declare `runtimeBytecode`
|
|||
|
**should** be attributed for by a compiler object.
|
|||
|
|
|||
|
- A single `contractTypes` **must** not be attributed to more than one
|
|||
|
compiler.
|
|||
|
|
|||
|
* **Required**: No
|
|||
|
* **Key**: `contractTypes`
|
|||
|
* **Type**: Array([Contract Alias](#contract-alias))
|
|||
|
|
|||
|
|
|||
|
### BIP122 URI
|
|||
|
|
|||
|
BIP122 URIs are used to define a blockchain via a subset of the
|
|||
|
[BIP-122](https://github.com/bitcoin/bips/blob/master/bip-0122.mediawiki)
|
|||
|
spec.
|
|||
|
|
|||
|
blockchain://<genesis_hash>/block/<latest confirmed block hash>
|
|||
|
|
|||
|
The `<genesis hash>` represents the blockhash of the first block on the
|
|||
|
chain, and `<latest confirmed block hash>` represents the hash of the
|
|||
|
latest block that’s been reliably confirmed (package managers should be
|
|||
|
free to choose their desired level of confirmations).
|
|||
|
|
|||
|
### Glossary
|
|||
|
|
|||
|
The terms in this glossary have been updated to reflect the changes made
|
|||
|
in V3.
|
|||
|
|
|||
|
#### ABI
|
|||
|
The JSON representation of the application binary interface. See the
|
|||
|
official
|
|||
|
[specification](https://solidity.readthedocs.io/en/develop/abi-spec.html)
|
|||
|
for more information.
|
|||
|
|
|||
|
#### Address
|
|||
|
A public identifier for an account on a particular chain
|
|||
|
|
|||
|
#### Bytecode
|
|||
|
The set of EVM instructions as produced by a compiler. Unless otherwise
|
|||
|
specified this should be assumed to be hexadecimal encoded, representing
|
|||
|
a whole number of bytes, and [prefixed](#prefixed) with `0x`.
|
|||
|
|
|||
|
Bytecode can either be linked or unlinked. (see
|
|||
|
[Linking](#linking))
|
|||
|
|
|||
|
* **Unlinked Bytecode**: The hexadecimal representation of a contract’s EVM instructions that contains sections of code that requires [linking](#linking) for the contract to be functional.<br>The sections of code which are unlinked **must** be filled in with zero bytes.<br>**Example**: `0x606060405260e06000730000000000000000000000000000000000000000634d536f`
|
|||
|
* **Linked Bytecode**: The hexadecimal representation of a contract’s EVM instructions which has had all [Link References](#link-reference) replaced with the desired [Link Values](#link-value). **Example**: `0x606060405260e06000736fe36000604051602001526040518160e060020a634d536f`
|
|||
|
|
|||
|
#### Chain Definition
|
|||
|
This definition originates from [BIP122
|
|||
|
URI](https://github.com/bitcoin/bips/blob/master/bip-0122.mediawiki).
|
|||
|
|
|||
|
A URI in the format `blockchain://<chain_id>/block/<block_hash>`
|
|||
|
|
|||
|
- `chain_id` is the unprefixed hexadecimal representation of the
|
|||
|
genesis hash for the chain.
|
|||
|
|
|||
|
- `block_hash` is the unprefixed hexadecimal representation of the
|
|||
|
hash of a block on the chain.
|
|||
|
|
|||
|
A chain is considered to match a chain definition if the the genesis
|
|||
|
block hash matches the `chain_id` and the block defined by `block_hash`
|
|||
|
can be found on that chain. It is possible for multiple chains to match
|
|||
|
a single URI, in which case all chains are considered valid matches
|
|||
|
|
|||
|
#### Content Addressable URI
|
|||
|
Any URI which 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
|
|||
|
|
|||
|
It is **recommended** that tools support IPFS and Swarm.
|
|||
|
|
|||
|
#### Contract Alias
|
|||
|
This is a name used to reference a specific [Contract
|
|||
|
Type](#contract-type). Contract aliases **must** be unique within a
|
|||
|
single [Package](#package).
|
|||
|
|
|||
|
The contract alias **must** use *one of* the following naming schemes:
|
|||
|
|
|||
|
- `<contract-name>`
|
|||
|
|
|||
|
- `<contract-name><identifier>`
|
|||
|
|
|||
|
The `<contract-name>` portion **must** be the same as the [Contract
|
|||
|
Name](#contract-name) for this contract type.
|
|||
|
|
|||
|
The `<identifier>` portion **must** match the regular expression
|
|||
|
`^[-a-zA-Z0-9]{1,256}$`.
|
|||
|
|
|||
|
#### Contract Instance
|
|||
|
A contract instance a specific deployed version of a [Contract
|
|||
|
Type](#contract-type).
|
|||
|
|
|||
|
All contract instances have an [Address](#address) on some specific
|
|||
|
chain.
|
|||
|
|
|||
|
#### Contract Instance Name
|
|||
|
A name which refers to a specific [Contract
|
|||
|
Instance](#contract-instance) on a specific chain from the
|
|||
|
deployments of a single [Package](#package). This name **must** be
|
|||
|
unique across all other contract instances for the given chain. The name
|
|||
|
must conform to the regular expression
|
|||
|
`^[a-zA-Z_$][a-zA-Z0-9_$]{0,255}$`
|
|||
|
|
|||
|
In cases where there is a single deployed instance of a given [Contract
|
|||
|
Type](#contract-type), package managers **should** use the
|
|||
|
[Contract Alias](#contract-alias) for that contract type for this
|
|||
|
name.
|
|||
|
|
|||
|
In cases where there are multiple deployed instances of a given contract
|
|||
|
type, package managers **should** use a name which provides some added
|
|||
|
semantic information as to help differentiate the two deployed instances
|
|||
|
in a meaningful way.
|
|||
|
|
|||
|
#### Contract Name
|
|||
|
The name found in the source code that defines a specific [Contract
|
|||
|
Type](#contract-type). These names **must** conform to the regular
|
|||
|
expression `^[a-zA-Z_$][a-zA-Z0-9_$]{0,255}$`.
|
|||
|
|
|||
|
There can be multiple contracts with the same contract name in a
|
|||
|
projects source files.
|
|||
|
|
|||
|
#### Contract Type
|
|||
|
Refers to a specific contract in the package source. This term can be
|
|||
|
used to refer to an abstract contract, a normal contract, or a library.
|
|||
|
Two contracts are of the same contract type if they have the same
|
|||
|
bytecode.
|
|||
|
|
|||
|
Example:
|
|||
|
|
|||
|
contract Wallet {
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
A deployed instance of the `Wallet` contract would be of of type
|
|||
|
`Wallet`.
|
|||
|
|
|||
|
#### Identifier
|
|||
|
Refers generally to a named entity in the [Package](#package).
|
|||
|
|
|||
|
A string matching the regular expression
|
|||
|
`^[a-zA-Z][-_a-zA-Z0-9]{0,255}$`
|
|||
|
|
|||
|
#### Link Reference
|
|||
|
A location within a contract’s bytecode which needs to be linked. A link
|
|||
|
reference has the following properties.
|
|||
|
|
|||
|
* **`offset`**: Defines the location within the bytecode where the link reference begins.
|
|||
|
* **`length`**: Defines the length of the reference.
|
|||
|
* **`name`**: (optional) A string to identify the reference.
|
|||
|
|
|||
|
#### Link Value
|
|||
|
A link value is the value which can be inserted in place of a [Link
|
|||
|
Reference](#link-reference)
|
|||
|
|
|||
|
#### Linking
|
|||
|
The act of replacing [Link References](#link-reference) with [Link
|
|||
|
Values](#link-value) within some [Bytecode](#bytecode).
|
|||
|
|
|||
|
#### Package
|
|||
|
Distribution of an application’s source or compiled bytecode along with
|
|||
|
metadata related to authorship, license, versioning, et al.
|
|||
|
|
|||
|
For brevity, the term **Package** is often used metonymously to mean
|
|||
|
[Package Manifest](#package-manifest).
|
|||
|
|
|||
|
#### Package Manifest
|
|||
|
A machine-readable description of a package.
|
|||
|
|
|||
|
#### Prefixed
|
|||
|
[Bytecode](#bytecode) string with leading `0x`.
|
|||
|
|
|||
|
* **Example**: `0xdeadbeef`
|
|||
|
|
|||
|
#### Unprefixed
|
|||
|
Not [Prefixed](#prefixed).
|
|||
|
|
|||
|
* **Example**: `deadbeef`
|
|||
|
|
|||
|
## Rationale
|
|||
|
|
|||
|
### Minification
|
|||
|
|
|||
|
EthPM packages are distributed as alphabetically-ordered & minified JSON to ensure consistency.
|
|||
|
Since packages are published on content-addressable filesystems (eg. IPFS), this restriction
|
|||
|
guarantees that any given set of contract assets will always resolve to the same content-addressed URI.
|
|||
|
|
|||
|
### Package Names
|
|||
|
|
|||
|
Package names are restricted to lower-case characters, numbers, and `-` to improve the readability
|
|||
|
of the package name, in turn improving the security properties for a package. A user is more likely
|
|||
|
to accurately identify their target package with this restricted set of characters, and not confuse
|
|||
|
a malicious package that disguises itself as a trusted package with similar but different
|
|||
|
characters (e.g. `O` and `0`).
|
|||
|
|
|||
|
### BIP122
|
|||
|
|
|||
|
The BIP-122 standard has been used since EthPM v1 since it is an industry standard URI scheme for
|
|||
|
identifying different blockchains and distinguishing between forks.
|
|||
|
|
|||
|
### Compilers
|
|||
|
|
|||
|
Compilers are now defined in a top-level array, simplifying the task for tooling to identify the compiler types
|
|||
|
needed to interact with or validate the contract assets. This also removes unnecessarily duplicated
|
|||
|
information, should multiple `contractTypes` share the same compiler type.
|
|||
|
|
|||
|
## Backwards Compatibility
|
|||
|
|
|||
|
To improve understanding and readability of the EthPM spec, the
|
|||
|
`manifest_version` field was updated to `manifest` in v3. To ensure
|
|||
|
backwards compatibility, v3 packages **must** define a top-level
|
|||
|
`"manifest"` with a value of `"ethpm/3"`. Additionally,
|
|||
|
`"manifest_version"` is a forbidden top-level key in v3 packages.
|
|||
|
|
|||
|
|
|||
|
## Security Considerations
|
|||
|
|
|||
|
Using EthPM packages implicitly requires importing &/or executing code written by others. The EthPM spec
|
|||
|
guarantees that when using a properly constructed and released EthPM package, the user will have the exact same
|
|||
|
code that was included in the package by the package author. However, it is impossible to guarantee that this code
|
|||
|
is safe to interact with. Therefore, it is critical that end users only interact with EthPM packages authored and
|
|||
|
released by individuals or organizations that they trust to include non-malicious code.
|
|||
|
|
|||
|
|
|||
|
## Copyright
|
|||
|
|
|||
|
Copyright and related rights waived via [CC0](../LICENSE.md).
|