diff --git a/release-lockfile.spec.md b/release-lockfile.spec.md index 57bc210..74f7c5a 100644 --- a/release-lockfile.spec.md +++ b/release-lockfile.spec.md @@ -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 @@ -282,7 +292,7 @@ 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 @@ -290,6 +300,141 @@ 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 `::<...>::` where all of ``, ``, `` are valid package names and `` is a valid contract name. +* The `` value **must** be a valid *contract instance* name. +* Within the release lockfile of the package dependency defined by ``, 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 `` 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. @@ -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` @@ -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` @@ -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` @@ -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 `::<...>::` where all of ``, ``, `` are valid package names and `` is a valid contract name. -* The `` value **must** be a valid *contract instance* name. -* Within the release lockfile of the package dependency defined by ``, 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 `` 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 diff --git a/spec/release-lockfile.spec.json b/spec/release-lockfile.spec.json index 57524cb..1cabc9d 100644 --- a/spec/release-lockfile.spec.json +++ b/spec/release-lockfile.spec.json @@ -123,12 +123,10 @@ "pattern": "[a-zA-Z][a-zA-Z0-9_]*" }, "bytecode": { - "title": "The unlinked '0x' prefixed bytecode for this contract type", - "type": "string" + "$ref": "#/definitions/BytecodeObject" }, "runtime_bytecode": { - "title": "The unlinked '0x' prefixed runtime portion of the bytecode for this contract type", - "type": "string" + "$ref": "#/definitions/BytecodeObject" }, "abi": { "title": "The ABI for this contract type", @@ -165,8 +163,7 @@ "$ref": "#/definitions/BlockHash" }, "runtime_bytecode": { - "title": "The on-chain bytecode for this contract instance.", - "type": "string" + "$ref": "#/definitions/BytecodeObject" }, "compiler": { "$ref": "#/definitions/CompilerInformation" @@ -180,17 +177,68 @@ } } }, + "BytecodeObject": { + "title": "Contract bytecode", + "type": "object", + "required": ["bytecode"], + "properties": { + "bytecode": { + "type": "string", + "pattern": "^0x[0-9a-fA-F]*$" + }, + "link_references": { + "type": "array", + "items": { + "$ref": "#/definitions/LinkReference" + } + }, + "link_dependencies": { + "type": "array", + "items": { + "$ref": "#/definitions/LinkValue" + } + } + } + }, + "LinkReference": { + "title": "A defined location in some bytecode which requires linking", + "type": "object", + "required": [ + "offsets", + "length", + "name" + ], + "properties": { + "offsets": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + } + }, + "length": { + "type": "integer", + "minimum": 1 + }, + "name": { + "$ref": "#/definitions/Identifier" + } + } + }, "LinkValue": { "title": "A value for an individual link reference in a contract's bytecode", "type": "object", "required": [ - "offset", + "offsets", "value" ], "properties": { - "offset": { - "type": "integer", - "minimum": 0 + "offsets": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + } }, "value": { "title": "The value for the link reference", @@ -203,6 +251,10 @@ } } }, + "Identifier": { + "type": "string", + "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$" + }, "ContractInstanceName": { "title": "The name of the deployed contract instance", "type": "string",