Encoding data for an Aleo program#
In order to have trust in attestation data the oracle contract needs to verify the attestation response and attestation report.
To do that, the response and report must be inputs to the contract in some format that makes it possible to read and make asserts on them. For example, an oracle should verify the report's signature, TEE measurements, make assertions on the attestation URL, status code, etc.
To achieve that, the response and report must be serialized and encoded in a specific way.
Encoding of the Attestation Response + attestation results (Report Data) happens on the backend.
Encoding header#
The encoded Report Data contains a header in the first 2 u128
that contains meta information about the encoded properties.
It helps decoding and deserializing the Report Data in Aleo back to the human-readable form.
Number of u128
: 2.
Encoding Report Data#
Here's the description of the encoding of a response. Every item in the list is written to a single buffer, every item is padded at the end with zeroes to align to 16, every item takes at least 16 bytes.
Here are the steps that are done for serialization and encoding Report Data:
- Encode Attestation Data
- Encode Attestation Timestamp
- Encode HTTP response status code
- Encode Attestation Target URL as bytes of the string
- Encode selector as bytes of the string
- Encode response format
- Encode request method as bytes of the string
- Encode encoding options object
- Encode request headers
- Encode HTML result type, request content type and request body. These 3 fields are optional in the request, and they are encoded even if they are empty.
1. Encode Attestation Data#
Encoding the Attestation Data is described in the Guide to understanding the Attestation Response.
Number of u128
: variable, check AttestationResponse.oracleData.encodedPositions.data
.
2. Encode Attestation Timestamp#
Encoding the Attestation Timestamp is done the same as encoding integer Attestation Data - the number is converted to little
endian bytes, padded to 16 bytes, then encoded as Aleo's u128
.
3. Encode HTTP response status code#
The Attestation HTTP response status code is encoded the same way as the Timestamp.
Number of u128
: 1.
4. Encode Attestation Target URL as bytes of the string#
The Attestation Target URL is serialized and encoded the same way as encoding string Attestation Data.
Number of u128
: variable, check AttestationResponse.oracleData.encodedPositions.url
.
5. Encode selector as bytes of the string#
The notarization selector is serialized and encoded the same way as encoding string Attestation Data.
Number of u128
: variable, check AttestationResponse.oracleData.encodedPositions.selector
.
6. Encode response format#
The response format encoded as 1 byte with the values:
0
for JSON1
for HTML
The value is set in the first little endian byte.
Number of u128
: 1.
7. Encode request method as bytes of the string#
The notarization request method is serialized and encoded the same way as encoding string Attestation Data.
Number of u128
: variable, check AttestationResponse.oracleData.encodedPositions.method
.
8. Encode encoding options object#
The encoding options themselves are encoded in 2 bytes.
The first little endian byte indicates the encoding options value:
0
forstring
1
forint
2
forfloat
If the encoding options value is float
, the ninth little endian byte will contain the encoding precision.
Example
Description | u128 bytes |
---|---|
Encoding string encoding options | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
Encoding integer encoding options | 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
Encoding float encoding options with precision 5 | 2 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 |
Number of u128
: 1.
9. Encode request headers#
Encoding Attestation Request headers starts with sorting headers alphabetically, then the headers are encoded using the following format:
- The first
u128
consists of the number of header key-value pairs in the first 8 little endian bytes, followed by 8 bytes of the **number ofu128**
that the encoded headers take (minus this one). - The following
u128
are constructed for every header key-value pair using the following format:- 2 bytes of length of "key:value" string as bytes
- "key:value" string as bytes
- Padding to 16
Number of u128
: variable, at least 1, check AttestationResponse.oracleData.encodedPositions.requestHeaders
.
10. Encode optional properties#
Fields that are optional in the Attestation Request are encoded all together, even when empty.
The first u128
is a header - the first little endian byte is a bitmask, which encodes existence of HTML result type (1st bit),
request content type (2nd bit), request body (3rd bit). The last 8 little-endian bytes are a little-endian byte representation of
the number of u128
s following the header, that contain all the optional parameters. There will always be at least 3 u128
s after the header - zero-byte u128
s encoding the lengths of the (non-existent) components.
The header is followed by the following content:
-
1
u128
encoding HTML result type. The first little endian byte encodes the value -1
forelement
,2
forvalue
. If there's no HTML result type, then the wholeu128
is 0. -
At least 1
u128
encoding the Attestation Request's content type. The first 8 little endian bytes encode the number of the followingu128
s encoding the actual content type as character codes. If there is no content type, there is 1u128
of 0, followed by 0u128
s of content. -
At least 1
u128
encoding the Attestation Request's body. The first 8 little endian bytes encode the number of the followingu128
s encoding the actual request body as character codes. If there is no request body, there's 1u128
of 0, followed by 0u128
s of content.
Number of u128
: variable, at least 4, check AttestationResponse.oracleData.encodedPositions.optionalFields
.