Skip to content

ABI: enums, structs and timestamps #50

@chriseth

Description

@chriseth

This is a combination of several already existing issues about extensions to the ABI. It subsumes #21, #46 and #47.

Time Units

Add the following new elementary types to the ABI:
timestamp, timespan
Encoding: identical to int256 for both
Semantics:

  • timestamp: point in time as seconds since the unix epoch (Discussion: As we have int256 we could also make it milli or microseconds)
  • timespan: a span of time in seconds (or smaller unit as above)

Enums

At any point in an interface definition where an elementary type is allowed, the following is also allowed:
(A|), (A|B), (A|B|C), ... for A, B, C being from [_$a-zA-Z][_$a-zA-Z0-9]*

Such a type is called an "enum" and the identifiers A, B, C, ... are encoded as 0, 1, 3, ..., respectively. This means that languages and user interfaces should prefer names over numeric values, but the names are not visible in the binary encoding and the type is treated identical to uint256.

Structs

Structs allow several values to be grouped together. This is especially useful if arrays of structs are created. If you look closely, you notice that the set of return values or arguments is already a struct now and the notation will be consistent with this proposal.

Change to function signatures as needed for function identifiers

As function signatures omit parameter names and only specify their types, and struct types should be a generalisation of a list of parameters / return parameters, the following change is proposed:

At any point where a type is allowed, a list of types in the from (type1,type2,..) is permitted, to the extent where there may be only one type. Examples:

function f((uint256[],uint8,(string,bytes20),(string))[20])

The function takes an array of 20 objects, each of which is of the following type:

  • The first value is a dynamic array of uint256s,
  • the second is a uint8,
  • the third is an object that consists of a string and a bytes20
  • the fourth is an object that only holds a string

Note that this notation is (hopefully) bijective.

Encoding

Structs are actually already part of the encoding specification, hidden in this comment. The gist is that the way arrays are encoded does not rely on the fact that the encoding of every element of the array is the same, so we can encode structs in just the same way as we encode arrays. This means that the encoding of a struct with only fixed-size types is the concatenation of the encodings of its elements. If there are dynamic types, their dynamic part is added at the end and the offset to the dynamic part is calculated from the start of the struct. This means that the offset to the string data is computed in a different way for (uint256,string) and (uint256,(string)).

JSON-formatted abi:

inputs and outputs is an array of objects with properties name (optional), type, subtype (optional, new) and indexed (for events). type can be any of the already supported types ("uint256", "uint256[10][]", ...), but additional values are permitted:

  • "[]" or "[k]" for some integer k (or a sequence of those, i.e. [][10][]): If this is used, the object is of array type and the type of the elements of the arrays is specified under the property subtype.
  • an non-empty array of objects as described here - this models a tuple.

If the subtype property is used, its value cannot be "[]" or "[k]", but it can be an array of length 1 whose element models the type one deeper in the array hierarchy.

Example:

The signature function f(abc: uint, def: (a: uint, b: (c: string, d: uint16)[10]))) is translated into json-abi as follows:

{
  name: "f",
  inputs: [
    {name: "abc", type: "uint256"},
    {name: "def", type: [
      {name: "a", type: "uint256"},
      {name: "b", type: "[10]", subtype: [{name: "c", type: "string"}, {name: "d", type: "uint16"}]}
    ]}
  ]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions