Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gnidan/link ref updates #162

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
267 changes: 172 additions & 95 deletions release-lockfile.spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,32 +43,42 @@ The set of EVM instructions as produced by a compiler. Unless otherwise
specified this should be assumed to be hexidecimal encoded and prefixed with a
`'0x'`.


#### Binary Bytecode

The binary representation of bytecode is defined as the raw bytes.


#### Unlinked Bytecode

Unlinked bytecode is the hexidecimal representation of a contract's EVM
instructions which contains placeholders which are referred to as *link
references*.
instructions which contains sections of code which require *linking* for the
contract to be functional.

* Unlinked Bytecode: `606060405260e0600073__MathLib_______________________________634d536f`
The sections of code which are unlinked **must** be filled in with zero bytes.


#### Linked Bytecode
* unlinked bytecode: `0x606060405260e06000730000000000000000000000000000000000000000634d536f`

Linked bytecode is the hexidecimal representation of a contract's EVM instructions which has hadd all *link references* replaced with the desired *link values*

* linked Bytecode: `606060405260e06000736fe36000604051602001526040518160e060020a634d536f`
#### Linked Bytecode

Linked bytecode is the hexidecimal representation of a contract's EVM
instructions which has had all *link references* replaced with the desired
*link values*

#### Link Reference
* linked bytecode: `0x606060405260e06000736fe36000604051602001526040518160e060020a634d536f`

A placeholder within the hexidecimal representation of a contract's EVM instructions.

`606060405260e0600073__MathLib_______________________________634d536f` the
#### Link Reference

In the bytecode
`606060405260e0600073__MathLib_______________________________634d536f`, the
substring `__MathLib_______________________________` is a link reference.
A location within a contract's bytecode which needs to be linked. A link
reference has the following properties.

* `offsets`: Defines the location within the bytecode where the link reference begins.
* `length`: Defines the length of the reference.
* `name`: A string that **must** match the regular expression
`[a-zA-Z][-a-zA-Z0-9_]*`.

#### Link Value

Expand Down Expand Up @@ -282,14 +292,149 @@ this project depends on.
* Values **must** be valid IPFS URIs which resolve to a valid *Release Lock File*


## Object Definitions
## Definitions

Definitions for different objects used within the release lockfile. 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 object has the following key/value pairs. All link references
are assumed to be associated with some corresponding bytecode.

#### Offset: `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 binary 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 *Contract Name*. 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 *Contract Name* format.


### The *Link Value* Object

A *Link Value* object is defined to have the following key/value pairs.


#### Offset `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 binary representation of the
corresponding bytecode.

* Required: Yes
* Type: Array
* Format: Array of integers, where each integer **must** conform to all of the following:
* be greater than or equal to zero
* strictly less than the length of the unprefixed hexidecimal representation of the corresponding bytecode.


#### Value `value`

The `value` field defines the value which should be written when *linking* the
corresponding bytecode.

* Required: Yes
* Type: String
* Format: One of the following formats.

To reference the address of a *contract instance* from the current release lockfile
the value should be the name of that *contract instance*.

* This value **must** be a valid *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 lockfile 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 `build_dependencies` for the current release lockfile.
* For every `pn` where `n > 1`, `pn` **must** be present in the keys of the `build_dependencies` of the lockfile 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.
* The `<contract-instance>` value **must** be a valid *contract instance* name.
* Within the release lockfile of the package 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.

To references a static address use the `'0x'` prefixed address as the value.


### The *Bytecode* Object

A bytecode object has the following key/value pairs.

#### Bytecode: `bytecode`

The `bytecode` field is a string containing the `0x` prefixed hexidecimal
representation of the bytecode.

* Required: Yes
* Type: String
* Format: `0x` prefixed hexidecimal.

#### Link References: `link_references`

The `link_references` field defines the locations in the corresponding bytecode
which require linking.

* Required: No
* Type: Array
* Format: All values **must** be valid *Link Reference* objects

This field is considered invalid if *any* of the link references 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: `link_dependencies`

The `link_dependencies` defines the *link values* that have been used to link
the corresponding bytecode.

* Required: No
* Type: Array
* Format: All values **must** be valid *Link Value* objects

Validation of this field includes the following:

* No two link value objects may contain any of the same values for `offsets`.
* Each link value object **must** have a corresponding link reference object under the `link_references` field.
* The length of the resolved `value` **must** be equal to the `length` of the corresponding link reference.


### The *Package Meta* Object

The *Package Meta* object is defined to have the following key/value pairs.
Expand Down Expand Up @@ -366,11 +511,11 @@ The `contract_name` field defines *contract name* for this *contract type*.

#### Bytecode `bytecode`

The `bytecode` field defines the unlinked `'0x'` prefixed bytecode for this *contract type*
The `bytecode` field defines the bytecode for this *contract type*

* Required: No
* Type: String
* Format: Hex encoded unlinked bytecode for the compiled contract.
* Type: Object
* Format: **must** conform to the *Bytecode* object format.


#### Runtime Bytecode `runtime_bytecode`
Expand All @@ -379,8 +524,8 @@ The `runtime_bytecode` field defines the unlinked `'0x'` prefixed runtime
portion of bytecode for this *contract type*.

* Required: No
* Type: String
* Format: Hex encoded unlinked runtime portion of the bytecode for the compiled contract.
* Type: Object
* Format: **must** conform to the *Bytecode* object format.


#### ABI `abi`
Expand Down Expand Up @@ -465,14 +610,17 @@ created this *contract instance* was mined.

#### Runtime Bytecode `runtime_bytecode`

The `runtime_bytecode` field defines the unlinked `'0x'` prefixed runtime
portion of bytecode for this *contract instance*. When present, the value from
this field takes priority over the `runtime_bytecode` from the
*contract_type* for this *contract instance*.
The `runtime_bytecode` field defines the runtime portion of bytecode for this
*contract instance*. When present, the value from this field supersedes
the `runtime_bytecode` from the *contract_type* for this *contract
instance*.

* Required: No
* Type: String
* Format: Hex encoded unlinked runtime portion of the bytecode for the compiled contract.
* Type: Object
* Format: **must** conform to the *Bytecode* object format.

Every entry in the `link_references` for this bytecode **must** have a
corresponding entry in the `link_dependencies` section.


#### Compiler `compiler`
Expand All @@ -486,77 +634,6 @@ compilation of this *contract class*. This field **should** be present in all
* Format: **must** conform the the *Compiler Information* object format.


#### Link Dependencies `link_dependencies`

The `link_dependencies` defines the values which were used to fill in any
*link* references which are present in the `runtime_bytecode` for this
*contract instance*. This field **must** be present if there are any *link
references* in the `runtime_bytecode` for this *contract instance*. This field
**must** contain an entry for all *link references* found the `runtime_bytecode`.

* Required: If there are any *link references* in the `runtime_bytecode` for the *contract type* of this *contract instance*.
* Type: Array
* Format: All values **must** be valid *Link Value* objects


### The *Link Value* Object

A *Link Value* object is defined to have the following key/value pairs.


#### Offset `offset`

The `offset` field defines the location within the corresponding bytecode where
the `value` for this *link value* should be written. This location is a
0-indexed offset from the beginning of the unprefixed hexidecimal
representation of the bytecode.

* Required: Yes
* Type: Integer
* Format: The integer **must** conform to all of the following:
* be greater than or equal to zero
* strictly less than the length of the unprefixed hexidecimal representation of the corresponding bytecode.


#### Value `value`

The `value` field defines the value which should be written when *linking* the
corresponding bytecode.

* Required: Yes
* Type: String
* Format: One of the following formats.

To reference the address of a *contract instance* from the current release lockfile
the value should be the name of that *contract instance*.

* This value **must** be a valid *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 lockfile from somewhere within the
dependency tree the value is constructed as follows.

* Let `[p1, p2, .. pn]` define the path down the dependency tree.
* Each of `p1, p2, pn` are dependency names.
* `p1` **must** be present in keys of the `build_dependencies` for the current release lockfile.
* For every `pn` where `n > 1`, `pn` **must** be present in the keys of the `build_dependencies` of the lockfile 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.
* The `<contract-instance>` value **must** be a valid *contract instance* name.
* Within the release lockfile of the package 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.

To references a static address use the `'0x'` prefixed address as the value.
Package managers **should not** use this pattern when building releases that
will be published as open source packages or that are intended to be used
outside of a closed system. Package managers **should** require some form of
explicit input from the user such as a command line flag like
`--allow-unverifiable-linking` before linking code with this type of *link
value*.


### The *Compiler Information* Object

The `compiler` field defines the compiler information that was used during
Expand Down
Loading